为广域网WoL远程开机解决OpenWrt ARP绑定(IP/MAC绑定)无效的问题
写在前面:我非专业人士,对编程、计算机理论仅有皮毛认识,没有系统的学习,经常知其然不知其所以然,所以我说的话可能一些在大佬看来很睿智,请见谅。
一、遇到的问题
最近我在重组家庭组网,更换了主路由,遇到了个烦心的问题——我平时为了能在外网串流我的PC中的游戏(用的Moonlight),需要用到WoL功能远程唤醒家里的PC,而且是在广域网(外网)使用WoL。这就需要路由器支持ARP绑定(PC的WoL相关的设置和路由器端口映射也得做好)。而我的刷了OpenWrt的软路由,它的ARP绑定却不好使。明明系统设置是有这个设置,但是就是不生效,具体表现为——
OpenWrt的“IP/MAC绑定”中已设置了绑定,但用ip neigh命令查看arp表的时候,发现条目状态为REACHABLE而并非PERMANENT,该主机关闭后,本条arp信息即失效,未形成永久绑定关系。
这会导致通过端口映射发送来的远程唤醒包无法抵达IP/MAC绑定的主机,主机无法通过外网端口映射唤醒。
具体见下图(上面这段话和下面这图都是我引用后文提到的Fyred大佬的):
二、着手解决
百度查阅很久后并没有找到特别好的办法,甚至相关的讨论都没几个,但是还是找到了一些说法。
总结一下就是要手动敲代码来绑定,但貌似是因为OpenWrt的arp命令不完整,使用arp -a、arp -s 和arp -d等等的arp命令全是只能浏览不能修改arp信息,所以要用以下代码(IP和MAC请替换成自己的):
ip neigh add "IP" lladdr "MAC" nud permanent dev br-lan
这条命令中的nud permanent代表把IP和MAC地址永久绑定的,除非你手动删除这个条目, 或者系统重启。
使用这代码后,再输入以下代码:
ip neigh show
相关的条目应该就显示 PERMANENT了。
再输入以下代码确认:
cat /proc/net/arp
显示 Flags 为 6即表示成功绑定了。
以为这就万事大吉了吗?并不是 当我输入以上代码的时候,会显示File exist错误,这表示arp表里已经有对应的ip/MAC的动态绑定条目了!这是一个莫名其妙的情况,它的绑定状态明明是默认的REACHABLE,咋就被谁绑定了?
搞不懂,但既然如此,我们不能用ip neigh add代码了(add表示增加绑定关系),改为用:
ip neigh chg "IP" lladdr "MAC" nud permanent dev br-lan
chg也可以改成change、replace。代表把IP/MAC的绑定关系改为“PERMANENT”。这样的话应该就成功了.....吧?
然而现实再一次击打我这个菜鸟 明明已经绑定为PERMANENT的IP,过了一会之后再查询居然变成了REACHABLE!? 时间不确定多久,但是REACHABLE条目是动态绑定的,关机后REACHABLE必然会老化成FAILED,然后从路由表上消失,广域网WoL也当然失效。
这实在已经超出我这菜鸟的水平范围之外了,只能寄托于百度。没想到最后真的搜到github上有人提出了一条Issue,题主Fyred看来比较懂行的,他描述遇到的问题就是跟我的一模一样,但是他表达得很清晰、很到位,还表达了自己的一些猜想,大家可以去看看:
这条issue虽然最后大家也没讨论出个合理的解决办法,但是我很感谢他,它让我看清楚了并不是我的设置有问题,而看来是OpenWrt本身的问题,有可能是部分内核版本才会有问题(我是4.19)。他提到了OpenWrt的IP/MAC绑定功能是通过arpbind启动脚本来实现的,而这脚本的代码是写的"ip neigh add",在这个莫名的环境下绑定失败了;然后他还提出了一个重要的猜想——“路由器启动后还有什么程序在改动ARP表”,据我观察正是这个程序一直在运作,这也导致用add命令的时候提示“File exist”,也导致明明绑定成PERMANENT了还会被变回REACHABLE。
搞清楚了不是我的问题,但是这让我更蛋疼,因为我折腾家庭组网已经弄吐了(这是另外一个故事了),不想再尝试换OpenWrt内核,不换内核的话我又不懂代码,无从入手。
三、最终解决方案
最后是一位很耐心教学的大佬点拨了我一个治标不治本但是很实际有效的办法——既然是是因为IP/MAC条目被未知的程序持续改写成REACHABLE进而导致关机后在路由表中只能维持一段时间,那么我弄个一直执行的脚本,持续地主动改写这条目为PERMANENT不就可以了吗?
OpenWrt中正好有“计划任务”这个功能,可以免去手动敲crontab命令。在里面新增一行代码:
*/5 * * * * ip neigh chg "IP" lladdr "MAC" nud permanent dev br-lan
前面的“5”代表每5分钟就执行一次,这个时间可以自己观察多久路由表被改写然后自定义。
但是以上代码只能在PC已经启动(即路由表中有PC的IP)的时候才可以生效,不然就会显示No such file or directory——没有IP当然改不了。那么可以把代码增加一部分:
*/5 * * * * ip neigh add "IP" lladdr "MAC" nud permanent dev br-lan || ip neigh chg "IP" lladdr "MAC" nud permanent dev br-lan
计划任务会先执行前半段代码,在关机、路由表中没有记录的时候用add命令就能新增PERMANENT的记录。如果已经有了记录,那前一段代码执行会失败,则自动执行后一段chg代码。这样不就万无一失了嘛
四、最终成果
最后实践,即使关机很久,路由表中依然有PC的IP和MAC条目,广域网WoL也终于正常了!
感谢我在百度上看到的一切朋友的宝贵经验,感谢给我最终解决方案的大佬。我想着也许还有人跟我一样的需求、跟我一样碰壁,特意整理了这篇经验帖,希望能帮助到你们。大神们觉得有更好更容易的办法也请不要嘲讽我....
我这文章除了希望帮到其他人之外,也是抛砖引玉,如果有大神了解真正的问题症结所在,希望不吝赐教!
值友7515578633
校验提示文案
sman
校验提示文案
swufefx
校验提示文案
值友8776195967
校验提示文案
和鱼一起飞翔
校验提示文案
沙琪王子
给楼主推荐我的写法,用replace:
* * * * * ip neigh replace 10.10.10.200 lladdr BB:BB:BB:BB:BB:BB nud permanent dev br-lan
校验提示文案
值友4014158107
校验提示文案
值友8977309072
校验提示文案
swufefx
校验提示文案
宫保鸡丁盖浇饭
校验提示文案
值友3809438051
校验提示文案
塞巴
校验提示文案
价好就收
校验提示文案
值友7515578633
校验提示文案
值友4014158107
校验提示文案
价好就收
校验提示文案
和鱼一起飞翔
校验提示文案
塞巴
校验提示文案
值友3809438051
校验提示文案
沙琪王子
给楼主推荐我的写法,用replace:
* * * * * ip neigh replace 10.10.10.200 lladdr BB:BB:BB:BB:BB:BB nud permanent dev br-lan
校验提示文案
值友8776195967
校验提示文案
宫保鸡丁盖浇饭
校验提示文案
swufefx
校验提示文案
swufefx
校验提示文案
sman
校验提示文案
值友8977309072
校验提示文案