最近在把一批老服务器迁到 KeyarchOS 上的时候遇到一个挺实际的需求机房出口已经全面跑 IPv6可内部还有不少只有 IPv4 地址的旧系统甚至一些外部依赖服务也只公布 IPv4 访问地址。总不能为了几个老接口再把整套双栈网络翻出来更不可能直接忽略 IPv6 只留 IPv4。我的选择是在 KeyarchOS 上装一个 tayga让它承担 NAT64 翻译工作把 IPv6 流量转换成 IPv4 流量送出去。tayga 是一个用户态的 NAT64 实现版本 0.9.2 在 Linux 生态里非常成熟安装方式和配置思路都比较固定。这篇文章就把我在 KeyarchOS 上从零安装、配置、调通 tayga-0.9.2-3 的完整过程记录下来包括为什么选 tayga、依赖怎么处理、tayga.conf 关键参数怎么定、路由和内核转发怎么配合以及后续 DNS64 怎么衔接和常见的坑。写这篇东西不为了炫技主要是想给同样在 KeyarchOS 这类 RPM 系 Linux 发行版上做 IPv6 过渡方案的运维同学一个能直接照着操作的参考。不管你是刚接触 NAT64还是已经被某些诡异的路由问题折磨了一下午下文的内容应该都能对上号。1. 为什么要在 KeyarchOS 上装 NAT64 / Tayga先说清楚 NAT64 到底解决什么问题。一套网络从 IPv4 迁移到 IPv6 是个漫长的过程迁移期间总会出现两种地址族并存的情况新搭建的纯 IPv6 网段没有 IPv4 地址但业务要访问的旧服务和第三方资源仍然是 IPv4-only。这个时候就需要一种“翻译”能力让 IPv6 主机发出去的 IPv6 报文到边界网关后被改写成 IPv4 报文再投递给 IPv4 目标服务器。返回路径则相反把 IPv4 报文再译成 IPv6 报文送回来。这就是 NAT64 的核心职责。实现 NAT64 有硬件方案也有软件方案硬件方案多见于运营商级设备。而在服务器层面尤其是一台 KeyarchOS 机器想临时客串边界翻译网关tayga 这类用户态守护进程就很合适。tayga 不需要特殊硬件依赖一个 TUN 虚拟接口配合系统路由进程就能工作。它把 IPv6 报文从 TUN 接口收进来在用户态完成报头转换、地址翻译再注入 IPv4 网络返回流量也是同样的逆向过程。因为是纯用户态实现出了问题可以加日志排查也可以随时改配置热重启对运维来讲可控性高很多。KeyarchOS 本身是一个基于 RPM 体系的 Linux 操作系统和 RHEL/CentOS 系列的包管理、服务管理习惯非常接近。所以 CentOS/RHEL 上能跑的工具移植过来通常也顺滑这次安装 tayga 正好验证了这一点。之前我在别的发行版上装过 tayga这次在 KeyarchOS 上重新走流程发现主要的工作量其实不在编译安装环节而在配置网络逻辑和路由规则上。顺带说一句部署 NAT64 网关有一个常见误区有人以为装了 tayga 以后所有 IPv6 流量就自动能访问 IPv4 地址了。实际上 tayga 只是个翻译引擎它只关心落到 TUN 接口上的、目标前缀匹配 NAT64 前缀的报文。至于哪些流量该进入这个前缀、DNS 查询结果要不要被改写成 AAAA 记录那是路由和 DNS64 需要解决的问题。所以我在方案设计时是按“tayga 翻译 路由引导 DNS64 合成 AAAA”三件套来规划缺一个都跑不通。明白了这一点后面的安装和配置就会有更清晰的逻辑不会在某个环节卡住时误以为是 tayga 本身出了问题。2. 安装方式的选择0.9.2-3 到底怎么搞tayga 的版本号写成 0.9.2-3一眼就能看出这是带打包发布号的版本对应上游源码版本 0.9.2-3 是打包方的第几次构建。在 KeyarchOS 默认软件源里通常找不到 tayga 这个包因为它的受众比较小未进入主流发行版的基础仓库。所以实际安装时有两条路径一是找到兼容的 RPM 包直接安装二是从官方源码编译安装。如果你能确认某个仓库提供 tayga-0.9.2-3 的 RPM而且它的依赖环境与 KeyarchOS 匹配直接rpm -ivh或dnf install是最省事的。但现实是镜像源里并不会有现成的 tayga RPM多数情况下还得自己从源码构建。源码构建其实也不复杂tayga 的依赖很轻核心依赖就是 gcc、make、Linux 内核头文件以及 libc 开发库。用 KeyarchOS 的 dnf 很容易装齐。我先说从源码构建的路径因为这条路径最可控也能确保你得到的就是 0.9.2 这个版本。大致步骤如下# 安装编译工具链 sudo dnf install -y gcc make tar wget # 获取 tayga 0.9.2 源码包 wget https://github.com/dertuxmalwieder/tayga/archive/refs/tags/0.9.2.tar.gz tar -xzf 0.9.2.tar.gz cd tayga-0.9.2 # 配置、编译、安装 ./configure make sudo make install编译过程中如果报错九成是缺了某个开发包。常见的有libc6-dev、linux-libc-dev在 KeyarchOS 里面对应的就是glibc-devel、kernel-devel。执行sudo dnf install -y glibc-devel kernel-devel基本能解决。编译完成后tayga 默认会安装到/usr/local/sbin/tayga配置文件示例放在/usr/local/etc/tayga.conf或源码目录的tayga.conf里。你可以在make install后先确认二进制是否成功生成tayga -h正常会打印用法说明包括--nodaemon、--debug、--conf等参数选项。看得到这些说明安装骨架就算完成了。如果你倾向于 RPM 方式也可以自己把源码打包成 RPM但这会引入 spec 文件编写、构建目录管理等额外工作对单纯想跑通服务的人来说性价比不高。我在生产环境里更推荐直接源码安装因为 tayga 这类小工具静态编译也不复杂后续维护无非是换配置文件和二进制。只要把版本信息和校验值记录到文档里升级路径也很清晰。还有一点要提醒源码包下载后尽量核对一下 SHA256 校验值确保从官方地址拿到的包没有被篡改。安全习惯这个东西在部署网络翻译网关上尤其重要因为你的网关一旦被植入后门影响的就不只是自己这台机器了。3. 配置 Tayga前缀、动态地址池与 TUN 接口安装好二进制之后真正决定能否跑通的是配置文件。tayga 的默认配置文件路径可能因编译方式不同而有差异源码方式一般是/usr/local/etc/tayga.conf。我配置时习惯直接建一个新的配置文件然后通过 systemd unit 里的--conf参数指定路径这样后续测试多套方案时切换比较方便。先看一份最基础但也足够跑通 NAT64 的配置tun-device nat64 ipv4-addr 192.0.2.1 ipv6-addr fd00:64:ff9b::1 prefix 64:ff9b::/96 dynamic-pool 192.0.2.10 192.0.2.254>sudo mkdir -p /var/lib/tayga sudo /usr/local/sbin/tayga --nodaemon --debug --conf /usr/local/etc/tayga.conf如果配置没问题你会看到日志里出现创建 TUN 接口、加载并校验配置的信息并且进程在后台日志输出。按CtrlC停掉说明配置语法和基本启动都通过了。4. 把流量送进门地址、路由和内核转发启动 tayga 只是第一步它创建了 TUN 接口但系统还不知道 IPv6 数据包该怎么走到那个接口上。所以还需要做三件事给 TUN 接口分配 IPv6 地址、添加 NAT64 前缀路由、开启内核 IP 转发。按照上面那份配置tayga 其实已经给 TUN 接口分配了 IPv4 和 IPv6 地址但你最好再确认一下接口状态。用ip addr show nat64查看能看到接口上有192.0.2.1和fd00:64:ff9b::1/64这样的地址。如果没有检查 tayga 是否真的启动成功是否因为配置里地址格式写错而被忽略。然后添加路由。你要让所有目标为64:ff9b::/96的 IPv6 报文进入 nat64 接口sudo ip -6 route add 64:ff9b::/96 dev nat64这条路由的作用是告诉内核凡是目标地址落在 NAT64 前缀范围内的 IPv6 包直接丢给 nat64 接口由 tayga 去处理。理解这一条就理解了 tayga 的工作边界它并不会“劫持”所有 IPv6 流量而是只处理匹配该前缀的那部分。接着开启转发。如果不开启 IP 转发经过系统协议栈的报文会被丢弃tayga 收到后也可能无法正常注入物理网卡。临时开启sudo sysctl -w net.ipv4.ip_forward1 sudo sysctl -w net.ipv6.conf.all.forwarding1如果要永久生效在/etc/sysctl.conf或/etc/sysctl.d/99-tayga.conf里写上同样的键值然后sysctl --system应用。这里要留意 IPv4 和 IPv6 的转发开关是独立的只开 IPv6 会导致 IPv4 方向的回报无法送出。做完这些可以试一下最直接的功能验证——从本机 ping 一个 IPv4 地址对应的 NAT64 地址。比如你的测试目标是192.0.2.8那么就用ping6 64:ff9b::c000:208如果网络路径顺畅tayga 会把 ICMPv6 报文翻译成 ICMPv4 的 echo request送往192.0.2.8并原路返回。ping6 能看到 reply就说明翻译链路已经通了。这里顺带说明一下 IPv4 地址到 NAT64 地址的换算方法把192.0.2.8的四个十进制数分别是 C0 00 02 08拼成十六进制再填入后 32 位得到64:ff9b::c000:0208。实际书写时前导 0 可以省略会得到64:ff9b::c000:208两者意义相同。有一个让不少人挠头的点ping6 通不代表所有 TCP/UDP 流量都通因为 ICMP 和 TCP 的报文路径可能受到不同的防火墙规则影响。生产环境里建议在 ping6 通过后再用 TCP 工具做一次真实业务验证这部分放到后面测试小节详细说。另外如果你有多个物理接口或多个子网记得在路由层面明确 NAT64 前缀该走哪个接口。不少人只配置了默认路由结果 NAT64 报文从别的接口出去了tayga 根本收不到。我在调试时也踩过一次这个坑排查了很久才发现是路由策略问题而不是 tayga 配置错误。5. DNS64 配合解决“纯 IPv6 拿不到 IPv4 目的地址”的问题光有 NAT64纯 IPv6 客户端还是很难直接使用它。因为正常情况下客户端解析一个域名时拿到的会是 IPv4 的 A 记录比如192.0.2.8。而纯 IPv6 主机没有 IPv4 协议栈收到 A 记录后根本无法发起连接自然也不会想起去用64:ff9b::c000:208这个地址。所以需要 DNS64 机制把 A 记录合成 AAAA 记录让客户端直接拿到一个目标前缀内的 IPv6 地址。DNS64 的常见实现有两种unbound 的 dns64 module 和 BIND 9 的 dns64 功能。如果网络里已经跑着 BIND直接在配置里加一段即可。我这次环境里用的是 unbound配置更简洁先讲 unbound 的方案。unbound 配置文件的server块里启用 dns64 模块server: module-config: dns64 iterator dns64-prefix: 64:ff9b::/96 access-control: 192.0.2.0/24 allow access-control: 2001:db8::/32 allow解释一下module-config必须把 dns64 放在 iterator 之前表示查询先从 DNS64 模块经过再做正常迭代。dns64-prefix要设置成和 tayga 的 NAT64 前缀一致这样合成出来的地址才能被 tayga 正确翻译。access-control用来限制哪些客户端可以使用该 DNS 服务避免这台 DNS64 被整个网段任意扫描利用。至于 BIND 9配置方式是在options里加一段dns64 64:ff9b::/96 { clients { any; }; mapping { exclude { 0.0.0.0/0; }; }; };这段是让 BIND 在解析到 IPv4 A 记录时返回对应 NAT64 IPv6 地址。exclude可以排除部分不需要合成 AAAA 的网段比如某些已经在 IPv6 协议栈里直连的内网服务。配置完成后把纯 IPv6 客户端的 DNS 指到这台 DNS64 服务器然后做一次解析验证。假设你要访问www.example.net其 IPv4 地址是192.0.2.8那么正常返回的 AAAA 记录应该是64:ff9b::c000:208的某种表示形式。用dig或nslookup看一眼就知道 DNS64 是否生效。这里有一个容易踩的坑有些 DNS64 实现默认不会对私有 IPv4 地址段做合成因为默认规则是只对全球单播地址应用。但 tayga 用于内网过渡时目标 IPv4 往往是私有地址比如10.x.x.x、192.168.x.x。如果不显式开启对私有地址的合成A 记录不会被改写成 AAAANAT64 也就形同虚设。unbound 如果要处理飞私有地址需要在 dns64-prefix 后增加无效的合成规则其实 unbound 比较直接它会默认合成所有 A 记录。BIND 9 则需要调整 exclude 规则。这点要结合自己内网地址规划格外小心DNS64 解析结果不对时优先检查是不是这里的问题。6. 实测 NAT64 转换从 ping6 到 curl配置到这一步可以完整走一遍端到端测试了。我的建议是先在本机做翻译层测试再从真实客户端做 DNS64 测试两步分开能更快定位问题出在翻译还是 DNS。第一层测试在 tayga 所在机器直接访问 NAT64 地址。找一个测试目标的192.0.2.8对应的 IPv6 地址ping6 -c 4 64:ff9b::c000:208 curl -g -v http://[64:ff9b::c000:208]/curl -g是让 curl 跳过对 URL 中方括号和冒号的“非法字符”检查。如果看到 HTTP 响应说明 TCP 翻译路径正常。注意 curl 访问时如果目标服务是基于域名做虚拟主机请求头里的 Host 会是这个 IPv6 地址的方括号形式部分 Web 服务可能会拒绝这属于应用层逻辑不代表 NAT64 有问题。第二层测试换一台纯 IPv6 客户端把 DNS 设置为 DNS64 服务器地址然后直接访问业务域名。比如前面那个域名返回的 AAAA 是64:ff9b::c000:208客户端就会通过 tayga 访问 IPv4 的192.0.2.8。此时可以用tcpdump在 tayga 机器的物理网卡上抓包观察是否存在 IPv4 出方向流量sudo tcpdump -i eth0 ip -nn看到目标端口为 80 或 443 的 IPv4 包且源地址是 tayga 动态地址池里的某个地址就说明 NAT64 转换确实发生在了物理网卡层面。我之前排查问题时用这一招最快区分出“流量根本没到 tayga”和“tayga 转换后没发出去”两种故障。第三层测试是长时间跑一个小并发脚本验证 NAT64 连接跟踪和端口复用是否稳定。可以用 netcat 或一个简单的 HTTP 请求循环。tayga 是用户态程序连接并发升高后 CPU 占用也会上升所以生产使用前要先评估好吞吐量。我做过的压力测试里单机 tayga 在日常办公和中小并发场景下足够用但如果是大规模用户出口建议考虑硬件 NAT64 或内核模块方案。还有一类业务值得单独测试FTP、SIP 等带有内嵌 IP 地址的应用协议。NAT64 和传统 NAT 一样天然带不动这类需要在应用层交换地址信息的协议。如果你发现 FTP 数据连接建立不了、SIP 注册失败多半不是 tayga 配置问题而是要上 ALG 或在应用层改造。这一点在选型时就该跟业务方沟通清楚。7. 踩坑与调试数据包没到 TUN 接口时怎么办把我在实际部署中踩过的一些坑集中说一下这些坑单看手册未必能注意到但遇到问题时照着排查效率会高很多。最典型的问题是 tayga 进程正常、路由也加了但就是 ping 不通。这时候优先确认“目标地址是否真的被前缀匹配了”。用ip -6 route get 64:ff9b::c000:208查看内核选择的路由。如果返回结果里dev不是 nat64说明你的路由策略有问题。我当时就是有一条更精确的默认 IPv6 路由把包带走了排查了半天才意识到可以先用ip route get这种查询内核实际选路结果的方式比自己逐条比对路由表高效得多。第二个常见坑是TUN 接口显示 up但 tayga 没在监听。tayga 启动时如果配置文件里的>sudo mkdir -p /var/lib/tayga sudo chmod 750 /var/lib/tayga如果用的是非 root 用户运行 tayga还要通过--user参数指定运行用户或者在 systemd unit 里设置 User。注意 TUN 设备创建本身需要 root 权限所以普通用户运行时通常还是得让 systemd 先创建好设备再切换身份。第三个坑和防火墙有关。tayga 所在主机如果开了 firewalld 或 nftables要注意把进出 nat64 接口的流量放行尤其是 IPv6 侧。有些发行版默认防火墙策略只放行有限端口结果 ping6 不通、curl 不通tcpdump 抓包却能看到请求到达主机。审核配置是它已经被防火墙吃掉了这种情况在调试时很容易绕晕。可以在测试期间先临时systemctl stop firewalld或用 nft 列表检查规则确认是防火墙问题后再补长期规则。第四个坑是 tayga 日志不落盘。从源码编译安装时tayga 默认把日志输出到 syslog但不同发行版的 syslog 服务名不同。KeyarchOS 上我观察到日志通常是进/var/log/messages或 journald。看日志的方式journalctl -u tayga -f调试阶段我更推荐直接用前台调试模式日志直接打到终端信息更全sudo /usr/local/sbin/tayga --nodaemon --debug --conf /usr/local/etc/tayga.conf前台模式可以看到报文收发的详细过程尤其是地址转换前后的信息。如果日志里显示报文进入了 TUN 接口但转换失败多半是动态地址池耗尽或网络层防火墙拒收。如果日志里压根没有报文记录那问题一定在所配置的 NAT64 前缀路由上回到第一个坑继续查。写到这里整套 tayga-0.9.2-3 的安装和跑通流程已经覆盖完整了。最后分享一点个人体会用 tayga 这类用户态 NAT64 工具重点是理解“翻译引擎、路由引导、DNS64 合成”三个环节的关系而不是死记配置项。配置内容就那么几行任何问题出现时顺着报文走的路径一层层查基本都能快速定位。对我而言这次在 KeyarchOS 上的部署经历除了收获一套可用的 IPv6 过渡方案更大的价值是让我把 IPv6 报文的处理细节彻底理清了。后续如果再碰到纯 IPv6 环境访问老系统的需求我会直接复用这套思路把 tayga 换成别的 NAT64 实现也完全不慌。
阅读完成 · 觉得有帮助?