Module 2 · 2.3
English
Using SSH smartly
Module 2: SSH and keys · Reading time: 10 minutes
Learning objective: After this lesson you can use SSH smoothly every day with your own configuration file, copy files with scp and rsync, and reach a database through a tunnel without opening the database port to the internet.
Key concepts: ~/.ssh/config, Host, HostName, User, IdentityFile, scp, rsync, sftp, port forwarding, -L, tunnel, ProxyJump, ServerAliveInterval, different port number, revoking a key
Less typing with ~/.ssh/config
After a few weeks you will be typing this dozens of times a day:
anna@laptop:~$ ssh -i ~/.ssh/id_ed25519 anna@192.0.2.10With a configuration file for the client this gets shorter and you make fewer mistakes. The file lives on your own computer: ~/.ssh/config (Windows: C:\Users\anna\.ssh\config, without an extension).
Host web1
HostName 192.0.2.10
User anna
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
Host test
HostName test.example.com
User anna
Port 2222Now it is simply:
anna@laptop:~$ ssh web1
anna@web1:~$What do the lines do?
- Host is the nickname you choose yourself. You type it after
ssh,scpandrsync. - HostName is the real address: an IP address or a name that is in the DNS.
- User and Port are the username and the port, so you no longer have to remember them.
- IdentityFile points to the key. Handy if you have several keys; without this line ssh tries your default keys.
- ServerAliveInterval 60 sends a small sign of life every 60 seconds. Many home routers and wifi networks drop a quiet connection after a few minutes; this keeps your session open.
Here too the first value wins, just as on the server. So put general rules such as Host * at the bottom of the file.
Copying files: scp, rsync and sftp
scp copies a file, in the same form as cp, but with host: in front:
anna@laptop:~$ scp backup.sql web1:/home/anna/
anna@laptop:~$ scp web1:/var/log/nginx/error.log .rsync is smarter with folders and large amounts of data: it only sends what has changed, and it can resume an interrupted copy. It must be installed on both sides (apt install rsync).
anna@laptop:~$ rsync -avz --progress ./site/ web1:/var/www/example.com/Watch the slash after ./site/: with a slash rsync copies the contents of the folder, without a slash the folder itself (you then get /var/www/example.com/site/). If in doubt, try with --dry-run first, and be very careful with --delete, which removes everything on the receiving side that does not exist on your side.
sftp and graphical programs such as FileZilla or WinSCP use the same SSH connection and the same key. So you do not need a separate FTP server. An old-fashioned FTP server on a VPS is not recommended: plain FTP sends your password over the network unencrypted.
A tunnel instead of an open port
This may be the most useful thing SSH can do. Say a PostgreSQL database runs on your server. You want to reach it from your laptop with a graphical program. It is very tempting to open port 5432 to the internet. Don't: open database ports are one of the biggest causes of data breaches (lesson 10.2), and later in the course we check from outside that they are closed (exercise Z5.1).
With local port forwarding you let SSH build a tunnel:
anna@laptop:~$ ssh -L 5432:127.0.0.1:5432 web1Read that as: "listen on my laptop on port 5432, and send everything that comes in there through the SSH connection to 127.0.0.1:5432, as seen from the server". As long as this session is open, you connect your database program to localhost port 5432 on your own laptop, and you end up at the database on the server.
What makes this so good?
- The database only listens on
127.0.0.1on the server and cannot be reached from outside. - The connection is encrypted by SSH, even if the database itself has no encryption.
- Only people who can log in with SSH can get to it. So you use the strong security you already have.
If something on your laptop already uses 5432, pick a different number on the left: -L 15432:127.0.0.1:5432, and connect to port 15432. If you put the tunnel in ~/.ssh/config, you always have it at hand:
Host web1-db
HostName 192.0.2.10
User anna
LocalForward 15432 127.0.0.1:5432With ssh -N web1-db you only get the tunnel, without a command line.
Through an intermediate server: ProxyJump
Sometimes you can only reach a server through another one, for example a database server without a public IP address behind your web server. ProxyJump jumps through the first server on to the second:
Host db1
HostName 10.0.0.5
User anna
ProxyJump web1The difference with agent forwarding (lesson 2.1): with ProxyJump the encryption runs end to end between your laptop and db1. The intermediate server only passes the packets along and cannot use your key.
A different port number: yes or no?
Many guides advise moving SSH to a different port, for example 2222. What does that really do?
- It reduces the noise: most automated guessing attempts only try port 22. Your log gets quieter.
- It is not security. A scanner that tries all ports finds SSH within seconds by its version banner.
With keys and password login switched off (lesson 2.2), the port makes little difference to security. If you still want to change it, do it in the right order: open the new port in the firewall, let SSH listen on both ports, test in a second window, and only then close the old port. On Ubuntu 24.04 and later this also involves systemctl daemon-reload and systemctl restart ssh.socket (lesson 2.2). Don't forget that your provider may have a firewall too.
Revoking access
A former colleague or a web developer had a key on your server and no longer works for you? Revoking access is easy, as long as you keep track:
- Look at all keys:
ssh-keygen -lf ~/.ssh/authorized_keys, and do this for every user (including/root/.ssh/authorized_keys). - Remove that person's line.
- If they used their own user account, lock it (lesson 3.1) and check whether they were in the
sudogroup (lesson 3.2). - If they have seen passwords, such as a database password in a configuration file, replace those too.
An ordinary key has no expiry date. What you do not remove keeps working, even years later. If you give someone temporary access, you can put the option expiry-time="20261231" in front of their line in authorized_keys; after that date the server refuses the key.
Summary
~/.ssh/configon your own computer stores the name, user, port and key for each server;Host *belongs at the bottom.- scp for single files, rsync for folders (watch the slash and
--delete), sftp instead of FTP. - With
ssh -Lyou reach a database through an encrypted tunnel, while the database port stays closed from outside. - ProxyJump jumps safely through an intermediate server; better than agent forwarding.
- A different port number reduces noise, but does not secure anything. Keys you do not remove keep working.
Quiz
Exercise
Exercise O2.3: An SSH config and a tunnel. On your own computer, create a ~/.ssh/config with a nickname for your server, log in with just ssh <bijnaam>, copy a file with scp or rsync, and build a tunnel with -L to a service that only listens on 127.0.0.1 on your server (if you don't have a database yet, use port 22 of the server itself: ssh -L 2200:127.0.0.1:22 <bijnaam> and then ssh -p 2200 anna@localhost). Answer the questions about what the tunnel does and why the port does not need to be open.
Exercise O2.3: An SSH config and a tunnel
You do this exercise yourself; no one checks it. Tick off what you've done and mark the exercise as done.
Your laptop listens on the left-hand port, the traffic travels encrypted through SSH and comes out on the server at 127.0.0.1:<poort>. The service stays unreachable from outside. A different SSH port means less noise in your log, but it is not security; keys and turning off password login are.
Your ticks and notes only stay in this browser; we don't send them anywhere. If you're signed in, we only save in My courses that you've done the exercise.
Further reading
The steps in these articles apply to WebOké's VPSs and panels; with other providers it works in a similar way.
- Logging in to your VPS with SSH (and creating an SSH key)
- ssh_config manual (client settings): https://man.openbsd.org/ssh_config
- ssh manual (options
-L,-J,-N): https://man.openbsd.org/ssh
