I've been trying to setup reverse SSH tunnelling from outside my network to home but I've beet getting no-where. My setup is all Apple: two Macs behind an Airport Extreme, one at x.x.x.20 listening on port 22 and the other at x.x.x.30 listening on 10,022. I've setup NAT on the AP to forward external ports 22 to the x.x.x.20 and 10,022 to x.x.x.30. I want the tunnel to run to x.x.x.20:10022.

I've been using this command from an apple device outside of my home network: ssh -v -f -N -R 22:localhost:10022 homeuser@myhomedoman.com as well as ssh -v -f -N -R 10022:localhost:22 homeuser@myhomedoman.com but either way, the logs on the x.x.x.20:22 listening machine show that the traffic goes to it and the x.x.x.30:10022 machine show no record in the secure.log file. I've even tried ssh -v -f -N -R 10022:localhost:10022 homeuser@myhomedoman.com and the traffic still hits the x.x.x.20:22 listening machine.

The strange thing is that when i run ssh -p 10022 homeuser@myhomedoman.com it connects to the x.x.x.30:10022 listening machine just fine. I've gone through every NAT rule in the Airport as well and there's only one rule covering port 10022 so it's not a NATing problem as far as the AP's configuration is concerned.

Either I'm doing something really wrong, there's a bug in Apple's implementation of reverse SSH tunnels or that the Airport is doing something funny with the traffic. Has anyone else had this problem or found a workaround?

The guide I'm running to get the reverse tunnel running is http://www.vdomck.org/2005/11/reversing-ssh-connection.html

Thanks in advance!

  • Update: On closer inspection, both methods are connecting to port 22 of my home router's public IP address as viewed by the machine attempting to make the connection. Even if I use ssh -v -f -N -R 10022:localhost:10022 ssh still opens a connection to port 22 :/
    – Scottmeup
    Feb 17 '13 at 12:20

To avoid confusion I'll call:

  • x.x.x.20 -> local1
  • x.x.x.30 -> local2
  • Apple device outside your home network -> remote1

You say:

I've setup NAT on the AP to forward external ports 22 to the x.x.x.20 and 10022 to x.x.x.30.

which I interpret like this:

                 ________                 +-----------------+         +-----------+
                /        \ -  port 22 ----|-----------------|------>  | local1:22 |                                  
+---------+    (          )               |                 |         +-----------+
| remote1 | -  ( Internet )               | Airport Express |                                     
+---------+    (          )               |                 |         +--------------+
                \________/ -  port 10022 -|-----------------|------>  | local2:10022 |  
                                          +-----------------+         +--------------+

That is, local2 is reachable on [public IP address of Airport Extreme]:10022.

However, the ssh commands you run in your question use the default SSH port (that is, 22/tcp), and connect to local1:22 (more exactly: they connect to [public IP address of Airport Extreme]:22, which forwards the connection to local1:22).

You must modify the ssh command you run on remote1 like this (notice option -p 10022):

remote1$ ssh -p 10022 -f -N -R 2222:localhost:22 [username at local2]@[public IP address of Airport Extreme]

-p 10022 tells ssh which port to connect to, while 2222:localhost:10022 tells ssh to allocate a socket on local2 to listen to port 2222 and forward any packet sent to that port to port 22 on remote1:

 +------------+                         +----------------------+
 |            |                         |                      |
 | remote1:xx | -- SSH (port 10022)-->  | local2:10022 (SSH)   |
 |            |                         |                      |
 | remote1:22 | <--- SSH tunnel ------  | local2:2222 (alloc'd |
 |            |                         |              by ssh) |
 +------------+                         +----------------------+

Now you can access remote1 from local2 as follows:

 local2$ ssh -p 2222 remoteuser@localhost

(You use -f in your command which sends ssh to the background. The sshd process that binds to port 2222 and runs on local2 will continue to execute even if you stop Remote Login in System Preferences:

enter image description here

To stop it, list it:

local2$ lsof -i | grep 2222
local2$ sshd   855 jaume   14u  IPv6 0x4857f   0t0  TCP localhost:2222 (LISTEN)

and kill it with kill <PID>:

local2$ kill 855

where PID is the second value in lsof's output line.)


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .