Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Question I would like to know how to tunnel requests made on a server (debian) to port 80 on my laptop using ssh tunneling.

Problem I can open up a tunnel with the following command that does not behave quite as I would like:

ssh -R 4445:localhost:80 sam@example.com

After running this and getting a shell at example.com, the following command executes as expected returning the web page being hosted on my laptop:

wget localhost:4445

However, when trying to run this same command using example.com:4445 rather than localhost:4445, I get a connection refused.

Extra info: I also tried writing a forwarding rule using shorewall:

DNAT            net             $FW:127.0.0.1:4445        tcp     4446

and then tried

wget example.com:4446

When wget fails in any of the above cases, I get this:

--2011-02-16 13:48:26--  http://example.com:4446/
Resolving example.com... 70.90.XXX.XX
Connecting to example.com|70.90.XXX.XX|:4446... failed: Connection refused.

Any ideas on where to go from here? Also, if there is different / better way to achieve this effect I am completely open to the idea.

EDIT Thanks for the suggestions! Tried the following:

ssh -R example.com:4445:localhost:80 sam@example.com

and

ssh -R :4445:localhost:80 sam@example.com

Then when running the same wget as above came back with the same error. I should maybe mention that this server has two interfaces (eth0 public eth1 private).

EDIT

I am a moron :( Had to set

GatewayPorts yes

in sshd_config. Thanks for the help everyone!

share|improve this question
add comment

3 Answers 3

up vote 2 down vote accepted

ssh is configured for security reasons to make the new tunnels to listen on localhost. You have to use:

ssh -R :4445:localhost:80 sam@example.com

From the man page of openssh:

 -R [bind_address:]port:host:hostport

Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine.

Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square braces or using an alternative syntax: [bind_address/]host/port/hostport.

By default, the listening socket on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server’s GatewayPorts option is enabled (see sshd_config(5)).

share|improve this answer
    
yea for man pages slapping myself in the head! However, for some reason this still did not work. Is there some log files I could be checking or something to get some more info? Actually still need to set the GatewayPorts option in sshd_config, I'll get back after I do this. –  Hersheezy Feb 16 '11 at 19:56
add comment

The first thing to keep in mind is that tunnels have a specific end point. That end point doesn't have to be the client or the server, but the data is only encrypted while it's between the client and the server.

If you want a connection on the server to tunnel to example.com, you could run

 ssh -R 4445:example.com:80 sam@example.com

When anyone on the server connects to localhost:4445 the packet will tunnel encrypted to your client. From your client, the packet will travel unencrypted to example.com:80. SSH does not perform any analysis of your connection protocol, the packets simply go in one end and come out the other.

One tunnel can only go to one endpoint. If you want to go somewhere else (say, example.org), you'll need to close the ssh connection and make a new one with -R 4445:example.org:80. If you want to connect to both example.com and example.org, you'd need to set up two different tunnels with different local ports: -R 4445:example.com:80 -R 4446:example.com:80.

By (very good) default, tunnels can only "come from" one place (the server's localhost for -R tunnels, the client's localhost for -L tunnels). For -R tunnels, if you enable GatewayPorts in the server's sshd_config file, then you can tell it to listen on the server's IP address for anyone who can connect to the server:

ssh -R server:4445:example.com:80 ...

Then, anyone who can reach server:4445 would have their packet travel unencrypted to the server, the server would tunnel it encrypted to the client, then the client would send it unencrypted to example.com:80.

share|improve this answer
add comment

Problem is you are trying to open port on example.com:4445 which is not really opened.

If you want to hit tunneled port 4445 on localhost when referencing example.com in wget command or in browser you will need to add entry to /etc/hosts file

127.0.0.1 example.com

which will then enable you to hit tunneled port on localhost when executing

wget example.com:4445

Other thing useful here to establish tunnel is, if you intend to use it on regular basis is to setup .ssh/config file and make block like this.

Host example Hostname example.com User someuser LocalForward 4445 localhost:80

This will tunnel port 80 from example.com to localhost:4445 simply by invoking "ssh example"

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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