Skip to main content

First SSH login and hardening an Ubuntu server

A new server with a public IP is targeted within minutes by bots that try weak passwords over SSH. In this tutorial you log in over SSH for the first time and do the basics every Linux server should have: a separate user with sudo, key-only login, no root login, automatic security updates, and automatic blocking of attacking IPs with fail2ban.

It is written for Arianet cloud servers and VPS running Ubuntu 24.04, and also works on Ubuntu 22.04; differences are called out.

Prerequisites​

  • A server with Ubuntu 24.04 and a public IP
  • An SSH key on your own computer, ideally added to the panel before creating the server (SSH keys and API tokens)
  • If you created the server with a password, the root password shown at creation
caution

Until you finish this tutorial, keep one SSH session open. Test every SSH change from a second terminal first. If you lock yourself out, use the panel console (Console on a cloud server, VNC console on a VPS).

1. Create an SSH key on your computer​

If you have no key, create one in a macOS or Linux terminal or in Windows PowerShell:

ssh-keygen -t ed25519 -C "my-laptop"
cat ~/.ssh/id_ed25519.pub

The cat output is the public key. Add it in the panel under Account settings → SSH keys so you can pick it when creating a server. Never paste the private key (~/.ssh/id_ed25519) anywhere.

If you created the server with a password, copy your key to it like this (the root password is asked once):

ssh-copy-id root@SERVER_IP

2. First login​

ssh root@SERVER_IP

The first time you see The authenticity of host ... can't be established and the server's key fingerprint. Type yes; the fingerprint is then stored in ~/.ssh/known_hosts.

tip

On a cloud server page, the Details tab shows a ready-made SSH command with the server's IP.

3. Update the system​

apt update && apt full-upgrade -y

If /var/run/reboot-required exists, the kernel or an important library was updated and the server needs one reboot:

[ -f /var/run/reboot-required ] && reboot

4. Create a sudo user​

Working as root every day is risky. Create a separate user (use any name instead of deploy):

adduser deploy
usermod -aG sudo deploy

adduser asks for a password. Choose a strong one: SSH will not accept it, but sudo and the panel console need it.

Give the new user the SSH key root logged in with:

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys

In a second terminal, log in and test sudo:

ssh deploy@SERVER_IP
sudo whoami

It should print root.

5. Disable root and password login​

Put your settings in a separate file under sshd_config.d. In OpenSSH the first value of an option wins, and files in that folder are read in alphabetical order; the 00- prefix makes your settings apply before files such as 50-cloud-init.conf (which may contain PasswordAuthentication yes).

sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
EOF

Check the configuration and restart SSH:

sudo sshd -t && sudo systemctl restart ssh
sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '

The output should be permitrootlogin no, passwordauthentication no and kbdinteractiveauthentication no. Now try from a new terminal:

ssh deploy@SERVER_IP       # should work
ssh root@SERVER_IP # should fail: Permission denied (publickey)
Changing the SSH port on Ubuntu 24.04

On Ubuntu 24.04 SSH is started by ssh.socket. If you change Port, after sudo sshd -t you also need sudo systemctl daemon-reload and sudo systemctl restart ssh.socket. On Ubuntu 22.04 sudo systemctl restart ssh is enough. Open the new port in the firewall before changing it. A different port adds little real security and only makes logs quieter; key-only login matters more.

6. Automatic security updates​

The unattended-upgrades package installs security patches automatically every day. It is usually preinstalled on standard Ubuntu images; make sure it is installed and enabled:

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Answer Yes. Check the result:

cat /etc/apt/apt.conf.d/20auto-upgrades
sudo unattended-upgrade --dry-run --debug 2>&1 | tail -n 5

20auto-upgrades must contain both APT::Periodic::Update-Package-Lists "1"; and APT::Periodic::Unattended-Upgrade "1";.

Some updates (such as the kernel) only take effect after a reboot. To let the server reboot itself at a quiet hour when needed:

sudo tee /etc/apt/apt.conf.d/52unattended-upgrades-local > /dev/null <<'EOF'
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
EOF

The time is in the server's time zone (setting the timezone).

7. Install fail2ban​

fail2ban reads the SSH logs and temporarily bans IPs with repeated failed logins.

sudo apt install -y fail2ban

Put your settings in jail.local (do not edit jail.conf; updates overwrite it). Replace 203.0.113.4 with your own static IP so you are never banned, or remove it:

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 203.0.113.4

[sshd]
enabled = true
EOF

sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

On Ubuntu 24.04 the fail2ban package reads logs from the systemd journal (backend = systemd) and bans with nftables by default; on Ubuntu 22.04 it reads /var/log/auth.log. The settings above work on both.

To unban an IP:

sudo fail2ban-client set sshd unbanip 198.51.100.7

Final check​

sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication) '
systemctl is-active fail2ban unattended-upgrades
sudo fail2ban-client status sshd
  • Login as deploy with your key works and root login is refused.
  • Both services are active.
  • fail2ban-client shows the sshd jail with the number of banned IPs.

Common errors​

ErrorCause and fix
Permission denied (publickey)The right key is not in the user's ~/.ssh/authorized_keys, or file permissions are too open. On the server: chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys. With several keys, pick one: ssh -i ~/.ssh/id_ed25519 deploy@SERVER_IP. Use ssh -v for details.
REMOTE HOST IDENTIFICATION HAS CHANGED!The server key changed after a reinstall, or the IP now belongs to another server. If you are sure it is your server: ssh-keygen -R SERVER_IP.
Connection timed outPort 22 is closed in the cloud firewall or ufw, or fail2ban banned your IP. Log in through the panel console and check.
Completely locked outLog in through the panel console as deploy with its password (or root and the root password) and fix /etc/ssh/sshd_config.d/00-hardening.conf. Without any password, use Rescue mode.

Next steps​

Create your server​

Arianet cloud servers are billed hourly, are created with your SSH key and are usually ready in under a minute. In the Arianet panel, go to Cloud server / Cloud Computing → New server («سرور ابری / Cloud Computing ← سرور جدید»), create your first server and run this tutorial on it.