I've tried to write a basic TCP hole puncher for a firewall in Python 3 using the principles outlined in this article. I'm having trouble getting anything to connect, though. Here is the code:
#!/usr/bin/python3
import sys
import socket
import _thread as thread
def client():
c = socket.socket()
c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
while(c.connect_ex((sys.argv[1], int(sys.argv[2])))):
pass
print("connected!")
thread.interrupt_main()
def server():
c = socket.socket()
c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
c.listen(5)
c.accept()
print("connected!")
thread.interrupt_main()
def main():
thread.start_new_thread(client, ())
thread.start_new_thread(server, ())
while True:
pass
if __name__ == '__main__':
main()
I decided to try the puncher on my local machine, so that I could capture all the traffic sent by both instances. I first set up a loopback firewall:
iptables -A INPUT -i lo -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j DROP
Then I launched two copies of the script:
left$ ./tcphole.py localhost 20012 20011
and
right$ ./tcphole.py localhost 20011 20012
I can see according to Wireshark that the SYN packets are being transmitted both ways:
But nothing ever prints "connected!" What am I doing wrong?
SYN
packets onlo
? There are no "ESTABLISHED" or "RELATED" connections in your example, right? – NPE