Networking – Home Network Proxy Server

networkingPROXYpythonrouter

First, my setup:

  1. a cable modem and a Fritz!Box connecting me to the Internet
  2. a PC connected via network cable to the Fritz Box
  3. 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

Best Answer

Here are some suggestions:

1) First of all, get access to your home gateway's (FritzBox) admin page. Usually is a username / password connection via browser to 192.168.1.1. Review settings of WAN, LAN, Wifi and read about it.

2) Install linux and commandline tools : tcpdump, netstat, nc, telnet

3) Have another machine windows / linux with user interface, install there Wireshark

4) Try to develop some simple python socket level programs (python socket libraries fit nicely on C socket API's)

5) Record traffic between programs on different computers with tcpdump, and examine packages with Wireshark

6) Try adding proxy server (dedicated machine) to your home LAN network.

7) Install programs like Apache web server, CuteFTP, SMPT Relay, MiniDLNA etc ...

You can use my cheetsheat for linux to experiment with network related stuff

8) Try to create your own SSL certificates, to secure connections between computers in your network.

Answers to your questions:

Network setup: proxy is placed on network like any other machine. But all machine's refer to it (use it as "gateway").

Settings: All machines need to be informed of a proxy (port, address) via configuration parameter.

Programmability: Nothing. it will work out of the box.

Limitations: Would such a setup mean a serious impact on my network speed? No.

Related Question