我在飞牛OS上,遇到了一个因中国联通宽带IPv6拨号策略引起的异常。Openwrt 系统在被下线重播后,残留了上一次无效的IPv6前缀,并持续RA广播。
这导致FnOS基于的Debian12系统分配的地址中不仅包含有效的全局IPv6地址,还有上一次的无效地址。问题在于,系统自带的 Qbittorrent 因为绑定了错误的IPv6地址,无法连接到 BYRPT 的 tracker。(绑定全部地址无法解决)
问题原因
被下线重拨号产生无效RA广播
Openwrt在IPv6拨号后,系统会收到前缀。但由于某些不知道的原因,这些openwrt广播中带有上一次无效的IPv6前缀,导致QBitTorrent无法正确切换到新地址
Qbittorrent绑定错误地址
Qbittorrent 默认会使用启动时从系统中获取到的IPv6地址。如果该地址后续变为无效地址,则无法正常连接tracker服务。
解决思路
- 检测有效的IPv6地址:使用 ip -6 -o addr show 命令,结合 awk 过滤条件,提取出 scope 为 global 且 preferred_lft 不为 0 的有效IPv6地址。
- 地址比对与重启服务:将当前检测到的全局地址与之前记录的地址进行比对,如果发生变化,则更新记录并 kill 掉 Qbittorrent 进程,等待其自动重启,从而重新绑定正确的IPv6地址。
脚本源码
#!/bin/bash
# 保存地址的文件
ADDR_FILE="/tmp/current_ipv6"
# 使用 -o 选项每条记录输出在一行,通过 awk 过滤只保留 scope 为 global 且 preferred_lft 不为 0 的 IPv6 地址,
# 同时排除地址中的掩码部分,取最新一条作为当前地址
new_addr=$(ip -6 -o addr show | awk '/inet6/ && /scope global/ && /preferred_lft/ && $0 !~ /preferred_lft 0sec/ {print $4}' | cut -d/ -f1 | tail -n1)
# 如果未找到有效的全局地址,则提示并退出
if [ -z "$new_addr" ]; then
echo "未找到有效的全局 IPv6 地址"
exit 0
fi
# 读取之前保存的地址(如果文件存在)
old_addr=""
if [ -f "$ADDR_FILE" ]; then
old_addr=$(cat "$ADDR_FILE")
fi
# 如果地址发生变化,则更新记录并 kill qbittorrent-nox 进程
if [ "$new_addr" != "$old_addr" ]; then
echo "检测到地址变化: 旧地址: ${old_addr:-空}, 新地址: $new_addr"
echo "$new_addr" > "$ADDR_FILE"
# 查找 qbittorrent-nox 进程 PID(使用正则过滤掉 grep 自身)
pid=$(ps -aux | grep [q]bittorrent-nox | awk '{print $2}')
if [ -n "$pid" ]; then
kill "$pid"
echo "已 kill qbittorrent-nox 进程 (PID: $pid),等待其自动重启..."
else
echo "未找到 qbittorrent-nox 进程"
fi
else
echo "地址无变化,当前地址为: $new_addr"
fi
总结
通过该脚本自动监控系统的IPv6地址变化,并在检测到地址发生变化时重启Qbittorrent,使其重新绑定到正确的全局IPv6地址上。对于类似的网络环境问题,该方法提供了一种简单而有效的 Workaround。