Initial server setup on Ubuntu 24.04 LTS
Harden a fresh Ubuntu 24.04 VPS in ten minutes. New user, SSH keys, firewall, automatic security updates.

A fresh VPS is a blank slate. Ten minutes of setup now saves hours of cleanup later. This guide gets a new Ubuntu 24.04 box production-ready with a non-root user, key-based SSH, a firewall, and unattended security updates.
Connect as root
Right after deployment, your VPS comes with a root password emailed to you. Use it once, then never again.
ssh root@your.vps.ip
Update the package index immediately. Ubuntu 24.04 ships with reasonably current packages, but you want the latest security patches.
apt update && apt upgrade -y
Create a sudo user
Operating as root is a habit that ends in tears. Create a regular user with sudo rights.
adduser deploy
usermod -aG sudo deploy
Pick a strong password. You'll rarely type it: SSH will use keys.
Copy your SSH key to the new user
Everything from here on assumes you have an SSH keypair on your laptop. If you don't, generate one now:
ssh-keygen -t ed25519
Accept the default path and confirm ~/.ssh/id_ed25519.pub exists before continuing. Then push your public key to the server:
ssh-copy-id deploy@your.vps.ip
If ssh-copy-id is not available, create the key directory on the server first, since adduser does not make one:
mkdir -p /home/deploy/.ssh
Then paste your ~/.ssh/id_ed25519.pub into /home/deploy/.ssh/authorized_keys on the server. Permissions matter:
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
Open a new terminal and confirm ssh deploy@your.vps.ip works without prompting for a password before you continue.
Lock down SSH
Fair warning before you touch anything: this step can lock you out. Once password auth is off, keys are your only way in over SSH. Keep your current session open, confirm in a second terminal that ssh deploy@your.vps.ip still works with your key, and remember that the GetVPS console gives you a recovery path via VNC if something goes wrong.
Create a new file, /etc/ssh/sshd_config.d/00-hardening.conf, for example with sudo nano /etc/ssh/sshd_config.d/00-hardening.conf, containing:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
The 00- prefix is not cosmetic. sshd uses the first value it finds for each keyword, and Ubuntu 24.04 images provisioned with a root password ship /etc/ssh/sshd_config.d/50-cloud-init.conf containing PasswordAuthentication yes. Name your file 99-hardening.conf and it sorts after that one and loses silently.
Reload:
sudo systemctl reload ssh
Now verify the settings actually took effect. Don't skip this:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'
You must see permitrootlogin no and passwordauthentication no before moving on. If either still says yes, another file in sshd_config.d is winning; check 50-cloud-init.conf. Once both read no, root logins and password auth are off.
Configure UFW
Ubuntu's ufw wrapper around iptables is the simplest firewall you'll ever use. Set the defaults and open SSH first:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
One more lockout hazard before you flip the switch: ufw enable activates the default-deny policy immediately, and ufw itself warns that it may disrupt existing SSH connections. Confirm the allow OpenSSH rule above went in with sudo ufw show added, and if you run SSH on a nonstandard port, allow that port instead, or you will cut off your own access.
sudo ufw enable
Add sudo ufw allow 80,443/tcp if you're running a web server. Check status with sudo ufw status verbose.
Unattended security upgrades
Patch on autopilot:
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
The defaults install security updates daily but never reboot on their own. One caution before you enable automatic reboots: with Automatic-Reboot on and no Automatic-Reboot-Time set, the default reboot time is "now", so the server restarts the moment a kernel update lands, killing every SSH session and service at whatever hour the daily job happens to run. If you want the server to reboot automatically when /var/run/reboot-required exists, add Unattended-Upgrade::Automatic-Reboot "true"; to /etc/apt/apt.conf.d/50unattended-upgrades and, in the same edit, set Unattended-Upgrade::Automatic-Reboot-Time "04:00"; (or another low-traffic window).
Verify and snapshot
Reboot once, log in as deploy, and run:
sudo ufw status
sudo systemctl status ssh
free -h
Take a snapshot from your GetVPS control panel. From here on, you have a known-good baseline.
That's it. Ten minutes for a server you can trust.
Continue reading