Linux – Forward all traffic through an ssh tunnel

command-line-interfaceiptableslinuxsshtunneling

I hope someone can follow this and I'll explain as best I can.

I'm trying to forward all traffic from port 6999 on x.x.x.224, through an ssh tunnel, and onto port 7000 on x.x.x.218.

Here is some ASCII art:

|browser|-----|Squid on x.x.x.224|------|ssh tunnel|------<satellite link>-----|Squid on x.x.x.218|-----|www|
         3128                      6999                          7000                                80

When I remove the ssh tunnel, everything works fine.

The idea is to turn off encryption on the ssh tunnel (to save bandwidth) and turn on maximum compression (to save more bandwidth). This is because it's a satellite link.

Here's the ssh tunnel I've been using:

ssh -C -f -C -o CompressionLevel=9 -o Cipher=none eamorr@172.16.1.224 -L 7000:172.16.1.224:6999 -N

The trouble is, I don't know how to get data from Squid on x.x.x.224 into the ssh tunnel? Am I going about this the wrong way? Should I create an ssh tunnel on x.x.x.218? I use iptables to stop squid on x.x.x.224 from reading port 80, but to feed from port 6999 instead (i.e. via the ssh tunnel). Do I need another iptables rule?

Any comments greatly appreciated.

Many thanks in advance,


Regarding Eduardo Ivanec's question, here is a netstat -i any port 7000 -nn dump from x.x.x.218:

14:42:15.386462 IP 172.16.1.224.40006 > 172.16.1.218.7000: Flags [S], seq 2804513708, win 14600, options [mss 1460,sackOK,TS val 86702647 ecr 0,nop,wscale 4], length 0
14:42:15.386690 IP 172.16.1.218.7000 > 172.16.1.224.40006: Flags [R.], seq 0, ack 2804513709, win 0, length 0

Update 2:

When I run the second command, I get the following error in my browser:

ERROR
The requested URL could not be retrieved

The following error was encountered while trying to retrieve the URL: http://109.123.109.205/index.php

Zero Sized Reply

Squid did not receive any data for this request.

Your cache administrator is webmaster.


Generated Fri, 01 Jul 2011 16:06:06 GMT by remote-site (squid/2.7.STABLE9)

remote-site is 172.16.1.224

When I do a
tcpdump -i any port 7000 -nn

I get the following:

root@remote-site:~# tcpdump -i any port 7000 -nn  
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused
channel 2: open failed: connect failed: Connection refused 
channel 2: open failed: connect failed: Connection refused

Best Answer

If I understood you correctly there's something wrong with your tunnel definition. What you seem to be doing with your current command line is to forward traffic from port 7000 on the current host (I assume it's .224) to port 6999 on .224 itself.

Try this instead:

ssh -N -g -f -C -o CompressionLevel=9 -o Cipher=none eamorr@172.16.1.224 -L 6999:172.16.1.218:7000

Or, if 172.16.1.218:7000 is not directly reachable (I'm guessing it isn't, as you would probably connect to it directly otherwise) you probably mean to connect to 172.16.1.218 instead:

ssh -N -g -f -C -o CompressionLevel=9 -o Cipher=none eamorr@172.16.1.218 -L 6999:localhost:7000

The format for -L is <localport>:<remotehost>:<remoteport>. <remotehost> is relative to the destination host, so in this case localhost should work.

Note I added -g in case you want to use the tunnel from a machine different than .224 (I'm assuming you're running ssh on .224).