Tag Archives: ssh

Restricting SSH Access to rsync

Passphrase-less SSH keys allows one to automate remote tasks by not requiring user intervention to enter a passphrase to decrypt the key. While this is convenient, is posses a security risk as the plain key can be used by anyone who gets hold of it to access the remote server. To this end, the developers of SSH allowed to restrict via the .ssh/authorized_keys the commands that can be executed of specific keys. This works great for simple commands, but as using rsync requires executing remote commands withe different arguments on the remote end, depending on the invocation on the local machine, it gets quite complicated to properly restrict it via .ssh/authorized_keys.

Luckily, the developers of rsync foresaw this problem and wrote a script called rrsync (for restricted rsync) specifically to ease the restricting keys to be used only for rsync via .ssh/authorized_keys. If you have rsync installed, rrsync should have been distributed along side it. In Debian/Ubuntu machines it can be found under /usr/share/doc/rsync/scripts/rrsync.gz. If you can find it there, you can download the script directly from here. On the remote machine, copy the script, unpacking if needed, and make it executable:

user@remote:~$ gunzip /usr/share/doc/rsync/scripts/rrsync.gz -c > ~/bin/rrsync
user@remote:~$ chmod +x ~/bin/rrsync

On the local machine, create a new SSH key and leave the passphrase empty (this will allow you to automate the rsync via cron). Copy the public key to the remote server.

user@local:~$ ssh-keygen -f ~/.ssh/id_remote_backup -C "Automated remote backup"
user@local:~$ scp ~/.ssh/id_remote_backup.pub user@remote:~/

Once the public key is on the remote server edit ~/.ssh/authorized_keys and append the public key.

user@remote:~$ vim ~/.ssh/authorized_keys

(Vim tip: Use :r! cat id_remote_backup.pub to directly insert the contents of id_remote_backup.pub into a new line). Now prepend to the newly added line

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding

The command="..." restricts access of that public key by executing the given command and disallowing others. All the other no-* stuff further restrict what can be done with that particular public key. As the SSH daemon will not start the default shell when accessing the server using this public key, the $PATH environment variable will be pretty empty (similar to cron), hence you should specify the full path to the rrsync script. The two arguments to rrsync are -ro which restricts modifying the directory (drop it if you want to upload stuff to the remote directory) and the path to the directory you want to enable remote access to (in my example ~/backups/).

The result should look something like:

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAA...vp Automated remote backup

After saving the file, you should be able to rsync files from the remote server to the local machine, without being prompted to for a password.

user@local:~$ rsync -e "ssh -i $HOME/.ssh/id_remote_backup" -av user@remote: etc2/

To things are needed to be noted:

  1. You need to specify the passphrase-less key in the rsync command (the -e "ssh -i $HOME/.ssh/id_remote_backup" part).
  2. The remote directory is always relative to the directory given to rrsync in the ~/.ssh/authorized_keys file.

Securing Access to phpMyAdmin on Lighttpd via SSH

phpMyAdmin lets easily manage your MySQL databases, as such it also presents a security risk. Logging in to phpMyAdmin is done using a username and password for the database. Hence, if someone is able to either eavesdrop or guess by brute-force the username and password could wreak havoc of your server.

A possible solution to the eavesdropping problem, is to use SSL to secure the communication to the phpMyAdmin. However, SSL certificates don’t present any method to stop brute-forcing. To prevent brute-forcing attempts, you could limit access to your IP address. However, most of us don’t have static IPs at home. The solution I came up with, kinds of combines both approaches.

Instead of using SSL to encrypt the data sent, I’m using SSH and instead of limiting access to my IP address, I’ll limit access to the server’s IP address. How will it work? First we start by editing the phpMyAdmin configuration for lighttpd. This usually resides in /etc/lighttpd/conf-enabled/50-phpmyadmin.conf. At the top of the file you’ll find the following lines:

alias.url += (
        "/phpmyadmin" => "/usr/share/phpmyadmin",
)

These lines define the mapping to the phpmyadmin installation, without it the phpMyAdmin wouldn’t be accessible. We use lighttpd’s conditional configuration to limit who is able to use that mapping by changing the above lines to:

$HTTP["remoteip"] == "85.25.120.32" {
        alias.url += (
                "/phpmyadmin" => "/usr/share/phpmyadmin",
        )
}

This limit access to the phpMyAdmin only to clients whose IP is the server’s IP (of course you’ll need to change that IP to your server’s IP). This stops curtails any brute-forcing attempts, as only someone trying to access the phpMyAdmin from the server itself will succeed.

But how can we “impersonate” the server’s IP when we connect from home? The easiest solution would be to use to the SOCKS proxy provided by SSH.

ssh user@server.com -D 1080

This will setup a SOCKS proxy on port 1080 (locally) that will tunnel traffic through your server. The next step is to instruct your browser of OS to use that proxy (in Firefox it can be done via Preferences->Advanced->Network->Connection Settings, it can also be defined globally via Network Settings->Network Proxy under Gnome). This achieves both of our goals. We are now able to connect to the server while using its own IP and our connection to the server is encrypted using SSH.

This method can be used to secure all kinds of sensitive applications. We could have achieved the same thing by using a VPN, but it’s more hassle to setup compared to SSH which is available on any server.