import socket import struct # use with # iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 2000 SO_ORIGINAL_DST = 80 # from linux/netfilter_ipv4.h def get_original_dst(conn): """Return (ip, port) of the original destination before REDIRECT.""" # Get raw sockaddr_in (16 bytes) odest = conn.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16) port, raw_ip = struct.unpack_from('!2xH4s', odest) ip = socket.inet_ntoa(raw_ip) return ip, port def main(): HOST = '0.0.0.0' PORT = 2000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) s.listen(10) print(f"Listening on {HOST}:{PORT}") while True: conn, addr = s.accept() try: orig_ip, orig_port = get_original_dst(conn) print(f"Connection from {addr}, originally to {orig_ip}:{orig_port}") except OSError as e: print(f"Could not get original destination: {e}") with conn: while True: data = conn.recv(1024) if not data: break conn.sendall(data) if __name__ == "__main__": main()