How can I help someone (like granny) over SSH who is behind a NAT router?

For helping others quickly, SSH is very useful, especially combined with GNU Screen. It's common that users are behind a NAT router. Even if the user can configure the router, it takes some time to remember the password, find the right options, etc.

So, what is the easiest way to help others over SSH if they're behind a NAT router?

I currently tell people to open a terminal run the below command and pass me their IP from a site like http://ip.appspot.com/:

sudo apt-get install openssh-server ssh-import-id && ssh-import-id lekensteyn

Obviously, this is not going to work if they're behind a NAT router or have a personal firewall configured. So, is there something like:

sshd --accept-help-from lekensteyn

I'm not looking for alternatives like Teamviewer, just a shell like SSH. It should be open-source too.


Solution 1:

If your own computer can accept SSH connections, there is a way to use the technique that Pavlos G. linked to without an extra computer.

You first need an underprivileged* user that your friend will connect as:

sudo adduser reverse --shell /bin/false

Tell your friend to start the tunnel:

ssh -N -R 62222:localhost:22 reverse@lekensteyns-server

Then, on your own computer (lekensteyns-server), start the reverse connection:

ssh -p 62222 localhost

* I don't know enough about security to be able to advise on creating a suitably underprivileged user. That's probably something that should be covered in a separate question.

Solution 2:

Based on your specific needs, i would probably:

  1. Ask them to tell me the router's password
  2. Login and setup port-forwarding for port 22 only
  3. Connect through SSH (or SSH tunneling if you need extra ports opened) and get the job done.

I also forgot that you can try the reverse ssh tunnel, although this solution technically needs one more - middle - computer to work.

More info can be found here

Solution 3:

I just usually set up an IPv6 tunnel (from sixxs.net or he.net) if they don't already have IPv6 and then that way the computer has a static address and I don't have to mess with NAT. I also like to set up key based authentication (then they don't have to tell you their password).

Sixxs has their own client that you use. It works behind almost any NAT, and automatically updates when the IPv4 address changes. They have instructions on how to set it up and it is packaged for Ubuntu.

Hurricane Electric uses a tunnel where IPv6 packages are sent as the payload of a IPv4 packet. Unlike Sixxs, no TCP/UDP is used. This means that the NAT you are behind has to support forwarding PROTOCOL 41 (not port) and only one computer behind the NAT can use it. The software to use a tunnel like this is built into Ubuntu.

For HE, I use something like this in /etc/network/interfaces:

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
     endpoint 216.218.226.238
     address  2001:470:a29f::2
     netmask  64
     ttl 64
     up ip -6 route add default dev he-ipv6
     down ip -6 route del default dev he-ipv6

The other thing you need to do is update your tunnel endpoint. Since you do not know when the External IP changes, you will have to just try to update the endpoint every few minutes. You could use something like this and run it from cron:

#!/bin/sh
echo -n "Hurricane Electric Proto-41 tunnel endpoint update: "
#(C) 2010 Erik B. Andersen This script is licensed under the latest version of the
# AGPL published by the Free Software Foundation at http://www.gnu.org/licenses/ .
####Set these for each different site#########
pass="passwordhere"
user_id="a765b8e2f474667dcb56e08c5f1aa05b"
tunnel_id="97817"
####Past here doesn't need to be changed######
wget -4 "https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=AUTO&pass=$(echo -n "${pass}" | md5sum | grep -o -E "[0-9a-fA-F]{32}")&user_id=${user_id}&tunnel_id=${tunnel_id}" -O /dev/null -o /dev/null --no-check-certificate
echo " Done"