通过Wireguard分配公网IPv6给其他主机
todo
todo
前言 什么是 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。 ...
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
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, )