在 Armbian 上部署 sing-box TUN 后,我遇到了一个不太直观的问题:IPv6 ping 能通,但开启 auto_redirect 后,IPv6 HTTPS 连接超时。
最终发现,故障并不在 IPv6 公网路由或代理节点,而是 Linux 回环接口 lo 缺少 ::1/128 地址。本文记录定位过程和修复方法。
环境
- Linux:Armbian,ARM64,6.18 系列内核
- sing-box:1.14.x
- 网络管理:Netplan + NetworkManager
- 透明代理:TUN,
auto_route: true,auto_redirect: true - IPv6:上游自动配置,接口已有全局 IPv6 地址和 RA 默认路由
为保护隐私,本文省略了真实公网地址、MAC、路由器地址、域名及自定义内部路由表编号。以下示例中的 ULA 地址和测试目标用于演示。
故障现象
直接测试 IPv6 HTTPS:
curl --noproxy '*' -6 -v --connect-timeout 5 \
--resolve 'cloudflare.com:443:[2606:4700::6810:85e5]' \
https://cloudflare.com/
开启 sing-box 后:
* Trying [2606:4700::6810:85e5]:443...
* Connection timed out after 5002 milliseconds
curl: (28) Connection timed out
对照实验:
| 状态 | IPv6 HTTPS |
|---|---|
| 停止 sing-box | 正常 |
auto_redirect: true | 超时 |
auto_redirect: false | 正常 |
单纯的 ping -6 测试却可能成功。ICMP 连通不能替代 TCP/HTTPS 测试。
排查过程
1. 排除 IPv6 地址与默认路由问题
ip -6 addr show dev eth0 scope global
ip -6 route show default
接口已有全局 IPv6 地址,默认路由由 RA 学到,形如:
default via fe80::... dev eth0 proto ra
NetworkManager 管理 IPv6 时,不应仅凭 net.ipv6.conf.eth0.accept_ra 的值判断 RA 是否正常;需要结合实际地址及路由观察。
2. 发现 TCP 未直接出现在 tun0 或 eth0
通过抓包观察 HTTPS 目标:
sudo tcpdump -ni tun0 'ip6 and tcp port 443'
sudo tcpdump -ni eth0 'ip6 and tcp port 443'
在启用 auto_redirect 的情况下,未看到预期的目标 IPv6 TCP SYN。这不一定是丢包:sing-box 的 nftables 规则可能先将 TCP 重定向到本地端口。
3. 检查 nftables 的本地 REDIRECT
sudo nft -a list table inet sing-box
规则中可见类似内容:
meta l4proto tcp ... queue flags bypass to 100
meta l4proto tcp ... redirect to :23457 return
其中端口为本次排查环境中的内部监听端口,其他版本或配置可能不同。检查 IPv6 监听:
sudo ss -6 -lntp '( sport = :23457 )'
sing-box 确实在监听该端口。
继续抓回环接口:
sudo tcpdump -ni lo -vv 'tcp port 23457'
此时看到的关键报文形如:
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
上面的
2001:db8::/32是文档专用 IPv6 示例前缀,不是真实公网地址。
SYN 不断重传,没有 SYN-ACK,说明连接已经重定向到本机 ::1,但本地 TCP 握手没有完成。
4. 找到根因:回环接口缺失 IPv6 地址
ip -6 addr show dev lo
输出竟然为空。正常情况下,回环接口应该有:
inet6 ::1/128 scope host
由于缺少 ::1/128,IPv6 TCP REDIRECT 指向本地 ::1 后无法正常建立连接。这与抓到的重复 SYN、无 SYN-ACK 现象吻合。
修复方法
先检查 lo 的 IPv6 状态:
ip link show lo
sysctl net.ipv6.conf.lo.disable_ipv6
ip -6 addr show dev lo
如果禁用了 IPv6:
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
确保回环接口已启用:
sudo ip link set lo up
如果 ::1/128 仍没有出现,手动补充:
sudo ip -6 addr add ::1/128 dev lo
验证:
ip -6 addr show dev lo
ping -6 -c 2 ::1
curl --noproxy '*' -6 --connect-timeout 5 https://api6.ipify.org
确认 auto_redirect: true 时 HTTPS 也正常,才算解决了该故障。
如果问题发生在重启后,检查 /etc/sysctl.d/ 是否存在禁用 lo IPv6 的配置,可在 sysctl 配置文件中明确设置:
net.ipv6.conf.lo.disable_ipv6 = 0
需要注意:这项配置只是保证没有禁用 lo 的 IPv6,不等于自动保证 ::1/128 永远存在。如果重启后地址再次消失,应继续追查启动顺序或管理 lo 的服务。
总结
- IPv6
ping成功不能说明 IPv6 TCP 代理正常,必须使用真实 HTTPS 请求验证。 - 开启 sing-box
auto_redirect后,部分 TCP 流量会被 nftables 重定向到本地端口;只抓eth0或tun0可能看不到预期目标流量。 - 通过
ss确认监听、通过tcpdump -i lo发现 SYN 重传,是本次定位的关键。 - 最终故障点是
lo缺少 IPv6 回环地址::1/128。 - 临时关闭
auto_redirect能绕开问题,但修复回环接口才是针对本次故障的解决办法。
诊断命令速查
ip -6 addr show dev lo
sysctl net.ipv6.conf.lo.disable_ipv6
ip -6 route show default
sudo nft -a list table inet sing-box
sudo ss -6 -lntp '( sport = :23457 )'
sudo tcpdump -ni lo 'tcp port 23457'
后续补充:启用 UFW 后下游设备无法联网
在解决 IPv6 回环问题之后,为 Armbian 启用 UFW,又遇到新的现象:Armbian 本机访问网络正常,下游通过它联网的设备却无法正常访问网络。
首先查看 UFW 拦截日志:
sudo ufw logging medium
sudo journalctl -k -f -o cat | grep --line-buffered 'UFW BLOCK'
以下为经过脱敏的代表性日志,IP 使用 RFC 5737 文档示例地址,不能直接照抄到真实网络配置:
[UFW BLOCK] IN=eth0 OUT= SRC=192.0.2.20 DST=192.0.2.254 PROTO=TCP DPT=9091 SYN
[UFW BLOCK] IN=eth0 OUT= SRC=192.0.2.20 DST=192.0.2.254 PROTO=TCP DPT=22703 SYN
这里 OUT= 为空,目标是本机地址,因此这些请求被识别为 INPUT(访问 Armbian 本机),而不是常规的 FORWARD。此前直接怀疑 deny routed 并不完整。
随后用以下命令确认监听进程:
sudo ss -lntup | grep -E ':(9091|22703)\b'
结果显示两个 TCP 端口都由 sing-box 监听,其中一个绑定到 LAN IPv4,另一个绑定到通配地址。将对应入站端口放行后,下游设备恢复联网。需要强调:这能证明端口可达性与故障有关,但不能仅凭监听结果推断它们就是 TUN 端口或某项特定功能。应检查 sing-box 配置确定具体用途。
如果服务只供 LAN 使用,UFW 可以将规则限制到实际 LAN 地址和网段。下面仅是使用 RFC 5737 示例网段的规则模板,必须替换为自己的真实值:
sudo ufw allow in on eth0 from 192.0.2.0/24 to 192.0.2.254 port 9091 proto tcp
sudo ufw allow in on eth0 from 192.0.2.0/24 to 192.0.2.254 port 22703 proto tcp
安全提示:不建议直接执行没有来源限制的 ufw allow 22703/tcp;如果端口监听通配地址,还应特别检查公网 IPv6 是否被意外开放。也不应为了下游恢复联网,长期把全部 routed 流量改为默认允许。
本次补充的排障要点是:先按 IN / OUT 区分 INPUT 和 FORWARD,再确认监听进程,最后按实际来源精确放行。UFW 的状态页面也不能代替 nft list ruleset,因为 sing-box 的 auto_redirect 另有 nftables 规则。