我尝试将计算机连接到NAT的两端(由OpenWRT运行)并通过NAT建立TCP连接:
我使用python和SO_BINDTODEVICE选项通过NAT在服务器(在eth0上)和客户端(在wlan0上)之间发送数据包:
对于服务器:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((str(self.local_ip_addr),self.handler.port))
self.server.setsockopt(socket.SOL_SOCKET,25,self.iface.name+"\0")
self.server.listen(10)
while self.stopped() is False:
connect = self.server.accept()[0]
connect.settimeout(1)
connect.close()
self.server.close()
对于客户:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, 25, self.iface.name + "\0")
sock.settimeout(1)
try:
sock.connect((self.dest,self.handler.port))
sock.close()
expect socket.timeout, socket.error as e:
return -1
我的问题是连接超时了。我将两个接口都连接起来,似乎问题出在客户端:
我认为它可能与linux-kernel有关,拒绝从属于该机器的地址接收数据包但如果有人有线索那将会有很大的帮助!
编辑:我缩小了它:它确实是一个内核问题,从eth0发送的数据包被视为" martians"由内核,因为他们有一个本地IP地址作为源。设置net.ipv4.conf.all.accept_local=1
没有帮助,也没有停用net.ipv4.conf.all.rp_filter=0
。
答案 0 :(得分:1)
在浏览内核源代码并添加大量KERNEL_WARNING后,我们发现它来自哪里:linux内核在某些主流发行版(Ubuntu ...)上配置充当路由器并丢弃源地址可疑的数据包为了防止欺骗(在https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt和RFC3704上搜索" rp_filter")
要允许此类流量,您必须在您的计算机上设置一些变量(以root身份):
sysctl -w net.ipv4.conf.all.accept_local=1
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.your_nic.rp_filter=0
其中your_nic
是接收数据包的网络接口。请注意同时更改net.ipv4.conf.all.rp_filter
和net.ipv4.conf.your_nic.rp_filter
,否则它将无效(内核默认为限制性最强的设置)。