On this page
Use this order
Server hardening is not a race to disable everything. A safe sequence is: create a local key, copy it to the deploy user, prove a second session works, allow SSH in the firewall, enable the firewall, then change SSH policy. Keep the provider console and the original session open throughout.
Generate and copy an Ed25519 key
Run key generation on your own computer, not on the server. Ubuntu recommends Ed25519 as a strong default. Protect the private key with a passphrase and never upload it to the website or repository.
ssh-keygen -t ed25519 -C 'my-laptop'
ssh-copy-id deploy@203.0.113.10
ssh deploy@203.0.113.10If ssh-copy-id is unavailable, add only the .pub file contents to /home/deploy/.ssh/authorized_keys from the provider console. Never copy the private key. In the new session, run sudo whoami and leave it open.
Enable UFW without losing SSH
Ubuntu's UFW is initially disabled on many images. Add the SSH rule before enabling it. If your SSH service uses a custom port, allow that exact port instead of 22.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verboseThe final status should include the SSH service and TCP ports 80 and 443. Do not open database, development or application ports to the whole internet unless there is a documented need.
Tighten SSH only after verification
Use a file in /etc/ssh/sshd_config.d on current Ubuntu systems so the change is easy to identify. Check the effective configuration and syntax before reloading. Distribution defaults differ, so review the official OpenSSH guide for your version.
sudoedit /etc/ssh/sshd_config.d/99-aioos-hardening.conf
sudo sshd -t
sudo systemctl reload ssh
sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin|pubkeyauthentication'A beginner-friendly policy is PubkeyAuthentication yes, PasswordAuthentication no and PermitRootLogin no, but apply it only after the key-based deploy login and sudo have both succeeded. Test a third fresh connection before closing old sessions.
Automatic security updates
Install and enable unattended security updates if the image does not already provide them. Also schedule a regular manual review, because automatic security updates do not manage every application dependency or breaking upgrade.
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
systemctl status unattended-upgrades --no-pagerWhat I learned
The most dangerous command is often a correct command run in the wrong order. Disabling password login is sensible, but doing it before testing the key can turn a five-minute task into a recovery-console session. I now treat every access-control change as a migration: add the new route, verify it, and only then remove the old route.
Finish line
Open one entirely new terminal and confirm key login, sudo, UFW status and SSH logs. Keep your private key backed up securely. Next, choose and protect the domain name for the site.
Access and rollback checks before activation
The OpenSSH profile above applies only after checking that it matches the actual SSH port; custom ports require an explicitly verified rule. Allow ports 80/443 only when the service needs them. Preparing rules does not activate the firewall. Keep the original session, verify a second key-based login with sudo, confirm provider-console access and back up the original rules. Only then have an administrator activate UFW through the official Ubuntu procedure. Do not activate it without a proven recovery entry point. If locked out, restore the previous rules through the provider console rather than layering additional restrictions.
Next steps
Continue with the next useful task; you do not need to read everything at once.
- Back up and maintain →
- How Caddy Automatic HTTPS Works and How to Troubleshoot It →
- Help Baidu and Google Discover a New Website: A Practical SEO Checklist →
- How to Choose Your First Cloud Server →