45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
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()
|
|
|