The ideea: start a ssh to a remote server and with iptables on tomato router direct the users behind it to
use this ssh tunnel for some (or maybe all) traffic. Just like socks proxy is used from browser with openssh client, but
in a transparent manner. For this dropbear ssh client needs a patch (remote sshd only needs to accept tcp forwarding)

Details:
Lets say the remote sshd server is at 1.1.1.1 and our tomato router is on 192.168.1.1. We want to direct all tcp traffic
from users behind tomato to 2.2.2.0/24 throughthe ssh tunnel.

Now when a tcp connection is done to 2.2.2.10 tomato linux kernel will send the connection to ssh client which will
see the orig target (2.2.2.10) and will send it via the ssh tunnel.
In the above ssh command , at -L it only matters the listen port 1111 and remote address 0, remote port is ignored.
Also the envvar BIND_TRPRXY is required, if one wishes to listen on all interfaces use 0.0.0.0 (this only works for ipv4)

I've put a dropbearmulti compiled with this patch on http://www.megaupload.com/?d=63MXGG6S for those that want to test it . Just upload it to router then 'ln -s dropbearmulti ssh' and run ./ssh ..

Interesting patch to dropbear. You might want to submit it upstream… Although, I am a bit confused why you pass in the BIND_TRPRXY as an environmental variable. Wouldn't ssh -L 192.168.1.1:1111:0:1 1.1.1.1|resu#1.1.1.1|resu work just as well? The other thing is it is actually legal to forward to address 0 in some situations. Instead I would check on port = 0, since that is never legal. e.g. ssh -L 192.168.1.1:1111:0:0 1.1.1.1|resu#1.1.1.1|resu

I do something similar with openssh+privoxy, but no patches required… I like your solution though, as it avoids the need to install optware, and the need to use a socks proxy.

I agree with Bill - the command line parameter would be a cleaner solution. Unlike the eapd case, you can change anything you want in dropbear sources, and you're already patching it anyway…

docbill: No actually, I'm saying there is no need. The listen address is already parsed from the command line as tcpinfo->listenaddr. So there is no need to add an environment variable to do the same thing…

Would you consider making this change?

docbill: I agree it is a good idea to put in this type of change. The comment about submitting it upstream, is this patch would be useful to more people that way. It doesn't mean we need to wait for it to be accepted upstream.

In this variation you can use "-" as the destination host, to cause the original destination to be used, and 0 for port to cause the original destination port to be used. So an example usages would be:

ssh -L 192.168.1.1:1111:-:80 -N -n user@1.1.1.1 ---> this listens to port 1111 on 192.168.1.1 and redirects connects to the original address, port 80.
ssh -L 192.168.1.1:1111:foo.bar:0 -N -n user@1.1.1.1 ---> this listens to port 1111 on 192.168.1.1 and redirects connects to for.bar with the original port.
ssh -L 192.168.1.1:1111:-:0 -N -n user@1.1.1.1 ---> this listens to port 1111 on 192.168.1.1 and redirects to original destination and original port
ssh -L 1111:-:80 -N -n user@1.1.1.1 ---> this listens to port 1111 and redirects connects to the original address, port 80.
ssh -L 1111:foo.bar:0 -N -n user@1.1.1.1 ---> this listens to port 1111 and redirects connects to for.bar with the original port.
ssh -L 1111:-:0 -N -n user@1.1.1.1 ---> this listens to port 1111 and redirects to original destination and original port

Of course you still need the same iptables rule, to make this magic work.

The dropbear ssh version from tomatousb build 54 does not know about binding on some address (thus the dumb env var bind patch). Another thing would be
that this will not work if we do not specify a ipv4 bind address (so ssh -L 1111:-:0 should not work, since default is to bind on IPV6 and the syscalls to get the
orig address do not work ).
I used the test for address instead of port because I had this patch also in openssh and there they do not allow destport 0.
Bill: the edited patch do not have the correct code to get the orig address:

you may wonder why we test for SOL_IP ? The reason is.. in linux we have getsockopt(fd, SOL_IP, SO_ORIGINAL_DST , while in freebsd/macosx we have getsockname
(combined with ipfw fwd instead of iptables). So basically this also works in freebsd/macosx (I do have a openssh package builded by a friend of mine for macosx ,
I could share it )

Little offtopic: Here is the patch against openssh client for the record(it should work also on earlier openssh versions.. with minors edits):

The dropbear ssh version from tomatousb build 54 does not know about binding on some address (thus the dumb env var bind patch).

Oh, that is bad, considering the dropbear help lists this option. We should probably fix that while we are at it.

> Another thing would be
that this will not work if we do not specify a ipv4 bind address (so ssh -L 1111:-:0 should not work, since default is to bind on IPV6 and the syscalls to get the
orig address do not work ).

That is a shame. So I guess there would need to be an option force it to do an IPV4 binding to make an any address redirect work…

Very nice. I'm doing the same on my router to watch hulu.com, but my solution is more convoluted: I use redsocks, which is a transparent SOCKS proxy redirector, together with ssh -D (which opens a socks proxy locally).