进阶篇:iStoreOS 完美解决多线 IPTV 播放问题!网关变了怎么办?

在之前文章《如何用 iStoreOS (OpenWrt) 实现多线上网 + 多线 IPTV》中,给粉丝朋友在 iStoreOS 中配置“电信上网 + 移动上网”以及“电信 IPTV + 广电 IPTV”的四口拆分与负载均衡。

当时配置主线路为电信线路,播放移动内网节目失败,后来粉丝有提到用静态路由配置,初步实现分流,让移动 IPTV 的单播源顺利走移动宽带拨号(PPPoE)出去了。

但这引出了一个非常致命的问题——断网重连后,电视就又看不了移动内网单播了!


🚨 为什么静态路由会“失效”?

在使用双线(电信为主,移动为辅)的场景下,为了让移动 IPTV(例如 CHINAMOBILE 接口)的内网流量强制走移动线路,通常会在 iStoreOS 的 网络 -> 路由 -> 静态 IPv4 路由 中手动指定 IP 段。

如图所示,我们需要把 39.0.0.0/8120.0.0.0/8 等移动的 IP 段绑定到 CHINAMOBILE 接口,并指定网关

图片静态路由配置说明

初期配置好后,单播播放如丝般顺滑。但运营商的 PPPoE 拨号是动态 IP 和动态网关 的!

一旦路由器重启,拨号网关就变了(比如从 100.67.201.1 变成了 100.67.112.1)。但是,静态路由表里的网关依然是上一次填写的旧网关

此时,静态路由因为网关不可达而彻底失效,所有的移动 IPTV 单播流量就会“漏”到默认的电信主干线上,由于跨网鉴权失败,电视播放失败。


🛠️ 解决方案:用 Shell 脚本实现网关自动跟随

既然手动填写的静态网关无法应对动态变化的 PPPoE 网关,我们就写一个脚本,让路由器自己去对比实际网关和路由表网关 ,发现不一致就自动修改并重载网络

1. 编写自动监测脚本

我们在路由器的 /opt/scripts/ 目录下创建一个名为 sync_route.sh 的脚本(使用终端 SSH 登录操作):

#!/bin/sh  
IFACE="CHINAMOBILE"  
LOG="/mnt/sata1-4/cm.log"  
MAX_LINES=100

# 获取当前时间  
NOW=$(date '+%Y-%m-%d %H:%M:%S')

# 获取实际网关  
REAL_GW=$(ubus call network.interface.${IFACE} status 2>/dev/null | \  
    grep -A3 '"target": "0.0.0.0"' | grep '"nexthop"' | \  
    grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')

if [ -z "$REAL_GW" ]; then  
    echo"$NOW [!] ${IFACE} 当前未获取到有效网关,跳过。" >> "$LOG"  
else  
    echo"$NOW => ${IFACE} 当前实际网关: ${REAL_GW}" >> "$LOG"  
      
    CHANGED=0  
    INDEX=0  
    whiletrue; do  
        ROUTE_IFACE=$(uci -q get network.@route[${INDEX}].interface 2>/dev/null)  
        [ -z "$ROUTE_IFACE" ] && break  
          
        if [ "$ROUTE_IFACE" = "$IFACE" ]; then  
            CONFIG_GW=$(uci -q get network.@route[${INDEX}].gateway)  
            if [ "$CONFIG_GW" != "$REAL_GW" ]; then  
                echo"$NOW [!] 发现不一致:静态路由 [@route[${INDEX}]] 原网关为 ${CONFIG_GW},已更新为 ${REAL_GW}。" >> "$LOG"  
                uci set network.@route[${INDEX}].gateway="$REAL_GW"  
                CHANGED=1  
            else  
                echo"$NOW [√] 静态路由 [@route[${INDEX}]] 网关已经是最新 (${CONFIG_GW}),无需修改。" >> "$LOG"  
            fi  
        fi  
        INDEX=$((INDEX + 1))  
    done

    if [ "$CHANGED" = "1" ]; then  
        uci commit network  
        /etc/init.d/network reload  
        echo"$NOW => 配置已保存并重载生效。" >> "$LOG"  
    fi  
fi

# 限制日志行数:保留最后100行覆盖回原文件  
if [ -f "$LOG" ]; then  
    tail -n "$MAX_LINES""$LOG" > "${LOG}.tmp"  
    mv "${LOG}.tmp""$LOG"  
fi

2. 赋予执行权限

脚本保存后,一定要赋予它执行权限,并解决可能存在的 Windows 换行符问题:

sed -i 's/\r$//' /opt/scripts/sync_route.sh  
chmod +x /opt/scripts/sync_route.sh

3. 加入定时任务 (Cron),每 5 分钟自动巡检

在终端运行 crontab -e,添加以下内容:

*/5 * * * * /opt/scripts/sync_route.sh

然后重启 Cron 服务生效:/etc/init.d/cron restart


🎯 效果实测:无感知的自动切换

完成上述配置后,让我们来看看实际效果!

  1. 日常状态下 ,脚本每 5 分钟巡检一次,发现实际网关和路由表网关一致,安安静静不打扰网络,并在日志中打上 [√]

图片检测网口网关和路由网关是否一致

  1. 触发断线重连 ,我们模拟移动宽带掉线。接口重新拨号后,获取到了全新的网关:100.67.112.1(原来是 100.67.192.1)。

图片重新拨号网关变了

  1. 脚本介入 ,在下一个 5 分钟周期到来时,脚本敏锐地捕捉到了网关的变化!自动将静态路由表中的旧网关全部替换为新的 100.67.112.1,并执行了一次无感知的 network reload

图片自动更新路由网关和网口一致

刷新 iStoreOS 的静态路由页面,你会发现网关已经悄无声息地变成了最新的!

图片自动更新的路由表

电视画面仅卡顿了很短的时间(取决于重拨时间),就自动恢复了流畅播放,再也不用每次登录路由器后台手动改网关了!


💡 总结

通过 iStoreOS 自带的 ubusuci 命令体系,配合简单的 Shell 脚本,我们完美补齐了传统“静态路由”无法应对动态 PPPoE 的短板。

多线多拨 + IPTV 融合确实是个折腾但充满乐趣的过程。如果你家里也是复杂的多宽带环境,不妨试试这个方案!

当然还可以用php脚本对特定url强制走特定网口,并实现内网转全网通使用,且看后面文章分享。

你还有哪些 OpenWrt 的奇淫巧技?欢迎在评论区留言交流!如果这篇文章解决了你的问题,别忘了点赞、在看、转发给同样爱折腾的朋友哦! 👇


📚 往期精彩文章推荐


🌟 与你互动

嗨~这里是【医工学习日志】的温暖小窝!
📩 随时戳一戳 :后台留言任何问题,树树会带着光速回复闪现!
💡 奇思妙想征集令
👉 遇到有趣资源?戳我分享!
👉 想看的硬核测评?甩题过来!
🔥 你的脑洞,可能成为下期爆款文章哦~

如需有偿部署服务或商务,请加V注明来意,不闲聊:

图片



📝 栏目信息
策划编辑 ✨ 树树 ✨

技术支撑 @恩山无线论坛 & Github & 瀚思彼岸


📜 版权声明
内容说明:

  1. 原创文章转载请私信授权;

  2. 部分素材源自网络,版权归属原作者;

  3. 如觉侵权,请凭权属证明联系删除

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部