Skip to content
Go back

SSH keys and secure file copy

· Updated:
By SumGuy 6 min read
SSH keys and secure file copy

SSH is the backbone of working with remote Linux servers. You’re not using it right if you’re still typing passwords. Here’s the complete flow: generate a key, get it on the server, configure your client, and then move files securely.

Generating SSH Keys

You want ed25519 keys. They’re smaller, faster, and more secure than RSA. If your target server is ancient (pre-2014), fall back to RSA.

Ed25519 (modern servers — do this):

Generate ed25519 key
ssh-keygen -t ed25519 -C "you@laptop" -f ~/.ssh/id_ed25519

The -C flag is just a comment. The -f flag specifies where to save it. When prompted for a passphrase, use one — your key file itself is encrypted on disk.

RSA (legacy servers):

Generate RSA key
ssh-keygen -t rsa -b 4096 -C "you@laptop" -f ~/.ssh/id_rsa

The -b 4096 sets the key size to 4096 bits (stronger than the 2048 default, and still fast). Anything under 2048 is obsolete — don’t bother.

You now have two files: ~/.ssh/id_ed25519 (private key — never share) and ~/.ssh/id_ed25519.pub (public key — safe to distribute).

Getting Your Public Key to the Server

The easy way:

Copy public key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

ssh-copy-id handles all the fiddly details: it logs in (you’ll type your password one last time), appends your public key to ~/.ssh/authorized_keys on the server, and sets permissions correctly so SSH won’t complain.

If ssh-copy-id isn’t available (some Windows setups), do it manually:

Manual public key installation
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Now test passwordless login:

Test SSH access

No password prompt? You’re done with auth. Close the connection and move on.

Configuring ~/.ssh/config

Stop typing ssh -p 2222 [email protected]. Create ~/.ssh/config:

~/.ssh/config
Host homelab
HostName 192.168.1.100
User username
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host production
HostName prod.example.com
User deploy
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking accept-new

Now you just type ssh homelab. SSH uses the right user, port, and key automatically. You can add multiple hosts — each gets its own section.

Common options:

Copying Files with SCP

SCP (secure copy) works like cp, except it can reach across the network over SSH.

Remote to local:

Download a file
scp [email protected]:/var/log/app.log ~/Downloads/

Local to remote:

Upload a file
scp ~/myapp.jar [email protected]:/opt/apps/

Recursive (directories):

Copy a directory tree
scp -r ~/myconfig/ [email protected]:/etc/myapp/

The -r flag means “recursively copy everything inside.” No -r? SCP treats it as a file and fails.

Using a non-standard SSH port:

SCP with custom port
scp -P 2222 ~/file.txt [email protected]:/tmp/

Note: it’s -P (capital), not -p. (Confusingly, ssh uses lowercase -p for ports. Different tools, different conventions.)

Host-to-host (remote to remote):

Copy between two remote servers
scp [email protected]:/data/backup.tar.gz \

Copying multiple files:

Multiple files to remote
scp file1.txt file2.txt [email protected]:~/

Or use glob patterns:

Files matching a pattern
scp [email protected]:~/logs/*.gz ~/backups/

Quick Cheatsheet

TaskCommand
Generate ed25519 keyssh-keygen -t ed25519 -C "comment" -f ~/.ssh/id_ed25519
Copy public key to serverssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
SSH to a hostssh user@host (or ssh hostname if in ~/.ssh/config)
Download a filescp user@host:/path/file ~/local/
Upload a filescp ~/file user@host:/path/
Copy a directoryscp -r ~/dir/ user@host:/path/
Download on custom portscp -P 2222 user@host:/file ~/
Copy between remotesscp user1@host1:/file user2@host2:/path/

That’s it. Keys, config, and file transfers — the foundation of working with remote machines. Your 2 AM self will appreciate never having to type a password again.

Using ssh-agent So You Don’t Retype Your Passphrase All Day

You followed the advice earlier and set a passphrase on your key — good. But now every ssh or scp invocation prompts for it. That gets old fast. ssh-agent solves this by holding your decrypted key in memory for the duration of your session.

Start the agent and add your key:

Terminal window
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Enter your passphrase once. From that point on, every SSH operation in that terminal session goes through the agent — no more prompts. You can verify what keys are loaded with ssh-add -l.

On macOS the system already runs an agent, and you can persist the key across reboots with one extra flag:

Terminal window
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

This stores the passphrase in the macOS Keychain so the key reloads automatically after a restart.

On Linux with a desktop session, most distros integrate with gnome-keyring or kwallet which handles this transparently once you log in. Headless servers? Add this to your ~/.bashrc or ~/.zshrc:

~/.bashrc
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

The if guard prevents spawning a new agent process for every terminal you open — rookie mistake that leaves dozens of orphaned agent processes behind.

Common gotcha: if you cloned a repo or set up a server and SSH suddenly stops working after a reboot, the agent died with your session. Just run ssh-add again. Alternatively, look into keychain (the tool, not the macOS concept) — it persists a single agent across logins on Linux, which is exactly what you want on a dev box you log into repeatedly.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
ss Is the New netstat (And It's Better)
Next Post
Reverse Proxy SSL: The Cert Chain Mistake Everyone Makes

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts