10

I am trying to forward web traffic from a remote server to my local machine in order to test out some API integration (tropo, paypal, etc). Basically, I'm trying to setup something similar to what tunnlr.com provides.

I've initiated the ssh tunnel with the command

$ssh –nNT –R :7777:localhost:5000 user@server

Then I can see that server is now listening on port 7777 with

user@server:$netstat -ant | grep 7777

tcp        0      0 127.0.0.1:7777          0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:7777                :::*                    LISTEN  


$user@server:curl localhost:7777
Hello from local machine

So that works fine. The curl request is actually served from the local machine.

Now, how do I enable server.com:8888 to be routed through that tunnel?

I've tried using nginx like so:

upstream tunnel {
    server 0.0.0.0:7777;
}
server {
  listen 8888;
  server_name server.com;
  location / {
    access_log /var/log/nginx/tunnel-access.log;
    error_log /var/log/nginx/tunnel-error.log;
    proxy_pass http://tunnel;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect off;
  }
}

From the nginx error log I see:

[error] 11389#0: *1 connect() failed (111: Connection refused)

I've been looking at trying to use iptables, but haven't made any progress. iptables seems like a more elegant solution than running nginx just for tunneling. Any help is greatly appreciated. Thanks!

EDIT (adding server info)

Server details: Ubuntu 10.10 maverick (standard install)

EDIT (nginx option)

The nginx options worked by changed 0.0.0.0:7777 to 127.0.0.1:7777 as @Marcel G suggested. Still looking for non-nginx solution though.

EDIT (update on final solution)

As @sciurus pointed out, make sure that GatewayPorts yes in your sshd_config file. I initially had this line in the config file, but I needed to issue a /etc/init.d/ssh reload instead of restart (at least it seems that way on ubuntu).

Final command used on the local machine: ssh -nNT -R '*:8888:localhost:5000' user@server

Then the server should indicate it is listening on *:8888 with lsof -i tcp:888

user@server:~$ sudo lsof -i tcp:8888
COMMAND   PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd    14711 user    8u  IPv4 1791013      0t0  TCP *:8888 (LISTEN)
sshd    14711 user    9u  IPv6 1791014      0t0  TCP *:8888 (LISTEN)
chris
  • 103
  • 1
  • 1
  • 5

2 Answers2

10

There is no need to use nginx.

In your ssh daemon configuration (it should be /etc/ssh/sshd_config) set GatewayPorts to clientspecified and reload it. This is necessary for other systems to be able to connect to your tunnel. Without it, only programs running on your server will be able to use it.

Now all you need to do is modify your ssh command to listen on port 8888 instead of port 7777. This could look like

ssh -nNT -R '*:8888:localhost:5000' user@server

The asterisk tells sshd to listen to port 8888 on all interfaces, rather than just the loopback interface. This would fail if you haven't changed GatewayPorts.

sciurus
  • 12,493
  • 2
  • 30
  • 49
  • Ok, I switched to your suggestion and when I `curl http://server.com:8888`, I get the error `curl: (7) couldn't connect to host`. I can still curl localhost:8888 from server's shell and it hits the local machine. – chris Mar 08 '11 at 02:49
  • btw, I stopped nginx before trying the new command you provided. – chris Mar 08 '11 at 03:04
  • @chris is GatewayPorts enabled in your server's sshd_config? If not, enable it. After starting the tunnel, make sure ssh is listening on more than just the loopback address; you can replace netstat and grep with `lsof -i tcp:8888`. – sciurus Mar 08 '11 at 06:20
  • Awesome! So I had `GatewayPorts yes` in sshd_config and I think I only did a /etc/init.d/ssh restart, but this time I did `reload`. I'm not sure what the difference is, but now it totally works!! Thanks a million @sciurus. – chris Mar 08 '11 at 15:30
1

I second sciurus' answer but if for some reason you need to use nginx... my guess is that your upstream definition is broken.

The way you create your ssh reverse tunnel it only listens on localhost (127.0.0.1 and ::1), so you might want to try to give the following upstream definition a go:

upstream tunnel {
    server 127.0.0.1:7777;
}

Just for the record: I've never configured nginx my self yet so this is just a guess.

Marcel G
  • 2,149
  • 14
  • 24
  • Thanks! This actually made it work. If possible I'd still prefer not use nginx just to get tunneling working, but good to know that it is possible – chris Mar 08 '11 at 02:51