拓扑:2台linux电脑直连。没有 iptables 规则(除了 - iptables -A OUTPUT -p tcp -j NFQUEUE )没有防火墙。
路由定义为 - “路由添加默认开发 eth0”
在第二个 (192.168.1.1) 上运行 apache server 。
我有一个基于 libnetfilter_queue 的小程序,它监听 nfqueue 并将 dst ip 更改为 192.168.1.1 以防 dst ip 为 192.168.1.2(我知道我可以使用 iptables 来完成,但我的程序会做更多的事情将来),修复校验和并返回队列。
如果我调用 telnet 192.168.1.1 ,意味着我的程序不需要做任何操作,握手就可以了。如果我调用telnet 192.168.1.2,我的程序会更改目标。服务器获取 syn 并返回 syn-ack,但在获取 syn-ack 之后客户端首先发送。
任何人都可以建议吗?
您遇到的问题是您正在打开一个到一个端点 (192.168.1.1) 的 TCP 套接字,将目标重写为 192.168.1.2 并以某种方式确保将数据包发送回您的 NIC。
当这些数据包到达您的 NIC 时,您在 192.168.1.2 对应的 linux 内核中没有打开的 TCP 套接字,因此内核会发送一个 RST。
要阻止 RST 造成的损害,您唯一可以做的就是插入一条
iptables
规则,以丢弃从源 TCP 端口发往 192.168.1.2 的 TCP RST 数据包。完成后您需要删除此规则。如果你在一个方向上破坏了数据包,你应该检查另一个方向上的数据包是否属于这种损坏的连接并撤消它。
在您的情况下,源为 192.168.1.1 的传入数据包可能属于您损坏的连接,您应该将源设置回 192.168.1.2。
内核发送 RST,因为源地址与它发送 SYN 的地址不匹配(内核对您的地址转换一无所知)。
客户端忽略 syn-ack 并发送 rst 的原因是因为端口表这个端口是在 ip 192.168.1.2(原始 ip)下注册的,所以当 ip 192.168.1.1 使用相同的端口发送回 syn-ack 时,客户端发送 RST。
更多细节说明:
我在 IPTABLES OUTPUT 上有一条规则,它将输出数据包放入 nfqueue 中。显然在这个阶段,客户端已经分配了一个端口并用原始 ip 注册了它,当你更改 ip 时,这个注册不会改变。
我更改了 ip,并使用新的目标 ip 将其返回给 NFQUEUE。
一个 syn 被发送到固定的 ip,但是当它返回 syn-ack 时,他的 ip 没有在这个端口上注册。
所以解决方案是也有 INPUT 规则,当你从更改后的 ip 返回数据包时,将 ip 更改回原始 ip。
谢谢大家的帮助。