Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with TCP hole punching

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:

Wireshark capture

But nothing ever prints "connected!" What am I doing wrong?

like image 534
George Hilliard Avatar asked Apr 23 '14 16:04

George Hilliard


People also ask

Is TCP hole punching possible?

One of the most effective methods of establishing peer-to-peer communication between hosts on different private networks is known as “hole punching.” This technique is widely used already in UDP-based applications, but essentially the same technique also works for TCP.

Does Skype use UDP hole punching?

Skype uses the UDP hole punching technique to allow communication between users who are behind NAT.

How does NAT hole punching work?

The basic story of a NAT Hole Punch is that, when both the Nodes who want to connect to each other send a message to the server. Server responds to both nodes with each other's IP address and Ports (Endpoints).

What is Port punching?

Hole punching (or sometimes punch-through) is a technique in computer networking for establishing a direct connection between two parties in which one or both are behind firewalls or behind routers that use network address translation (NAT).


1 Answers

The answer turned out to be quite simple: packets aren't considered RELATED if they aren't coming to the same IP address!

Changing the bind lines to

c.bind('', int(sys.argv[3])))

(the '' binds to the loopback address) fixes the problem entirely.

like image 191
George Hilliard Avatar answered Oct 07 '22 16:10

George Hilliard