I adapted Sam Mason's answer to execute a UDP reverse connection.
This is the configuration:
HOST UDP-LISTEN <=> python cc <=> NAT <=> internet <=> server <=> python ll UDP-LISTEN
Host listen to a UDP port. You can reach the host from any third client that has acces to the server by using the reverse connection through the python script.
The first part is the listen listen script. It will listen for the client script on CC_PORT and will forward anything on SERVICE_PORT. It will also discard keepalive coming from the cc script.
import socket
from select import select
CC_PORT = 8881
SERVICE_PORT = 8880
LISTEN_IP='x.x.x.x'
sock_cc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_cc.bind((LISTEN_IP,CC_PORT))
sock_serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_serv.bind((LISTEN_IP,SERVICE_PORT))
sockets = (sock_cc, sock_serv)
for s in sockets:
s.setblocking(0)
client_serv=None
client_cc=None
# loop forever forwarding packets between the connections
while True:
avail, _, _ = select((sock_cc, sock_serv), (), (), 1)
# send a keep alive message every timeout
if not avail:
continue
for s in avail:
# something from the local server, forward it on
if s is sock_cc:
msg = sock_cc.recvfrom(8192)
client_cc=msg[1]
if client_serv is not None:
if msg[0] != b'keep alive':
sock_serv.sendto(msg[0], client_serv)
# something from the remote server
if s is sock_serv:
msg = sock_serv.recvfrom(8192)
client_serv=msg[1]
if client_cc is not None:
sock_cc.sendto(msg[0], client_cc)
The client client script
import socket
from select import select
DEST_IP = 'x.x.x.x'
DEST_PORT = 8881
LOCAL_IP = '127.0.0.1'
LOCAL_SERVICE = 8800
sock_remote = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock_remote.connect((DEST_IP,DEST_PORT)) sock_local = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock_local.connect((LOCAL_IP,LOCAL_SERVICE)) sockets = (sock_remote, sock_local) for s in sockets:
s.setblocking(0)
# loop forever forwarding packets between the connections while True:
avail, _, _ = select((sock_local, sock_remote), (), (), 1)
# send a keep alive message every timeout
if not avail:
sock_remote.send(b'keep alive')
continue
for s in avail:
# something from the local server, forward it on
if s is sock_local:
msg = sock_local.recv(8192)
sock_remote.send(msg)
# something from the remote server
if s is sock_remote:
msg = sock_remote.recv(8192)
# don't forward keep alives to local system
if msg != b'keep alive':
sock_local.send(msg)
Thanks again to Sam Mason for helping me solve this problem.