>_ Operating systems & Linux

SSH on the client side: keys, config file, scp and rsync

Everyday SSH without hassle: ed25519 keys, ssh-agent, the ~/.ssh/config file with server aliases, copying files with scp and syncing with rsync.

SSH is the standard way to work on a remote computer from the terminal, used both to administer servers and to push code to a repository. Many people, though, use it in the most laborious way: an IP address to remember, a password typed every time, files copied with graphical tools. With keys, a well-written configuration file and two commands for transfers, daily work becomes quicker and safer too. Here I deal with the client side, the computer you connect from.

Keys: how they work

A key pair consists of a private key, which stays on your computer and must never be shared, and a public key, which you copy to the servers you want to access. When you connect, the server poses a challenge that only the holder of the private key can solve. No password travels over the network, and an attack based on trying different passwords becomes useless.

To generate a modern pair:

ssh-keygen -t ed25519 -C "anna-laptop"

The ed25519 type produces short, fast and robust keys. The comment only serves to recognise the key once you have several. The program asks for a passphrase: set one, because it protects the private key if the computer is stolen or the disk copied. The files are saved as ~/.ssh/id_ed25519, the private key, and ~/.ssh/id_ed25519.pub, the public one.

Copying the key to the server

The simplest way:

ssh-copy-id user@server.example.com

The command asks for the password one last time and adds the public key to the ~/.ssh/authorized_keys file on the server. From the next connection onwards, login uses the key. Many server providers' control panels also let you paste the public key when the machine is created.

ssh-agent: the passphrase only once

Typing the passphrase at every connection is tedious. The ssh-agent keeps the key unlocked in memory for the length of the session:

ssh-add ~/.ssh/id_ed25519
ssh-add -l

On the most common Linux desktops and on macOS the agent is already running and tied to the system keyring. On macOS, with the UseKeychain yes option in the configuration file, the passphrase is stored in the Keychain.

The ~/.ssh/config file

This is the tool that saves the most time. Each block defines an alias with its own settings:

Host production
    HostName 203.0.113.10
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Host backup
    HostName backup.example.com
    User anna
    ProxyJump production

Host *
    ServerAliveInterval 60
    AddKeysToAgent yes

With this configuration, ssh production replaces ssh -p 2222 -i ~/.ssh/id_ed25519 deploy@203.0.113.10. The second block shows ProxyJump: to reach a server not exposed to the internet, you pass through another one, transparently. The Host * block applies to every connection: ServerAliveInterval sends a periodic signal and stops an idle connection from being dropped by a router.

Aliases also work with scp, rsync and Git, which use SSH under the hood. The file must be readable only by you: chmod 600 ~/.ssh/config.

The first connection and the server fingerprint

On the first connection SSH shows the fingerprint of the server's key and asks for confirmation. Once accepted, it is saved in ~/.ssh/known_hosts. If one day a warning appears saying the server's identification has changed, don't ignore it: it may be a legitimate reinstallation, but it may also be an interception. Before removing the old entry with ssh-keygen -R hostname, check the fingerprint with whoever manages the server.

Copying files with scp

For one-off transfers scp uses the same syntax as cp, with the server written as alias:path:

scp report.pdf production:/home/deploy/
scp production:/var/log/nginx/error.log .
scp -r folder/ production:/srv/

Syncing with rsync

When there are many files, or the transfer has to be repeated, rsync is clearly superior: it compares source and destination and copies only what has changed.

rsync -avz --progress site/ production:/var/www/site/

The options: -a preserves permissions, dates and links; -v shows details; -z compresses during transfer. Two habits avoid the most common mistakes:

  • the trailing slash on the source matters: site/ copies the folder's contents, site copies the folder itself into the destination;
  • --delete removes from the destination any files no longer present in the source, and it is as powerful as it is dangerous. Before using it, a trial run with -n (--dry-run) shows what would happen without touching anything.

In my work, rsync -avn --delete followed by a careful read of the list is a fixed step before every sync to a production server.

Good habits

  • One key per device, so if you lose a laptop you revoke only that one.
  • Always set a passphrase on private keys.
  • Correct permissions: chmod 700 ~/.ssh and chmod 600 on private files, otherwise SSH may refuse to use them.
  • Remove keys that are no longer needed from authorized_keys.

In short

  • ed25519 keys with a passphrase replace passwords and resist automated guessing.
  • ssh-copy-id installs the key on the server; ssh-agent saves you retyping the passphrase.
  • ~/.ssh/config turns addresses, ports and users into short aliases, ProxyJump included.
  • scp for one-off copies, rsync for repeated or large transfers.
  • Before rsync --delete, always do a --dry-run first.
MM
Marco Marzaduri

Marco Marzaduri works in cybersecurity, digital forensics and web development. With degrees in computer science and psychology, he combines technical analysis with an understanding of the human factor.

Read also