Thursday, February 25, 2010

SSH access to the computer at your office

There can be different ways to get connected to the computer at your office; most are grouped as VPN or VNC techniques; but they are quite a bloat when all you want to do is get connected to check how things are going up with that program you are running; under Windows you might get a crashed computer at the office, and that is bad thing if the program was running overnight.

You can use SSH alone to get connected from home, provided you have good knowledge of how SSH works (public key authentication and port forwarding), you have administrative access to the external computer and the router/modem, and your company firewall is not too restrictive. This post is about settings in which external computers cannot get connected to the computer at the office because the company firewall masquerades its IP address, or blocks external access to port 22 of the office computer. In these cases, the connection to the computer at the office needs a previously-set connection with port forwarding, as illustrated next:


The external computer must be configured to be visible from Internet. Configure it to have a static IP address and put it in the demilitarized zone (DMZ) of the router/modem, or at least as a virtual server. Refer to the router guide for instructions.

Let us use the name aaron for the external computer. For security, disable non-essential services (portmap, nfs, ftp) from aaron, and enable sshd so it accepts a reduced number of users (namely you and you alone); ensure strong passwords for these users, because Linux viruses are real; I have had the experience of being target of brute force attacks on my SSH servers all the time.
Insecurity in Linux comes from incompetent administrators. I definitely take measures to ensure the privacy and security of my computer, which is all open to Internet. For example,  besides the normal user account facorread, I created an unprivileged user account fabio, which will accept the incoming connection at aaron. The computer at the office will automatically try to connect to aaron as user fabio, so you need to set up public key authentication for this task. The following commands are what you need this set up, as user fabio:
fabio@aaron ~ $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fabio/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/facorread/none.id_rsa.
The key fingerprint is: cc:dd:ff:3d fabio@aaron
fabio@aaron ~ $
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
Save the public key in your USB memory stick:
fabio@aaron ~ $ cp .ssh/id_rsa.pub /media/usb1/fabio.pub
As root, improve security by disabling the shell for user fabio:
root@aaron ~ # usermod -s /sbin/nologin fabio
Configure aaron to listen at both the secure SSH port (22) and an insecure one (my favorite one is 11111), so you can test both connections from the office. In summary of all the above, add the following lines to your sshd_config file:
# Listening on two ports
Port 22

Port 11111
# Only allowed users
AllowUsers facorread fabio
# Restrictions for fabio
Match User fabio
    KbdInteractiveAuthentication no
    PasswordAuthentication no
When you restart your sshd service, you must notice the following when running netstat -tenpl as root:
tcp    127.0.0.1:22     0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:11111  0.0.0.0:*    LISTEN      sshd
After this, you can check that ports 22 and 11111 are open to the Internet using a port scanner.
It is advisable to register your home computer with a free DNS service so you and the office computer always know the IP address of aaron through a host name of the likes of aaron.dyndns.org.  Modern modems/routers can connect to these services and keep them up to date about the IP address of your home. My modem is quite old, so I have created a script which uses ez-ipupdate to keep reporting the IP address to the dyndns service. Please adapt it to your needs and the particular modem you use at home:
#!/bin/bash


# Ensure only one instance of this script
[[ $(pgrep -o tellip) != $BASHPID ]] && exit 0


unset oldAddress
while true; do
newAddress=`curl -s --user admin:modemPassword http://modem/wancfg.cmd | grep isolate the IP address as reported by the port scanner`
if ! netstat -ei | egrep --quiet "addr:static address of aaron "; then
    echo "No interface has the static address to act as server. Waiting 1 minute."
elif [[ ( -z "$newAddress" ) || ( "$newAddress" == 0.0.0.0 ) ]]; then
    echo Waiting one minute before getting a valid address
elif [[ ( $newAddress != $oldAddress ) ]]; then
    echo "${oldAddress} -> ${newAddress} $(date)" &&
    oldAddress="${newAddress}" &&
    echo "address=${newAddress}
host=aaron.dyndns.org The host name you chose at the dyndns website
service-type=dyndns
user=dyndnsUser:dyndnsPassword" | /usr/sbin/ez-ipupdate -c - 2>&1
fi
sleep 1m
done
Ensure this script runs at all times; you might add this script to the list of local scripts you computer runs when you turn it on. Also, set good power management schemes, save on your energy bill when you leave the computer running alone at home.
Back at the office computer (name ezra), you must test both ssh connections and the public key you copied above:
facorread@ezra ~ $ cp /media/usb1/fabio.pub .ssh/
facorread@ezra ~ $ ssh -p11111 -i .ssh/fabio.pub fabio@aaron.dyndns.org
The authenticity of host 'aaron.dyndns.org' can't be established.
RSA key fingerprint is f6:7b:b5:07:43.
Are you sure you want to continue connecting (yes/no)? yes
Last login: Thu Jun 12 08:24:25 COT 2007
This account is currently not available.
Connection to aaron.dyndns.org closed.
facorread@ezra ~ $ ssh -i .ssh/fabio.pub aaron.dyndns.org
The authenticity of host 'aaron.dyndns.org' can't be established.
RSA key fingerprint is f6:7b:b5:07:43.
Are you sure you want to continue connecting (yes/no)? yes
Last login: Thu Jun 12 08:24:25 COT 2007
This account is currently not available.
Connection to aaron.dyndns.org closed.
"This account is currently not available" is the expected answer from the computer at home, because of the hardened security on the fabio account. If you succeed in the first attempt, you can connect to home using the insecure port. If you succeed in the second attempt, you will be able to connect using the secure SSH port, so you should configure the SSH server at aaron to listen only to port 22 as intended.
Use the following script to tell the computer at the office to connect to the computer at home and forward local port 22 to remote port 2222. This script uses the resolveip utility of the mysql package. By the way, if you find a better tool, please tell me. Installing mysql to use resolveip is like buying a hammer to kill a flea.
#!/bin/bash


remotehost=aaron.dyndns.org


while true; do
    echo $(date) $(resolveip "${remotehost}" 2>&1 ) &&
   
# This line renews the home IP address at the known host list.
    sed -i "s/^${remotehost},[^ ]\\+/${remotehost},$(resolveip -s ${remotehost})/" .ssh/known_hosts 2>&1 &&
    ssh -i ~/.ssh/fabio.rsa -o "BatchMode yes" -R '*:2222:localhost:22' "fabio@${remotehost}" -N 2>&1
    sleep 1m
done
Also ensure this script runs at all times as the normal user facorread, even thought there might be a power outage at the company. Include it in the list of local scripts to run at startup (or as a startup cron job).
Go home and try to connect to the office through the forwarded port using the command:
facorread@aaron ~ $ ssh -p2222 localhost
This is the only command you will need from now on to connect to the computer at the office. Most of the time the connection is straightforward; sometimes you will get Connection refused notices, due to the IP address of aaron being changed and the automatic connection being renewed. Wait a minute and try again. For the impatient, the following command helps check whether the tunnel is open.
tcp    127.0.0.1:22     0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:2222   0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:11111  0.0.0.0:*    LISTEN      sshd
This set up takes time and some effort on your part; please comment on your success stories. I hope it is useful.
For convenience, I recommend using connection sharing and public key authentication for the normal user facorread as instructed in the SSH man page.