MitMproxy on Wifi with VLANs
This is a three step guide to building a portable mitmproxy cascade with conatainers.
Step 1: The container
The following compose file creates the whole container:
version: '3.9'
services:
mitmproxy:
image: mitmproxy/mitmproxy
command: >
sh -c "apt-get update && apt-get -y install iptables iproute2 &&
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 &&
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080 &&
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE &&
mitmweb --web-host 0.0.0.0"
ports:
- '127.0.0.1:8083:8081'
tty: true
stdin_open: true
networks:
incoming:
gate:
cap_add:
- NET_ADMIN
sysctls:
# don't know which one actually works, so I set both
- net.ipv4.conf.all.forwarding=1
- net.ipv4.ip_forward=1
networks:
incoming:
driver: macvlan
driver_opts:
parent: enp34s0.10
#ipvlan_mode: l2
macvlan_mode: bridge
ipam:
config:
- subnet: 192.168.91.0/24
#gateway: 192.168.91.1
gate:
The network incoming
will be reachable from outside the docker host with the vlan id 10
. By allowing ip forwarding in the sysctls:
section the traffic will be routed through the default gateway on the gate
network. The gate
network will have the eth0
network name and therefore we need to place the MASQUERADE rules on there.
Step 2: Create a Wifi with a tagged vlan
There are pretty nice GUIs for this by now. In Unifi this should be an easy option. If you own a Cisco AP like I do it's also pretty easy:
You also need to setup dhcp on your vlan. I did that with my Cisco AP too, but you might also do this inside the container.
Step 3: Creating the nginx backend
You still have to reach the web interface of the mitmproxy container. The compose config only forwards from localhost to the container's web interface, which is barely useful. So we put a nginx front on that with a nice domain and everything:
server {
listen :80 ;
server_name mitm.domain.tld;
# Might add ssl
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /srv/http/acme.sh/;
}
location / {
# This might look weird, but the dns rebinding
# protection demands this stupid workaround
proxy_set_header Host localhost:8083;
proxy_set_header Origin http://localhost:8083;
proxy_pass http://127.0.0.1:8083;
expires off;
proxy_http_version 1.1;
proxy_redirect http://$http_host:8083 http://$http_host;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
access_log off;
}
That should be it.