Я пытаюсь подключить свой компьютер к обеим сторонам NAT (под управлением OpenWRT) и установить TCP-соединение через NAT:
- Я запускаю DHCP-сервер на своем первом сетевом адаптере (eth0, IP-адрес 129.104.0.1) и подключаю его к WAN-порту маршрутизатора (IP-адрес 129.104.0.198).
- Я подключаю свой Wi-Fi (wlan0, IP-адрес 192.168.1.119) к SSID маршрутизатора за NAT
Я использую python и параметр SO_BINDTODEVICE для отправки пакета между сервером (на eth0) и клиентом (на wlan0) через NAT:
Для сервера:
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
Моя проблема в том, что время ожидания соединения истекло раньше. Я подключил оба своих интерфейса, и кажется, что проблема находится на стороне клиента:
- wlan0 отправляет пакет TCP SYN на 129.104.0.1
- Пакет правильно транслируется маршрутизатором по NAT и принимается с адреса 129.104.0.198 через eth0.
- eth0 отвечает пакетом SYN, ACK, который корректно пересылается по NAT обратно на wlan0.
- wlan0 не понимает этот SYN,ACK и пытается повторно передать первый SYN-пакет
Я думаю, что это может быть как-то связано с отказом ядра linux получать пакет с адреса, принадлежащего машине, но если кто-нибудь знает, это будет очень полезно!
РЕДАКТИРОВАТЬ: я сузил его: это действительно проблема ядра, пакеты, отправленные из eth0, воспринимаются ядром как «марсиане», потому что они имеют локальный IP-адрес в качестве источника. Установка net.ipv4.conf.all.accept_local=1
не помогла, отключение net.ipv4.conf.all.rp_filter=0
тоже.