Dev Notes

Various Cheat Sheets and Resources by David Egan/Carawebs.

Connect Local Backup Server to Remote Server


Linux, Sysadmin
David Egan

Passwordless access to a server will typically be required by a backup script, run by root on a client machine.

In our case we use a raspberry Pi connected to an external storage drive as an always-on local fileserver - this connects to a remote server via SSH and collects backup data. It is low power, cost-effective, secure and runs automatically.

A public-private key pair is required, with the public key added to the target server.

The client machine should be able to connect without a passphrase, but the scope of action on the target machine should be limited to read-only rsync.

Key Generation

If one doesn’t already exist, or you need a unique key for some reason, you can generate an RSA key with a specific name:

ssh-keygen -t rsa

# Outputs this:
Enter file in which to save the key (/home/david/.ssh/id_rsa):

Specify a filename if required. Enter the full path, e.g. /home/username/.ssh/local-fileserver

Comments in the Key File

It can be helpful to have a comment in the key file. When transferred to the target machine, the public key will be appended to the /home/username/.ssh/authorized_keys file. The comment will help distinguish the key.

If the client machine is compromised, it allows the relevant line to be easily removed from the server authorized_keys file. If no comment is added, the public key file has username@hostname appended to the key as a default comment.

To add a comment, just enter text at the end of the public key, separated from the key content by a space.

Specify the Correct Key

If you’re not using the default key file, create an entry in an SSH config file specifying the correct key file for the server that you’re going to connect to.

You may need to create the config file it it doesn’t exist. The following command will do this in any case, with the file being created when you save (ctrl + o in nano):

sudo nano /home/username/.ssh/config

# Enter the following and save
Host 192.168.1.XXX
    IdentityFile ~/.ssh/local-fileserver

Uploading the Key

This can be achieved easily using the ssh-copy-id command.

If no keyfile is specified, this command will copy all public keys from the /home/username/.ssh directory, which may not be what you intend.

The -i flag can be used to set the specific key file that should be transferred:

ssh-copy-id -i ~/.ssh/local-fileserver.pub username@192.168.1.XXX

Security

Using an SSH key without a passphrase makes it possible to automate remote tasks - a user-entered passphrase is not required for key decryption.

Automation of backup tasks is essential - if backup relies on human intervention, sooner or later it will fail. However, using SSH keys without a passphrase is a security risk - is someone had access to the local backup server, they would be easily able to access the remote server.

Realistically, this is a pretty low risk. The bad guy would have to break in to your office and know his way round a headless Linux box. We don’t get too many roving bands of rogue systems administrators in this neck of the woods, but just in case…

SSH allows restriction of the commands that can be executed by a specific set of keys. This is accomplished by editing the /home/username/.ssh/authorized_keys file on the target server.

A script called rrsync (which stands for restricted rsync) is provided with rsync specifically to ease the restricting keys to be used only for rsync via .ssh/authorized_keys.

On Ubuntu, the script is located here: /usr/share/doc/rsync/scripts/rrsync.gz. The script needs to be unzipped and installed under usr/local/bin:

# Copy the archive rrsync script to /usr/local/bin
sudo cp /usr/share/doc/rsync/scripts/rrsync.gz  /usr/local/bin/

# Unzip the script
sudo gzip -d   /usr/local/bin/rrsync.gz

# Give it correct permissions
sudo chmod 755 /usr/local/bin/rrsync

Once rrsync is in place, we can lock down access for our SSH key by amending the /home/backupuser/.ssh/authorized_keys file on the target server.

Open the public key for the backup user on the target server. This will constitute a single line of text:

sudo nano /home/backupuser/.ssh/authorized_keys

Prepend the key data with the following:

command="/usr/local/bin/rrsync -ro /home/path-to/backup/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding
  • The command="/usr/local/bin/rrsync ..." restricts access of that particular public key - only the given command can be executed
  • The ...-ro /home/path-to/backup/" gives read-only access to the specified directory
  • The no-* options further restrict what actions can be carried out with the public key.
  • Note that the full path is need to reference rrsync

If you try and SSH into the Production machine from the Backup server you should now see a message like this:

PTY allocation request failed on channel 0
/usr/local/bin/rrsync: Not invoked via sshd
Use 'command="/usr/local/bin/rrsync [-ro] SUBDIR"' in front of lines in /home/backupuser/.ssh/authorized_keys
Connection to 123.45.67.89 closed.

Your script however will be able to gain read-only access, which is good enough to pull-down backup files.

rsync Command rsync from the Client

Note: After the above amendment to the authorized_keys file, the final path from the Backup server’s point of view is now /

Sample rsync command from the local server:

rsync --log-file=$HOME/.rsyncd.log --progress -az -H -e "ssh -p 1234" backupuser@123.456.789.0:/ ~/backup-target-directory

This specifies:

  • -a: archive mode; equals -rlptgoD (no -H,-A,-X)
  • -z: Compress file data during the transfer
  • -H: Maintain hardlinks (important due to our incremental backup)
  • -e “ssh -p 1234”: connect via SSH on port 1234
  • See rsync man page

References

Ubuntu Manpage for ssh-copy-id


comments powered by Disqus