起因
在搬家后迁移联通的宽带,装维师傅给换了个光猫,换成了HG6145D2,然后之前好使的IPv6外网访问就失效了。
分析
查看路由器,IPv6地址可以正常分配。之后进入光猫后台,尝试一番后发现其防火墙功能残缺,无法像之前一样通过单独关闭IPv6防火墙或调整防火墙等级来实现IPv6外网访问。通过一番检索,了解到该款光猫可以通过指定网址来开启telnet,然后通过ip6tables命令来控制IPv6防火墙,从而实现IPv6外网访问。但是在之后的测试中却发现,光猫固件做的防范比较严格,没有找到可以利用的开机启动入口来实现控制固化。没办法,最终决定通过定时执行外部脚本来解决该问题。
处理
将操作步骤写成Python脚本,并通过我路由器上的supervisor进行托管执行。
关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| def main_task(): timeout = 10 while True: try: r = requests.get("http://192.168.1.1/telnet?enable=1&key=112233445566") if r.status_code != 200: raise Exception("status_code is not 200, it is {}".format(r.status_code)) with telnetlib.Telnet("192.168.1.1") as telnet: telnet.read_until(b"login: ", timeout) telnet.write(b"admin\n") telnet.read_until(b"Password: ", timeout) telnet.write(b"Fh@445566\n") telnet.write(b"rm -f /var/tmp.sh\n") telnet.write(b"echo '#!/bin/sh' >> /var/tmp.sh\n") telnet.write(b"echo 'ip6tables -vnL | grep FORWARD_CUSTOM' >> /var/tmp.sh\n") telnet.write(b"echo 'if [ $? != 0 ]; then' >> /var/tmp.sh\n") telnet.write(b"echo ' ip6tables -N FORWARD_CUSTOM' >> /var/tmp.sh\n") telnet.write(b"echo ' ip6tables -A FORWARD -j FORWARD_CUSTOM' >> /var/tmp.sh\n") telnet.write(b"echo ' ip6tables -A FORWARD_CUSTOM -p icmpv6 --icmpv6-type echo-request -j ACCEPT' >> /var/tmp.sh\n") telnet.write(b"echo ' ip6tables -A FORWARD_CUSTOM -p udp --dport 10000 -j ACCEPT' >> /var/tmp.sh\n") telnet.write(b"echo ' ip6tables -A FORWARD -j FORWARD_CUSTOM' >> /var/tmp.sh\n") telnet.write(b"echo 'fi' >> /var/tmp.sh\n") telnet.write(b"chmod +x /var/tmp.sh\n") telnet.write(b"/var/tmp.sh\n") telnet.write(b"rm -f /var/tmp.sh\n") telnet.write(b"exit\n") result = telnet.read_all() _LOGGER.info("success, wait 30 min for next") time.sleep(60*30) except Exception as e: _LOGGER.exception(e) time.sleep(60*1)
|
该代码适配时请注意如下几点:
- 光猫地址192.168.1.1请修改为自己的光猫地址
- 开启telnet的key为自己的光猫MAC地址
- telnet密码为自己的光猫MAC地址后6位
结果
通过外部控制脚本,实现了IPv6的外网访问,最多会在光猫重启后短暂的失败一段时间,但基本不影响正常使用。后续若能找到光猫上可用的开机启动入口,可以在光猫上就近部署脚本,进而解除外部依赖,缩短不可用时间。
参考
- 恩山无线论坛讨论贴
- Python的Telnet相关文档说明
- ip6tables命令说明