FreedomBoxBlog

SSH access from the internet to my FreedomBox

Rob van der Hoeven
Sat Jul 02 2011

On my FreedomBox I want SSH access from the internet for the following reasons:

Using virtual machines complicates the use of SSH. Each virtual machine has its own IP address, and the FreedomBox only has one external IP address. There must be a way to connect this external address to one of the many internal addresses. Fortunately SSH is very flexible and it is possible to do this very elegantly.

Read this first.

This article is one in a series that describes the building of my FreedomBox. Not all information from the previous articles is repeated.

The method.

On my FreedomBox the external IP address is connected to a special virtual machine which I call the internet module. This internet module acts as a gateway to the host system and all the other virtual machines.

[client (A)] --> Internet --> [internet module (IM)] -->  n*[virtual machine (B)]

If you want a SSH connection from client A to a virtual machine B then you need two SSH connections. First you have to make a connection from A to an account on the internet module (IM). From this connection you can make a second connection from IM to B. Making connections this way is not transparent. Machine A does not know it's connected to machine B, machine B does not know it's connected to machine A. Because the machines are not connected directly some SSH commands do not behave normally, or may not work at all.

Fortunately there is an elegant way to let both machines think they have a direct connection. For this you have to use the ProxyCommand statement in the ~/.ssh/config configuration file. With this statement you can specify a shell command that makes the connection to the remote system. The SSH client then uses the resulting stdin/stdout of the command as a channel to the remote SSH server.

For a transparent connection the returned stdin/stdout must be connected to the SSH port of the target server. The tick to get this done involves the following steps. First make a connection to the gateway system. On the gateway system start a program that returns a connection to the target system. Return this connection to the client.

Enough theory, here's the ~/.ssh/config setting I use to connect to my freedomboxblog VM over the internet:

Host freedomboxblog
  ProxyCommand ssh -p 99999 -qax guest@freedomboxblog.nl nc -w 1 freedomboxblog.freedom.box 22

I use ssh to log-in on the guest account of my internet module. Then the netcat program is used to make a connection to the freedomboxblog VM. This connection is returned and used by the SSH client to connect to “host freedomboxblog”.

On the internet module I only allow RSA authentication for the guest account. This is not only the most secure way, but it also prevents the password pop-up. With RSA authentication it is not possible to log-in if you don't have the private key. Unfortunately many people still try to log in by brute force. To prevent these attacks I use a non-standard SSH port (see my firewall article).

The configuration.

Client side:

cd ~/.ssh

Edit the config file, add the following lines:

Host myhost
  ProxyCommand ssh -p 99999 -qax guest@mydomain.com nc -w 1 myhost.freedom.box 22

Create RSA authentication keys:

ssh-keygen

This command creates two keys with your username. The one ending with .pub is needed by the internet module on the FreedomBox.

scp yourusername.pub root@internet.freedom.box:~

The internet module.

ssh root@internet.freedom.box

Install netcat:

apt-get install netcat

Create a guest user:

useradd -m guest
cd /home/guest

Add your public key to the authorized users of this account:

mkdir .ssh
cd .ssh

cat /root/yourusername.pub >> authorized_keys

Edit /etc/ssh/sshd_config so it has the following settings:

PasswordAuthentication no
AllowUsers guest

Restart ssh:

/etc/init.d/ssh restart

Now you can only log-in using the guest account, and only if you have one of the private keys belonging to the public keys in /home/guest/.ssh/authorized_keys.

The next time you try:

ssh root@internet.freedom.box

you get:

Permission denied (publickey).

So in order to get root access you first have to log-in to the guest account and then use the su command.