First, my setup:
- a cable modem and a Fritz!Box connecting me to the Internet
- a PC connected via network cable to the Fritz Box
- multiple Wi-Fi devices, also connected to the Fritz Box
Here is what I want to achieve: I want to set up something like a network proxy server on a separate machine, that intercepts and (potentially) relays ALL traffic between any device in my network and the Internet. I don't care about traffic between devices in my network. I don't want to be limited to messages on a certain protocol / port / IP address. My main goal is to learn about networking / protocols, etc., and implement multiple applications / play around on that proxy server. Examples could be:
- Collect statistics about all IPs / ports that had ongoing communication (so, basically forwarding all traffic, and doing some counts)
- block some traffic (e.g., prevent the kids from accessing stuff that they shouldn't see, based on IP address. Prevent software to send privacy-related data about me.)
- warn about new devices in my home network (e.g., somebody misusing my Wi-Fi)
- change messages before forwarding them (e.g., adding text to web content coming in)
- send own messages to either a server on the Internet, or to one of the connected devices (e.g., collected usage statistics to be displayed in a web interface)
- many more ...
Assuming that I have a Unix (/ Linux) machine available:
- Network setup: What network topology would be needed? Where in my network do I need to place the proxy machine?
- Settings: What do I need to configure on the proxy, in order to receive and forward all incoming and outgoing traffic? I do NOT want to change settings on the host devices. Connecting them to the network should be enough.
- Programmability: What do I need to set up additionally, in order to read / modify / write / send / block messages/packets using Python?
- Limitations: Would such a setup mean a serious impact on my network speed?
--- EDIT --- I made some progress and created a python script that accepts incoming connections. Furthermore, I set the wifi connection of another machine to use the first one as a gateway. I successfully receive messages now, but the problem is, that I don't have any idea where they actually should be sent to. I would assume that I have to change the socket configuration and use transparent proxies, but I didn't find much about how to actually do this in python. Also, my script runs currently on a mac, so maybe not every option for sockets is available.
Below my current snippet:
import socket
def received_from(sock, timeout):
dt = ""
sock.settimeout(timeout)
try:
while True:
dt = sock.recv(4096)
if not dt:
break
dt = + dt
except:
pass
return dt
def hexdump(data, length=16):
filter = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
lines = []
digits = 4 if isinstance(data, str) else 2
for c in range(0, len(data), length):
chars = data[c:c+length]
hex = ' '.join(["%0*x" % (digits, (x)) for x in chars])
printable = ''.join(["%s" % (((x) <= 127 and filter[(x)]) or '.') for x in chars])
lines.append("%04x %-*s %s\n" % (c, length*3, hex, printable))
print(''.join(lines))
s = socket.socket()
print("Socket successfully created")
try:
port = 12222
s.bind(('', port))
print("socket bound to port {}".format(port))
s.listen(5)
print("socket listening")
print("proxy sock: {}".format(s.getsockname()))
while True:
try:
c, addr = s.accept()
print("got connection from {}".format(addr))
print("client peer: {}".format(c.getpeername()))
print("client sock: {}".format(c.getsockname()))
data = received_from(c, 3)
hexdump(data)
print()
c.send("Connection received. Thanks and bye!".encode('utf-8'))
c.close()
except Exception as e:
c.close()
raise e
except Exception as e:
s.close()
raise e