What is it? #
SSH is how you reach your server. The first connection is also the moment to verify you are talking to the right machine and to see what state it arrived in.
Providers vary: some give you root, some create a user with sudo. Either way, the first session should establish what is installed, what is listening, and whether anything needs immediate attention.
Setting up an SSH config entry straight away turns a long command into a short alias, which you will use hundreds of times.
The immediate priorities after connecting are covered in the next few lessons: a non-root user, key-only access, updates and a firewall.
Think of it like this #
The first visit to a newly rented property. You check the locks, find the fuse box, see what furniture was left behind, and make a note of what needs fixing before you move anything in.
Simple example #
A freshly created server. You connect, verify the host key fingerprint against what the provider displayed, survey the machine, and write an SSH config entry before doing anything else.
Code #
# First connection
ssh [email protected]
# The host key prompt appears once
# The authenticity of host '203.0.113.10' can't be established.
# ED25519 key fingerprint is SHA256:abc123...
# Are you sure you want to continue connecting (yes/no)?
#
# Compare this fingerprint with the one shown in your provider's console
# before typing yes. After this, it is stored in ~/.ssh/known_hosts and
# checked on every future connection.
# Survey the machine before changing anything
hostnamectl # OS, kernel, virtualisation
uptime # how long it has been running
nproc; free -h; df -h # resources
sudo ss -tulpn # what is already listening
systemctl list-units --type=service --state=running | head -20
sudo ufw status || echo "ufw not installed"
grep -E "^(PermitRootLogin|PasswordAuthentication)" /etc/ssh/sshd_config
sudo lastb | head # failed login attempts already?
# ~/.ssh/config on your machine — write this immediately
Host app-prod
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3
# Now: ssh app-prod
# scp release.tar.gz app-prod:/tmp/
# rsync -a ./dist/ app-prod:/srv/app/current/
# Keep long work alive across disconnections
sudo apt install tmux
tmux new -s setup
# Ctrl+b then d to detach; tmux attach -t setup to return
The order of the first hour
1. connect and verify the host key
2. survey: what is installed, what is listening, what is exposed
3. create a non-root user with sudo and your key → next lesson
4. disable root login and password authentication → ssh keys lesson
5. apply all pending updates → updates lesson
6. enable a default-deny firewall → firewall lesson
Only then install anything application-related.
How it works #
The host key prompt is a one-time trust decision. Comparing the fingerprint with the provider's console is the only moment you can verify it properly, and it is usually skipped. From then on, SSH checks it automatically and warns if it changes.
Surveying before changing gives you a baseline. Knowing what was listening on arrival makes it obvious later if something unexpected appears.
lastb on a brand-new public server frequently already shows failed login attempts. Automated scanners find new addresses within minutes, which is a useful reality check before deciding security can wait.
The SSH config entry is small and saves a great deal of typing. It also means scp and rsync use the same alias, so deployment commands stay short.
ServerAliveInterval prevents idle sessions being dropped by intermediate firewalls, which otherwise interrupts long operations.
Installing tmux early is worth it. Applying updates or running a migration inside tmux means a dropped connection does not interrupt the work — and an interrupted package upgrade can leave a system in an awkward state.
The ordered list is the sequence the next five lessons follow, and doing it in that order means the machine is never left in an easily compromised state.
Real-world use #
New servers are scanned within minutes of getting a public address. The window between creation and hardening is genuinely worth minimising, which is why cloud-init setup is valuable.
Teams keep SSH config entries for every environment, so ssh app-prod and ssh app-staging are unambiguous. It also reduces the chance of running a command on the wrong machine.
A bastion host with ProxyJump becomes the pattern once you have several servers, with only the bastion publicly reachable.
Running tmux for any operation longer than a minute becomes reflexive after the first time a migration is interrupted halfway.
If the host key warning ever appears for a server you did not rebuild, treat it seriously and verify with whoever manages the machine before proceeding.
Common mistakes #
- Accepting the host key without comparing the fingerprint.
- Installing application software before hardening the server.
- Typing full connection commands instead of writing an SSH config entry.
- Running updates or migrations outside tmux and losing them to a disconnect.
- Ignoring failed login attempts already present on a new machine.
Practice #
Connect to a new server, verify the host key fingerprint against the provider console, and record what is listening and which services are running. Write an SSH config entry, reconnect using the alias, and start a tmux session for the setup work that follows.