通过Wireguard分配公网IPv6给其他主机

todo

June 21, 2025

Prometheus + Node Exporter + Grafana 部署

前言 什么是 Prometheus、Node Exporter 和 Grafana?它们是用于监控和可视化系统性能的工具。 Prometheus 是一个开源的监控系统和时间序列数据库 Node Exporter 是 Prometheus 的一个组件,用于收集 Linux 系统的硬件和操作系统指标 Grafana 是一个开源的数据可视化平台,可以与 Prometheus 集成来展示数据 关于数据流动,Prometheus 通过 HTTP 拉取 Node Exporter 的指标数据,然后将这些数据存储在时间序列数据库中。Grafana 则通过查询 Prometheus 的 API 来获取这些数据,并以可视化的方式展示出来。 所以 Prometheus 需要能访问 Node Exporter 的 HTTP 接口,而 Grafana 则需要能访问 Prometheus 的 HTTP 接口。 在实践中,我们将把 Prometheus 和 Grafana 部署在同一台服务器上。Node Exporter 将安装在所需要监控的服务器上。 为什么不用 docker ?个人觉得为了 docker 那点便利性不值得,并且 docker 至今还不原生支持 nftables,直接在宿主机上部署更少问题。 Native support for nftables 架构示意图 环境 Debian 12 安装 Prometheus 使用我的脚本 如果你不想手动安装,可以使用我写的脚本来自动化安装 Prometheus。 ...

June 18, 2025

Debian 编译安装 unbound

unbound 简介 Unbound是一款验证型、递归式、带缓存的DNS解析器,旨在实现快速与轻量化,并融合了基于开放标准的现代特性。 为增强在线隐私保护,Unbound支持DNS-over-TLS和DNS-over-HTTPS,使客户端能够加密通信。此外,它还支持多种现代标准,这些标准不仅减少了与权威服务器交换的数据量,提升了隐私性,还增强了DNS的健壮性。其中最为关键的技术包括查询名称最小化、积极利用DNSSEC验证缓存,以及对权威区域的支持,后者可用于加载根区域副本。 Unbound兼容所有Linux和BSD发行版,以及macOS,大多数平台均有现成安装包。它已被纳入所有主要BSD操作系统的基础系统,以及大多数Linux发行版的标准软件库中,安装与配置简便易行,仅需几行配置即可为单机或网络设置解析器。 作为遵循BSD许可证的自由开源软件,Unbound的产品开发路线图首要关注用户的安全与隐私。同时,所有功能均需依托成熟的开放标准。我们持续为所有用户优化Unbound的功能,这意味着我们不会为付费客户定制构建或提供专属功能。我们的优先级由用户反馈,特别是拥有支持合同的用户,以及更广泛的互联网社区所引导。在可能的情况下,赞助功能将获得更高优先级,并会逐案评估。 Source 安装必要的依赖 sudo apt update sudo apt install -y build-essential libssl-dev bison flex libhiredis-dev libevent-dev libsystemd-dev pkg-config make dns-root-data 下载并编译安装 unbound git clone https://github.com/NLnetLabs/unbound cd unbound ./configure --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --runstatedir=/run \ --with-username=unbound \ --with-ssl \ --with-libevent \ --enable-systemd \ --enable-subnet \ --enable-tfo-client \ --enable-tfo-server \ --enable-cachedb \ --with-libhiredis \ --disable-rpath \ --with-pidfile=/run/unbound/unbound.pid \ --with-rootkey-file=/var/lib/unbound/root.key \ --with-libnghttp2 \ --with-libsodium \ --with-pthreads \ --with-chroot-dir= make && make install 说明 `configure' 配置 unbound 1.23.1 以适应多种类型的系统。 用法: ./configure [选项]... [变量=值]... 要分配环境变量 (例如 CC, CFLAGS...), 请将它们指定为 变量=值。有关一些有用变量的描述,请参见下文。 选项的默认值在中括号内指定。 配置: -h, --help 显示此帮助信息并退出 --help=short 显示此软件包特有的选项 --help=recursive 显示所有包含的软件包的简短帮助信息 -V, --version 显示版本信息并退出 -q, --quiet, --silent 不打印 `checking ...' 消息 --cache-file=FILE 将测试结果缓存在 FILE 中 [禁用] -C, --config-cache `--cache-file=config.cache' 的别名 -n, --no-create 不创建输出文件 --srcdir=DIR 在 DIR 中查找源代码 [配置目录或 `..'] 安装目录: --prefix=PREFIX 将与体系结构无关的文件安装在 PREFIX 中 [/usr/local] --exec-prefix=EPREFIX 将与体系结构相关的文件安装在 EPREFIX 中 [PREFIX] 默认情况下, `make install' 会将所有文件安装在 `/usr/local/bin', `/usr/local/lib' 等目录中。您可以使用 `--prefix` 指定一个不同于 `/usr/local' 的安装前缀, 例如 `--prefix=$HOME'。 为了更好地控制,请使用以下选项。 微调安装目录: --bindir=DIR 用户可执行文件 [EPREFIX/bin] --sbindir=DIR 系统管理员可执行文件 [EPREFIX/sbin] --libexecdir=DIR 程序可执行文件 [EPREFIX/libexec] --sysconfdir=DIR 只读的单机数据 [PREFIX/etc] --sharedstatedir=DIR 可修改的与体系结构无关的数据 [PREFIX/com] --localstatedir=DIR 可修改的单机数据 [PREFIX/var] --runstatedir=DIR 可修改的每进程数据 [LOCALSTATEDIR/run] --libdir=DIR 目标代码库 [EPREFIX/lib] --includedir=DIR C 头文件 [PREFIX/include] --oldincludedir=DIR 非 gcc 的 C 头文件 [/usr/include] --datarootdir=DIR 只读的与体系结构无关的数据根目录 [PREFIX/share] --datadir=DIR 只读的与体系结构无关的数据 [DATAROOTDIR] --infodir=DIR info 文档 [DATAROOTDIR/info] --localedir=DIR 区域设置相关的数据 [DATAROOTDIR/locale] --mandir=DIR man 文档 [DATAROOTDIR/man] --docdir=DIR 文档根目录 [DATAROOTDIR/doc/unbound] --htmldir=DIR html 文档 [DOCDIR] --dvidir=DIR dvi 文档 [DOCDIR] --pdfdir=DIR pdf 文档 [DOCDIR] --psdir=DIR ps 文档 [DOCDIR] 系统类型: --build=BUILD 为在 BUILD 上构建进行配置 [猜测值] --host=HOST 交叉编译以构建在 HOST 上运行的程序 [BUILD] 可选特性: --disable-option-checking 忽略无法识别的 --enable/--with 选项 --disable-FEATURE 不包含 FEATURE (等同于 --enable-FEATURE=no) --enable-FEATURE[=ARG] 包含 FEATURE [ARG=yes] --enable-checking 启用警告、断言、makefile 依赖关系 --enable-debug 等同于 enable-checking --disable-flto 禁用链接时优化 (gcc 特定选项) --enable-pie 启用位置无关可执行文件 (例如,为了充分 利用 ASLR,会有少量性能损失) --enable-relro-now 在加载时启用完全重定位绑定 (RELRO NOW, 以保护 GOT 和 .dtor 区域) --enable-shared[=PKGS] 构建共享库 [默认=yes] --enable-static[=PKGS] 构建静态库 [默认=yes] --enable-fast-install[=PKGS] 为快速安装进行优化 [默认=yes] --disable-libtool-lock 避免锁定 (可能会破坏并行构建) --disable-rpath 禁用硬编码的 rpath (默认=启用) --disable-largefile 忽略对大文件的支持 --enable-systemd 编译时支持 systemd (需要 libsystemd, pkg-config) --enable-alloc-checks 启用内存分配统计信息,用于调试 --enable-alloc-lite 启用轻量级分配断言,用于调试 --enable-alloc-nonregional 启用非区域分配,速度较慢但会将区域分配暴露给其他内存净化器,用于调试 --disable-swig-version-check 禁用 swig 版本检查,以使用较旧的 swig 构建 python 模块即使这样做不可靠 --disable-sha1 禁用 SHA1 RRSIG 支持,不会禁用 nsec3 支持 --disable-sha2 禁用 SHA256 和 SHA512 RRSIG 支持 --enable-subnet 启用客户端子网 --disable-gost 禁用 GOST 支持 --disable-ecdsa 禁用 ECDSA 支持 --disable-dsa 禁用 DSA 支持 --disable-ed25519 禁用 ED25519 支持 --disable-ed448 禁用 ED448 支持 --enable-event-api 启用 (实验性的) 可插拔事件基础 libunbound API,安装到 unbound-event.h --enable-tfo-client 为客户端模式启用 TCP Fast Open --enable-tfo-server 为服务器模式启用 TCP Fast Open --enable-static-exe 启用以针对未安装的 (事件) 库静态编译 可执行文件,用于调试 --enable-fully-static 启用以完全静态编译 --enable-lock-checks 启用以检查锁定和解锁调用,用于调试 --enable-allsymbols 从 libunbound 导出所有符号并将二进制文件链接到它,安装尺寸更小但 libunbound 导出表会被内部符号污染 --enable-dnstap 启用 dnstap 支持 (需要 protobuf-c) --enable-dnscrypt 启用 dnscrypt 支持 (需要 libsodium) --enable-cachedb 启用 cachedb 模块,可以使用外部缓存存储 --enable-ipsecmod 启用 ipsecmod 模块,以促进机会性 IPsec --enable-ipset 启用 ipset 模块 --disable-explicit-port-randomisation 禁用显式源端口随机化,并依赖 内核提供随机源端口 --enable-linux-ip-local-port-range 定义此项以启用 /proc/sys/net/ipv4/ip_local_port_range 作为默认传出端口范围。这仅适用于 Linux 上的 libunbound 并且不影响 unbound 解析守护进程本身。这可能会严重限制可用的传出端口数量,从而降低随机性。仅当目标系统限制 (例如某些启用 SELinux 的发行版) 使用非临时端口时才定义此项。 可选软件包: --with-PACKAGE[=ARG] 使用 PACKAGE [ARG=yes] --without-PACKAGE 不使用 PACKAGE (等同于 --with-PACKAGE=no) --with-conf-file=path Unbound 配置文件的路径名 --with-run-dir=path 设置 chdir 到的默认目录 (默认为 cfg 文件所在的目录) --with-chroot-dir=path 设置 chroot 到的默认目录 (默认为与 run-dir 相同) --with-share-dir=path 设置共享数据的默认目录 (默认为 share/unbound) --with-pidfile=filename 设置 unbound pid 文件的默认路径名 (默认 run-dir/unbound.pid) --with-rootkey-file=filename 设置根密钥文件的默认路径名 (默认 run-dir/root.key)。此文件会被读取和写入。 --with-rootcert-file=filename 设置根更新证书文件的默认路径名(默认 run-dir/icannbundle.pem)。如果您对内置证书满意,则此文件不必存在。 --with-username=user 设置 unbound 更改到的默认用户 (默认用户是 unbound) --with-pic[=PKGS] 尝试仅使用 PIC/非 PIC 对象 [默认=两者都使用] --with-aix-soname=aix|svr4|both 在 AIX 上提供的共享库版本控制(又名 "SONAME")变体, [默认=aix]。 --with-gnu-ld 假设 C 编译器使用 GNU ld [默认=no] --with-sysroot[=DIR] 在 DIR 中搜索依赖库 (如果未指定,则为编译器的 sysroot)。 --with-pthreads 使用 pthreads 库,或使用 --without-pthreads禁用线程支持。 --with-solaris-threads 使用 solaris 原生线程库。 --with-syslog-facility=LOCAL0 - LOCAL7 设置 SYSLOG_FACILITY, 默认 DAEMON --with-dynlibmodule 构建动态库模块,或使用 --without-dynlibmodule 禁用它。(默认=no) --with-pyunbound 构建 PyUnbound,或使用 --without-pyunbound 跳过它。 (默认=no) --with-pythonmodule 构建 Python 模块,或使用 --without-pythonmodule 禁用脚本引擎。(默认=no) --with-nss=path 使用 libnss 代替 openssl,安装在 path。 --with-nettle=path 使用 libnettle 作为加密库,安装在 path。 --with-ssl=pathname 启用 SSL (将检查 /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr 或指定类似 /usr/include/openssl11) --with-libbsd 使用可移植的 libbsd 函数 --with-deprecate-rsa-1024 弃用 RSA 1024 位长度,使其成为不受支持的密钥,用于 OpenSSL FIPS 拒绝 1024 位验证的情况 --with-libevent=pathname 使用 libevent (将检查 /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr 或您可以指定一个显式路径)。速度较慢,但允许使用大的传出端口范围。 --with-libexpat=path 为 libexpat 指定显式路径。 --with-libhiredis=path 为 libhiredis 指定显式路径。 --with-libnghttp2=path 为 libnghttp2 指定显式路径。 --with-libngtcp2=path 为 libngtcp2 指定显式路径,用于 QUIC。 --with-dnstap-socket-path=pathname 设置默认 dnstap 套接字路径 --with-protobuf-c=path protobuf-c 的安装路径,用于 dnstap --with-libsodium=path libsodium 的安装路径,用于 dnscrypt --with-libmnl=path 为 libmnl 指定显式路径。 --with-libunbound-only 不构建守护进程和工具程序 一些有影响的环境变量: CC C 编译器命令 CFLAGS C 编译器标志 LDFLAGS 链接器标志, 例如 -L<lib dir> 如果您的库在非标准目录 <lib dir> 中 LIBS 传递给链接器的库, 例如 -l<library> CPPFLAGS (Objective) C/C++ 预处理器标志, 例如 -I<include dir> 如果您的头文件在非标准目录 <include dir> 中 YACC 要使用的 `Yet Another Compiler Compiler' 实现。默认为找到的第一个程序: `bison -y', `byacc', `yacc'。 YFLAGS 默认传递给 $YACC 的参数列表。此脚本将 YFLAGS 默认为空字符串,以避免某些 make 应用程序给出的默认值 `-d'。 LT_SYS_LIBRARY_PATH 用户定义的运行时库搜索路径。 PKG_CONFIG pkg-config 工具的路径 PKG_CONFIG_PATH 添加到 pkg-config 搜索路径的目录 PKG_CONFIG_LIBDIR 覆盖 pkg-config 内置搜索路径的路径 CPP C 预处理器 SYSTEMD_CFLAGS SYSTEMD 的 C 编译器标志, 覆盖 pkg-config SYSTEMD_LIBS SYSTEMD 的链接器标志, 覆盖 pkg-config SYSTEMD_DAEMON_CFLAGS SYSTEMD_DAEMON 的 C 编译器标志, 覆盖 pkg-config SYSTEMD_DAEMON_LIBS SYSTEMD_DAEMON 的链接器标志, 覆盖 pkg-config PYTHON_VERSION 要使用的已安装 Python 版本,例如 '2.3'。此字符串将附加到 Python 解释器的规范名称。 SOURCE_DATE_EPOCH 如果设置了此变量,则使用该变量的值而不是当前时间作为构建时间戳。格式为 unix时间戳。这可以实现可重现的构建输出。 PROTOBUFC_CFLAGS PROTOBUFC 的 C 编译器标志, 覆盖 pkg-config PROTOBUFC_LIBS PROTOBUFC 的链接器标志, 覆盖 pkg-config 使用这些变量来覆盖 `configure' 所做的选择,或帮助 它找到具有非标准名称/位置的库和程序。 将错误报告给 <unbound-bugs@nlnetlabs.nl 或 https://github.com/NLnetLabs/unbound/issues>。 创建 unbound 用户和组并配置 groupadd --system unbound useradd --no-create-home --system --shell /usr/sbin/nologin unbound mkdir -p /var/lib/unbound cp /usr/share/dns/root.key /var/lib/unbound/root.key chown -R unbound:unbound /var/lib/unbound 创建 unbound 的 systemd 服务文件 cat <<EOF > /etc/systemd/system/unbound.service [Unit] Description=Unbound DNS Resolver (Experimental Build) Documentation=man:unbound(8) man:unbound.conf(5) https://www.nlnetlabs.nl/projects/unbound/documentation.html Wants=network-online.target After=network-online.target # 如果您的 auto-trust-anchor-file 或 cachedb 路径位于 /var/lib/unbound, # 确保 /var 在此服务启动前已挂载。 RequiresMountsFor=/var/lib/unbound /run [Service] # === 基本配置 === Type=notify # Unbound 在 '--enable-systemd' 编译时支持 notify 类型,它会在服务完全准备好后通知 systemd。 # 指定运行 Unbound 的用户和组。 # 您在 ./configure 时使用了 --with-username=unbound。 # 您需要确保 'unbound' 用户和组在系统上存在。 # 例如: # sudo groupadd --system unbound # sudo useradd --system -g unbound -d /var/lib/unbound -s /bin/false -c "Unbound DNS Resolver" unbound User=unbound Group=unbound # 预启动检查配置文件 ExecStartPre=/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf # 启动命令 # -d: 不进行后台守护进程化 (systemd 处理) # -p: 创建 PID 文件 (与 --with-pidfile 编译选项匹配) # -c: 指定配置文件路径 ExecStart=/usr/sbin/unbound -d -p -c /etc/unbound/unbound.conf # 重载配置 (需要 unbound.conf 中启用 remote-control) ExecReload=/usr/sbin/unbound-control reload # 重启策略 Restart=on-failure RestartSec=5s # PID 文件路径 (与 --with-pidfile 编译选项匹配) # RuntimeDirectory 会自动创建 /run/unbound 并设置权限给指定用户 PIDFile=/run/unbound/unbound.pid # === 资源和权限管理 === # 运行时目录,systemd 会创建 /run/unbound 并设置所有权为 User 和 Group 指定的用户/组 RuntimeDirectory=unbound RuntimeDirectoryMode=0750 # 能力绑定 # CAP_NET_BIND_SERVICE 允许 'unbound' 用户绑定到特权端口 (如53) AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID # 如果在 unbound.conf 中启用了 chroot,并且 Unbound 在降权为 'unbound' 用户后才执行 chroot, # 则可能还需要 CAP_SYS_CHROOT。但通常 chroot 在降权前由root完成,或者Unbound启动时即为'unbound'用户,则无法chroot到任意目录。 # 您的 --with-username=unbound 意味着Unbound会自行处理权限。 # --- 安全强化选项 --- #NoNewPrivileges=yes #ProtectSystem=no # 如果 ProtectSystem=strict 导致 Unbound 无法写入其管理的 root.key 或 cachedb (通常在 /var/lib/unbound/): # 您需要添加 ReadWritePaths 指令。例如: # ReadWritePaths=/var/lib/unbound # 如果您在 unbound.conf 中使用了 chroot: "/etc/unbound" 并且需要在其中写入 (如 root.key): # ReadWritePaths=/etc/unbound #ProtectHome=no #PrivateTmp=no #PrivateDevices=yes # MemoryDenyWriteExecute=yes # 如果系统和Unbound版本支持,可增强安全性 [Install] WantedBy=multi-user.target EOF 创建 unbound 的配置文件 cat <<EOF > /etc/unbound/unbound.conf # Unbound configuration file # # See unbound.conf(5) man page for more information. # # 注意: 路径 (例如 logfile, root-hints, auto-trust-anchor-file) # 可能需要根据您的操作系统和Unbound安装方式进行调整。 # 确保Unbound进程对指定的日志文件和自动信任锚点文件具有写入权限(或对其目录)。 server: # --- 基本服务器设置 --- verbosity: 0 # 日志详细级别 (0=仅错误, 1=操作信息, 2=详细操作, ... 5=非常详细) #logfile: "/var/log/unbound/unbound.log" # 日志文件路径。如果注释掉或为空,则可能记录到syslog。 # 例如: FreeBSD: /var/unbound/unbound.log, OpenBSD: Unbound chroots and logs via syslog # Linux (from package): often /var/log/unbound.log or uses systemd journal use-syslog: no # 如果指定了 logfile,设为 no 则仅记录到文件。设为 yes 则也发送到 syslog。 module-config: "validator cachedb iterator" interface: 0.0.0.0 # 监听所有 IPv4 地址 interface: ::0 # 监听所有 IPv6 地址 (如果您的系统支持IPv6) port: 54 # 监听的端口 (DNS标准端口) do-ip4: yes # 允许 IPv4 do-ip6: yes # 允许 IPv6 (如果网络支持) do-udp: yes # 允许 UDP do-tcp: yes # 允许 TCP # --- 访问控制 --- # 定义哪些客户端IP地址或子网可以查询此服务器。 # 强烈建议配置此项以防止滥用。 access-control: 127.0.0.0/8 allow # 允许本地回环地址 (IPv4) access-control: ::1/128 allow # 允许本地回环地址 (IPv6) # 示例:允许常见的私有网络范围。根据您的网络调整或添加。 access-control: 192.168.0.0/16 allow access-control: 10.0.0.0/8 allow access-control: 172.16.0.0/12 allow # access-control: ::ffff:127.0.0.1/128 allow # IPv4-mapped IPv6 localhost # --- 性能和缓存设置 --- msg-cache-size: 10m # DNS消息缓存大小 (查询和应答) rrset-cache-size: 20m # RRset缓存大小 (DNS资源记录) # 缓存相关的 slab 数量,通常可以设为接近 num-threads 的值或者2的幂次方。 msg-cache-slabs: 4 rrset-cache-slabs: 4 num-threads: 2 # 创建的线程数。理想情况下,设置为CPU核心数。 # 对于较小的部署,1或2通常足够。 # 增加传出查询可用的端口范围,有助于防止某些类型的攻击。 outgoing-range: 1024 # 每个线程可以并发处理的查询数上限。 num-queries-per-thread: 2048 # --- 过期缓存与预取功能 (Requested "过期缓存功能") --- prefetch: yes # 在缓存条目过期前主动获取更新,保持常用条目新鲜。 prefetch-key: yes # 在验证DS记录时,提前获取DNSKEY记录,加速后续DNSSEC验证。 serve-expired: yes # 在尝试获取新记录的同时,从缓存中提供已过期的记录。 # 这可以提高当上游权威服务器缓慢或无响应时的可用性。 serve-expired-ttl: 3600 # (1小时) 提供已过期记录时,该记录的TTL值。 serve-expired-reply-ttl: 30 # (30秒) 当提供过期数据时,客户端应该缓存这条过期数据的TTL。 serve-expired-client-timeout: 1000 # (1秒) 在提供过期数据之前,等待新答案的最长时间(毫秒)。 # --- 安全设置 --- harden-glue: yes # 强化对胶水记录的验证。 harden-dnssec-stripped: yes # 防止DNSSEC剥离攻击。 harden-algo-downgrade: yes # 防止算法降级攻击。 use-caps-for-id: yes # 在查询ID中使用随机大小写混合(0x20技巧)来增加欺骗难度。 edns-buffer-size: 1232 # EDNS0 UDP包的建议大小,以减少IP分片。 hide-identity: yes # 拒绝回应 id.server 和 hostname.bind 的查询。 hide-version: yes # 拒绝回应 version.server 和 version.bind 的查询。 # 定义私有地址范围,Unbound会从DNS响应中剥离这些地址,以防止DNS重绑定攻击。 private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10 # private-domain: "example.com" # 如果您有不想被外部解析的内部域名,可以在这里声明。 # 不查询回环地址上的公共域名,防止潜在的循环或安全问题。 do-not-query-localhost: yes # --- DNSSEC 验证 --- # 自动管理和更新根信任锚点。Unbound需要对该文件的目录有写权限,或者您可以手动管理此文件。 # 路径可能为: /var/lib/unbound/root.key (Debian/Ubuntu), /usr/local/etc/unbound/root.key (FreeBSD ports), # /etc/unbound/root.key (generic from source), /opt/homebrew/etc/unbound/root.key (macOS Homebrew) auto-trust-anchor-file: "/var/lib/unbound/root.key" val-log-level: 1 # DNSSEC验证失败时的日志级别 (1=基本信息, 2=详细信息)。 # --- 根提示文件 (Root Hints) --- # 如果Unbound作为递归解析器直接从根服务器开始解析 (而不是转发模式),则需要此文件。 # 确保此文件存在并且保持最新。 # 路径可能为: /usr/share/dns/root.hints (common on Linux), /etc/unbound/root.hints, # /usr/local/etc/unbound/root.hints root-hints: "/usr/share/dns/root.hints" # --- 转发模式 (可选) --- # 如果您希望Unbound将所有查询转发到其他上游DNS服务器,而不是自己从根进行递归解析, # 请取消注释并配置以下部分。如果启用了转发,则上面的 root-hints 通常不再需要。 # forward-zone: # name: "." # 转发所有查询 # # 常用的公共DNS服务器示例: # forward-addr: 8.8.8.8@53 # Google # forward-addr: 8.8.4.4@53 # Google # forward-addr: 1.1.1.1@53 # Cloudflare # forward-addr: 1.0.0.1@53 # Cloudflare # # 如果您的上游服务器支持DNS-over-TLS (DoT): # # forward-tls-upstream: yes # # forward-addr: 1.1.1.1@853#cloudflare-dns.com # DoT示例,主机名用于证书验证 # --- 远程控制 (可选) --- # 允许使用 unbound-control 工具管理Unbound服务。 # 如果启用,请确保使用 unbound-control-setup 生成密钥和证书文件。 # remote-control: # control-enable: yes # control-interface: 127.0.0.1 # 监听远程控制连接的IP地址 # control-port: 8953 # 监听远程控制连接的端口 # # 以下文件路径也需要根据您的安装进行调整 # server-key-file: "/etc/unbound/unbound_server.key" # server-cert-file: "/etc/unbound/unbound_server.pem" # control-key-file: "/etc/unbound/unbound_control.key" # control-cert-file: "/etc/unbound/unbound_control.pem" # cachedb: # backend: "redis" # 指定后端为 redis (这通常也适用于Valkey) # --- Redis/Valkey 服务器连接参数 --- # redis-server-host: 192.168.2.11 # redis-server-port: 6379 #redis-server-path: "/run/valkey/valkey-server.sock" # redis-server-password: "your_valkey_password" # 如果Valkey设置了密码 # redis-database: 0 # 可选,Valkey/Redis数据库编号 (默认为0) # --- 可选的 Redis/Valkey 相关超时设置 (如果后端驱动支持) --- # redis-timeout: 100 # 连接和操作超时 (毫秒) # --- 缓存数据密钥前缀 (可选) --- # redis-key-prefix: "unbound_cache:" # 避免与其他应用在同一Valkey实例中的键冲突 # --- 其他 cachedb 通用设置 (可能适用) --- # cachedb-no-store: no # 是否存储否定缓存条目 (默认为no,即存储) EOF 启动 unbound 服务 sudo systemctl daemon-reload sudo systemctl enable unbound sudo systemctl start unbound 检查 unbound 服务状态 sudo systemctl status unbound

May 20, 2025

ffmpeg 将视频转码至 h265 编码

ffmpeg 简介 FFmpeg是一个开源的音视频处理工具,支持录制、转换数字音频、视频,并能将其转化为流。它包含了一个完整的解决方案,能够处理几乎所有的音视频格式。 FFmpeg的核心是libavcodec库,它提供了多种音视频编解码器,支持从简单的音频转码到复杂的视频处理任务。FFmpeg还提供了丰富的命令行工具,用户可以通过命令行轻松实现音视频的转换、剪辑、合并等操作。 FFmpeg的跨平台特性使其能够在Linux、Windows和macOS等多种操作系统上运行。它的强大功能和灵活性使其成为音视频处理领域的事实标准。 Source 必要条件 安装FFmpeg:确保你的系统上已经安装了FFmpeg。 转码命令 # Intel QuickSync (hevc_qsv) # 参数: # -global_quality: 1–51(类似 CRF,数值越大质量越低,文件越小,默认23) # -preset: ultrafast | fast | medium | slow | slower | veryslow(速度↑/压缩率↓,默认medium) ffmpeg -y -i input.mp4 \ -c:v hevc_qsv -global_quality 23 -preset medium \ -c:a copy -c:s copy \ output_h265_intel.mp4 # AMD AMF (hevc_amf) # 参数: # -qp: 0–51(质量参数,数值越大压缩越强,默认23) # -quality: speed | balanced | quality(speed=最快最低质;balanced=中;quality=最高质,默认balanced) ffmpeg -y -i input.mp4 \ -c:v hevc_amf -rc cqp -qp 23 -quality balanced \ -c:a copy -c:s copy \ output_h265_amd.mp4 # NVIDIA NVENC (hevc_nvenc) # 参数: # -cq: 0–51(质量参数,数值越大质量越低,文件越小,默认23) # -preset: ultrafast | fast | medium | slow | slower | veryslow(同x265预设,默认medium) ffmpeg -y -i input.mp4 \ -c:v hevc_nvenc -cq 23 -preset medium \ -c:a copy -c:s copy \ output_h265_nvidia.mp4 # 软件 x265 (libx265) # 参数: # -crf: 0–51(数值越大压缩越强,默认23) # -preset: ultrafast | fast | medium | slow | slower | veryslow(速度↑/压缩率↓,默认medium) ffmpeg -y -i input.mp4 \ -c:v libx265 -crf 23 -preset medium \ -c:a copy -c:s copy \ output_h265_x265.mp4 Python 脚本 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 将视频文件转码为H.265编码。 用法: python convert_to_h265.py <视频文件路径> [--intel] [--amd] [--nvidia] 使用 --intel 参数启用 Intel QuickSync 硬件加速 使用 --amd 参数启用 AMD AMF 硬件加速 使用 --nvidia 参数启用 NVIDIA NVENC 硬件加速 """ import argparse import os import subprocess import sys def convert_to_h265( input_file, use_intel=False, use_amd=False, use_nvidia=False, crf=23, preset="medium", bitrate=None, ): """ 使用ffmpeg将视频转码为H.265格式 参数: input_file: 输入视频文件路径 use_intel: 是否使用Intel QuickSync硬件加速 use_amd: 是否使用AMD AMF硬件加速 use_nvidia: 是否使用NVIDIA NVENC硬件加速 """ # 检查文件是否存在 if not os.path.isfile(input_file): print(f"错误: 文件不存在 - {input_file}") return False # 构建输出文件路径 file_dir = os.path.dirname(input_file) file_name, file_ext = os.path.splitext(os.path.basename(input_file)) output_file = os.path.join(file_dir, f"{file_name}_h265{file_ext}") # 将 Windows 路径反斜杠改为正斜杠,避免 \0 被误识别 input_file = input_file.replace("\\", "/") output_file = output_file.replace("\\", "/") # 构建 ffmpeg 命令 ffmpeg_cmd = [ "ffmpeg", "-y", # 如果目标已存在则强制覆盖 "-i", input_file, ] # 硬件/软件编码选择 if use_intel: ffmpeg_cmd.extend( [ "-c:v", "hevc_qsv", # Intel QuickSync HEVC/H.265编码器 "-global_quality", str(crf), # QSV 对应的质量参数 "-preset", preset, ] ) elif use_amd: # 将 --preset 映射到 AMF 的 quality 参数 amf_quality = { "ultrafast": "speed", "fast": "speed", "medium": "balanced", "slow": "quality", "slower": "quality", "veryslow": "quality", }.get(preset, "balanced") ffmpeg_cmd.extend( [ "-c:v", "hevc_amf", # AMD HEVC/H.265编码器 "-rc", "cqp", # AMF 使用 CQP 模式 "-qp", str(crf), # AMF 的质量参数 "-quality", amf_quality, # AMF 支持的 quality 选项 ] ) elif use_nvidia: ffmpeg_cmd.extend( [ "-c:v", "hevc_nvenc", # NVIDIA NVENC H.265编码器 "-cq", str(crf), # NVENC 的质量参数 "-preset", preset, ] ) else: # 软件 x265 编码 ffmpeg_cmd.extend( [ "-c:v", "libx265", # 软件x265编码器 "-crf", str(crf), "-preset", preset, ] ) # 如果指定了固定码率,则覆盖质量参数 if bitrate: ffmpeg_cmd.extend(["-b:v", bitrate]) # 添加通用的编码参数 ffmpeg_cmd.extend( [ "-c:a", "copy", # 复制音频流 "-c:s", "copy", # 复制字幕流 (如果有) output_file, ] ) print(f"正在转码: {input_file}") print(f"输出文件: {output_file}") print("转码中,请稍候...") try: # 执行ffmpeg命令 process = subprocess.Popen( ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ) # 安全地处理并显示进度信息 if process.stdout: # 确保stdout不是None for line in process.stdout: # 仅显示包含关键字的行以减少输出量 if "frame=" in line or "speed=" in line or "error" in line.lower(): print(f"\r{line.strip()}", end="") else: # 如果无法获取输出流,提供一个替代方案 print("正在处理中,请等待...") # 等待进程完成 return_code = process.wait() if return_code == 0: print(f"\n\n转码完成!输出文件: {output_file}") print(f"原始文件大小: {os.path.getsize(input_file) / (1024*1024):.2f} MB") print( f"转码后文件大小: {os.path.getsize(output_file) / (1024*1024):.2f} MB" ) return True else: print(f"\n转码失败,ffmpeg返回错误代码: {return_code}") return False except FileNotFoundError: print("错误: 找不到ffmpeg。请确保ffmpeg已安装并添加到系统PATH中。") return False except Exception as e: print(f"发生错误: {str(e)}") return False if __name__ == "__main__": parser = argparse.ArgumentParser(description="将视频转码为H.265格式") parser.add_argument("input_file", help="输入视频文件路径") parser.add_argument( "--intel", action="store_true", help="使用 Intel QuickSync硬件加速", ) parser.add_argument( "--amd", action="store_true", help="使用 AMD GPU 硬件加速", ) parser.add_argument( "--nvidia", action="store_true", help="使用 NVIDIA NVENC 硬件加速", ) # 新增质量/码率可调参数 parser.add_argument( "--crf", type=int, default=23, help="质量参数(CRF或等效值,数值越大文件越小)", ) parser.add_argument( "--preset", default="medium", choices=[ "ultrafast", "fast", "medium", "slow", "slower", "veryslow", ], help="编码preset", ) parser.add_argument( "--bitrate", help="目标码率,如2000k,优先于CRF/质量参数", ) args = parser.parse_args() if sum(bool(x) for x in (args.intel, args.amd, args.nvidia)) > 1: print("错误: 只能指定一个硬件加速选项") sys.exit(1) convert_to_h265( args.input_file, use_intel=args.intel, use_amd=args.amd, use_nvidia=args.nvidia, crf=args.crf, preset=args.preset, bitrate=args.bitrate, )

May 20, 2025