SSH and File Transfer: ssh, scp, rsync

K
Kai··5 min read

Every skill from the earlier articles applies on a server — and the way you get into that server is SSH. This is the most foundational DevOps skill: nearly every operation on a remote machine begins with an SSH session. This article teaches SSH with key authentication (the right way), and file transfer with scp/rsync.

What SSH is

SSH (Secure Shell) gives you a shell on another machine, over an encrypted connection. You type commands on your machine, and they run on the remote server.

ssh user@host
ssh ubuntu@203.0.113.10        # connect to the server at that IP as user ubuntu
ssh -p 2222 user@host          # -p if SSH runs on a different port (default 22)

The first time you connect to a host, SSH asks you to confirm the server's "fingerprint" (type yes) — this is an anti-spoofing mechanism: it remembers the server and warns you next time if the fingerprint changes.

Two ways to authenticate: password and key

SSH allows logging in by password or by a key pair. Keys are both safer and more convenient, and are the standard for servers.

A key pair consists of:

  • Private key — kept secret on your machine, never shared.
  • Public key — placed on the server. Can be shared freely.
   Your machine (client)               Server
   ┌─────────────────┐                 ┌──────────────────────┐
   │ private key      │ ──── ssh ────►  │ ~/.ssh/authorized_keys│
   │ (~/.ssh/id_...)  │  proves         │  (holds public key)   │
   └─────────────────┘  ownership of    └──────────────────────┘
        → you're in, NO password needed

How it works: the server issues a challenge, the client uses the private key to prove it owns the key matching the stored public key — no password is sent over the network.

Setting up keys in practice

Step 1 — create a key pair on your machine (only once):

ssh-keygen -t ed25519
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...  ban@may

This creates two files in ~/.ssh/: id_ed25519 (private — keep secret) and id_ed25519.pub (public). (ed25519 is a modern key type, compact and strong; rsa is the older type, still usable.) When prompted for a passphrase, you can add an extra password layer protecting the key file itself.

Step 2 — get the public key onto the server. The easiest way:

ssh-copy-id user@host

This command copies the public key into ~/.ssh/authorized_keys on the server. (Manually, you'd add the public-key line to that file yourself.)

Step 3 — from then on, log in with no password:

ssh user@host        # straight in, using the key

The permissions on the ~/.ssh directory matter a lot (recall Article 7): SSH refuses the key if permissions are too loose. You need ~/.ssh to be 700, and ~/.ssh/authorized_keys and the private key file to be 600. The "Permissions are too open" error on a private key is because you forgot chmod 600.

The config file: less typing

Typing ssh -p 2222 ubuntu@203.0.113.10 -i ~/.ssh/work_key every time is tedious. Create ~/.ssh/config:

Host myserver
    HostName 203.0.113.10
    User ubuntu
    Port 2222
    IdentityFile ~/.ssh/work_key

Now all you need is:

ssh myserver

Add multiple Host blocks for multiple servers — this is how DevOps folks keep many machines manageable.

scp: copy files over SSH

scp (secure copy) copies files between your local machine and a server, over the SSH connection:

scp file.txt user@host:/path/to/        # local -> server
scp user@host:/path/to/file.txt ./       # server -> local
scp -r dir/ user@host:/path/             # -r for whole directories

The destination syntax is user@host:path. scp is simple, good for copying a few files.

rsync: smart syncing

For syncing directories (deploy, backup), rsync is better than scp because it transfers only the changes — next time it sends only the new/different files, not everything again:

rsync -av dir/ user@host:/path/          # sync a directory up to the server
rsync -av user@host:/path/ ./backup/     # pull it down
rsync -av --delete src/ user@host:/path/ # --delete: remove at the destination what's no longer in the source
  • -a (archive) preserves permissions, timestamps, symlinks...; -v verbose.
  • --delete makes the destination an exact copy of the source (careful: it deletes).
  • The trailing / on the source matters: src/ syncs the contents of src; src (no /) syncs the whole directory src into the destination.

rsync runs over SSH out of the box, but it needs rsync installed on both ends (client and server). It's the standard tool for deploying source code and incremental backups.

When to use which: scp for a few one-off files; rsync for syncing a directory repeatedly (much faster from the second time on, since it only sends the diff).

A security note on the SSH server

When you administer a server (not just connect to it), a few standard practices:

  • Disable password login, allow keys only (in /etc/ssh/sshd_config: PasswordAuthentication no) — blocks password guessing.
  • Disable direct root login (PermitRootLogin no) — log in as a regular user then sudo (Article 12).
  • Consider changing the SSH port or using fail2ban to reduce automated scanning.

🧹 Cleanup

For the hands-on part (if you stood up two containers to test ssh between them), delete the containers + network. Keep the SSH key pair on your machine to reuse.

Wrap-up

SSH gives you a shell on a remote server over an encrypted connection. Use key authentication (safer and more convenient than passwords): ssh-keygen creates a key pair, the public key goes on the server (~/.ssh/authorized_keys, via ssh-copy-id), the private key stays secret with 600 permissions. ~/.ssh/config keeps multiple servers tidy. Transfer files with scp (single files) or rsync (directory sync, sends only the diff — the standard for deploy/backup).

You can now get into a server and do anything on it. Article 15 covers managing the background services running there: systemd — start/stop services, auto-start them, and view logs.