Monday, April 20, 2015

a tale of two tunnels, in which iptables proxies a bridge

poor man's VPN for android emulator
  • genymotion
  • running on virtualbox
  • running on an ubuntu linux host
  • redirected thru a transparent proxy on the host
  • routed thru an ssh tunnel to a remote server ( in the examples)
  • iptables based masquerade for NAT
i thought this should be pretty simple, but it ended up being a couple days of work, so documenting it here. i'm not a networking guy, so most of this was trial and error based on google searches

on both the host and the remote machines:
  • sudo cp ~/.ssh/authorized_keys /root/.ssh
  • set in /etc/ssh/sshd_config
    • PermitTunnel yes
    • PermitRootLogin without-password
on the remote machine (venet0 is my connection to the LAN):
  • echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
  • sudo iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
  • sudo iptables -A FORWARD -i venet0 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
  • sudo iptables -A FORWARD -i tap0 -o venet0 -j ACCEPT
  • sudo ifconfig tap0 netmask up

on the host:
  • ssh -C2qTnN -D 8082
  • sudo ssh -i ~/.ssh/id_rsa -o Tunnel=ethernet -f -N -w 1:0
  • sudo ssh -i ~/.ssh/id_rsa -o Tunnel=ethernet -f -N -w 0:2 root@localhost

  • sudo brctl addbr br0
  • sudo brctl addif br0 tap2
  • sudo brctl addif br0 tap1
  • sudo iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 8888
  • sudo iptables -t nat -A PREROUTING -i br0 -p tcp --dport 443 -j REDIRECT --to-port 8888

  • proxychains mitmproxy -p 8887
  • proxychains mitmproxy -T --host -p 8888

  • sudo ifconfig tap0 up
  • sudo ifconfig tap1 up promisc
  • sudo ifconfig tap2 up
  • sudo ifconfig br0 netmask up
  • adapter 1: unchanged (host-only, vboxnet0)
  • adapter 2: bridged adapter, tap0
~/.proxychains/proxychains.conf: socks5 8082, 8887

my intuition was i could have virtualbox bridge directly to br0 (and omit the local tunnel entirely). packets got sent to the remote tunnel correctly, but i couldn't get iptables to redirect them, so i added the local tunnel. at that point, iptables was pulling the packets from the bridge, but not routing them anywhere, they just silently disappeared. to fix that, i added the bridge IP and zeroed out the tunnel endpoint IPs, and everything worked (i read this advice several places, but don't understand why it works)

i use 2 proxies, both of which pass data over the ssh connection to port 8082
  • 8887 port uses the proxy mechanism provided by android
  • 8888 is a transparent proxy to catch anything else (i'm trying to document an api)
non-http/https stuff is passed thru the tap1 tunnel
  • monitor with: sudo tcpdump -vvvnni tap1
  • nothing should leak out thru the local network
  • must be 1 (ubuntu default): /proc/sys/net/bridge/bridge-nf-call-*
over the bridge and through the two tunnels
to genymotion's house we go
iptables knows the way to proxy the packets
thru the virtual and private network

No comments: