用iptables实现一个特殊场景的路由转发
背景:
一个玩具(早教机器人)厂家因为跟比特币有点关联,难逃倒闭的厄运,厂家连带服务器全部关停,导致市场上有大量的早教机瘫痪了。笔者比较幸运,不是倒闭前买的早教机,是机缘巧合拿到了这么一台,研究了一番,看看有无起死回生的可能
过程:
拆机看了一眼,内部做工相当精巧,布局也很紧凑,不是一般的玩具厂商的手笔,倒闭了实在可惜。
通过app代码反编译+拆机,分析出来玩具的运动是通过蓝牙控制;视频是通过服务器转发;蓝牙容易搞定;视频转发有点难度,本文探索了路由器ip转发的原理,发现可行,记录如下:
目标:
假设玩具固件中写死的服务器ip是ip1, 新搭建的服务器是ip2;因为玩具的固件是改不了的(笔者尝试了,没有发现固件内明显的漏洞),那么目标就很明确,要把固件访问的ip1篡改成ip2,并且要把ip2返回的数据再正常转发给固件。
思路:
因为固件改不了,所以这个篡改过程只能在路由器上完成,用iptables的prerouting和postrouting应该很合适。
先贴个routing原理图
上图中左边箭头代表上行,也就是固件向服务器请求数据,prerouting发生在路由选择前,既然还没有路由选择,所以在这个阶段改目的地址就很合适了。
先交代下:
假设玩具固件中写死的服务器ip是ip1, 新搭建的服务器是ip2;
iptables -t nat -A PREROUTING -d ip1 -j DNAT --to-destination ip2
这个NAT规则代表把所有数据包中的目的地址从ip1替换为ip2,因为是在路由器上完成的,玩具固件并不感知
同理
上图中右边箭头代表下行,也就是服务器向固件返回数据,postrouting发生在路由选择后,数据已经从路由器外网网卡eth0转到了内网网卡eth1了,下一步数据就要达到固件了,在这时进行SNAT就非常合适了,把数据包中的source ip由真实的ip2替换为原来的ip1, 让固件能正确处理返回的数据。iptables规则如下:
iptables -t nat -I POSTROUTING -s ip2 -j SNAT --to-source ip1
这个NAT规则代表把所有数据包中的源地址从ip2替换为ip1,同理,因为是在路由器上完成的,玩具固件并不感知这个过程,但数据真实的返回给了玩具固件。
上述两个规则的原理如下:
1)PREROUTING:在数据包传入时,就进到PREROUTIING链。该链执行的是修改数据包内的目的IP地址,即DNAT(变更目的IP地址)。PREROUTING只能进行DNAT。因为进行了DNAT,才能在路由表中做判断,决定送到本地或其它网口。
2)POSTROUTING:相对的,在POSTROUTING链后,就传出数据包,该链是整个NAT结构的最末端。执行的是修改数据包的源IP地址,即SNAT。POSTROUTING只能进行SNAT。
?
完成上述两条iptables规则后,数据的上下行都搞定了。而且,从固件的视角,它以为是跟ip1交互,实际上路由器帮它完成了跟ip2的交互过程。从路由器视角看,这种任务也是很轻松就能完成的,因为NAT转换就是路由器的本职工作。
引申:
为了理解和记忆,进一步思考路由器的实现原理。最通常的场景下,当局域网的设备访问公网,数据包到达路由器并进行路由选择后,路由器在POSTROUTING阶段,会自动把源ip替换为路由器的ip,也就是SNAT过程;
当公网数据返回到路由器后,路由器必须把数据转发给内网设备,所以必须在路由选择前,也就是PREROUTING阶段把目的ip改成原来的内网设备的ip,也就是DNAT过程,然后再进行路由选择,实现数据转发到内网设备中。
所以正常的内网设备访问公网,上网过程是先SNAT(POSTROUTING)再DNAT(PREROUTING),这个过程是路由器的本职工作,所以不需要用户手动添加iptables规则。
笔者描述的上述场景是先DNAT(PREROUTING)再SNAT(POSTROUTING),这个不是路由器正常的业务逻辑,所以,需要添加额外的iptables规则
过程记录完毕,加上自己的浅显的一点理解,完毕。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!