9

I'm using a TP-Link TL-WR1043ND router running OpenWrt and Gargoyle. I'd like to forward all traffic from my local network (served by the router) to a remote server transparently. Essentially as a socks proxy would work, just without the need to configure the connected client machines for proxy.

I've read that sshuttle is the way to go for this kind of requirement. After much fiddling, I finally managed to satisfy all prerequisites, and I can start sshuttle without any error messages, like this:

./sshuttle --dns -vvr XXXXXX@YY.YY.YY.YY 0/0

Where XXXXXX is my username at a remote server YY.YY.YY.YY sshuttle seems to initialize just fine, no error messages, adds all necessary rules to iptables, yet after the local proxy is established, I'm unable to connect anywhere from my local network. This is sshuttle's output:

Starting sshuttle proxy.
Binding: 12300
Listening on ('127.0.0.1', 12300).
DNS listening on ('127.0.0.1', 12300).
firewall manager ready.
c : connecting to server...
c : executing: ['ssh', 'XXXXXX@YY.YY.YY.YY', '--', 'P=python2; $P -V 2>/dev/null || P=python; exec "$P" -c \'import sys; skip_imports=1; verbosity=2; exec compile(sys.stdin.read(764), "assembler.py", "exec")\'']
c :  > channel=0 cmd=PING len=7 (fullness=0)
WARNING: Ignoring unknown argument '--'
XXXXXX@YY.YY.YY.YY's password:
server: assembling 'cmdline_options.py' (29 bytes)
server: assembling 'helpers.py' (914 bytes)
server: assembling 'ssubprocess.py' (13668 bytes)
server: assembling 'ssnet.py' (5446 bytes)
server: assembling 'hostwatch.py' (2270 bytes)
server: assembling 'server.py' (2370 bytes)
 s: latency control setting = True
 s: available routes:
 s:   69.64.32.0/22
 s:  > channel=0 cmd=PING len=7 (fullness=0)
c : connected.
Connected.
c : Waiting: 3 r=[3, 5, 9] w=[9] x=[] (fullness=7/0)
c :   Ready: 3 r=[] w=[9] x=[]
c : mux wrote: 15/15
c : Waiting: 3 r=[3, 5, 9] w=[] x=[] (fullness=7/0)
 s:  > channel=0 cmd=ROUTES len=14 (fullness=7)
 s: Waiting: 1 r=[4] w=[5] x=[] (fullness=21/0)
 s:   Ready: 1 r=[] w=[5] x=[]
 s: mux wrote: 15/15
 s: mux wrote: 22/22
 s: Waiting: 1 r=[4] w=[] x=[] (fullness=21/0)
c :   Ready: 3 r=[9] w=[] x=[]
c : <  channel=0 cmd=PING len=7
c :  > channel=0 cmd=PONG len=7 (fullness=7)
c : <  channel=0 cmd=ROUTES len=14
firewall manager: starting transproxy.
 s:   Ready: 1 r=[4] w=[] x=[]
 s: <  channel=0 cmd=PING len=7
 s:  > channel=0 cmd=PONG len=7 (fullness=21)
 s: mux wrote: 15/15
 s: Waiting: 1 r=[4] w=[] x=[] (fullness=28/0)
>> iptables -t nat -N sshuttle-12300
>> iptables -t nat -F sshuttle-12300
>> iptables -t nat -I OUTPUT 1 -j sshuttle-12300
>> iptables -t nat -I PREROUTING 1 -j sshuttle-12300
>> iptables -t nat -A sshuttle-12300 -j RETURN --dest 127.0.0.0/8 -p tcp
>> iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 0.0.0.0/0 -p tcp --to-ports 12300 -m ttl ! --ttl 42
>> iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 127.0.0.1/32 -p udp --dport 53 --to-ports 12300 -m ttl ! --ttl 42
c : mux wrote: 15/15
c : <  channel=0 cmd=PONG len=7
c : received PING response
c : Waiting: 3 r=[3, 5, 9] w=[] x=[] (fullness=0/0)
 s:   Ready: 1 r=[4] w=[] x=[]
 s: <  channel=0 cmd=PONG len=7
 s: received PING response
 s: Waiting: 1 r=[4] w=[] x=[] (fullness=0/0)

I have no idea how to even start debugging this issue. If I stop sshuttle, it will remove the iptables rules and network connections will work again:

firewall manager: undoing changes.
>> iptables -t nat -D OUTPUT -j sshuttle-12300
>> iptables -t nat -D PREROUTING -j sshuttle-12300
>> iptables -t nat -F sshuttle-12300
>> iptables -t nat -X sshuttle-12300
c :
c : Keyboard interrupt: exiting.

Has anyone managed to set up a working sshuttle instance on openwrt? Or is there any other way to achieve what I need here (transparent proxy on an openwrt router)?

Related and unanswered question: sshuttle on a DD-WRT / OpenWRT Router

11
+100

Luckily I got an answer at the sshuttle google group from the author of sshuttle. He wrote:

You might need to add '-l 0.0.0.0' (that's a lowercase L) in order to tell sshuttle to listen for connections from other than localhost (the router itself). For security reasons, sshuttle won't route other people's traffic by default.

And it works perfectly! Use:

./sshuttle -l 0.0.0.0 --dns -vvr XXXXXX@YY.YY.YY.YY 0/0

1
  • My use case is running sshuttle on the host for forwarding traffic of Docker containers while they are building, and this works great. Oct 1 '14 at 12:42
5

A few things that tripped me up:

From stock OpenWRT 12.09 AA, you have to install these packages:

  1. python (with dependencies, consumes 3-4 MB of flash)
  2. iptables-mod-nat-extra
  3. iptables-mod-ipopt

Then, to SSH into the remote server using an SSH key, you have to create a Dropbear-format key:

dropbearkey -t rsa -f /root/.ssh/id_rsa

And finally, provide the key location on the sshuttle command line:

./sshuttle -e "ssh -i /root/.ssh/id_rsa" -l 0.0.0.0 -r xxxxxx@yy.yy.yy.yy 0/0 -vv --dns
0

On GL-AR300M router which runs OpenWrt Chaos Calmer 15.05 the procedure seems to be slightly different than what @trapezoid described. Maybe it's not quite stock OpenWRT (I didn't reinstall after buying), or it's just the passage of time.

I installed the packages they named, i.e. python iptables-mod-nat-extra iptables-mod-ipopt.

For ssh key based login to work, I didn't need to generate a special ssh key, my usual one was enough, but the autorized_keys needed to be moved to /etc/dropbear/ (that is, ssh-copy-id didn't put it in the right directory).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.