Your First Hour on a New Ubuntu Server
Set up Ubuntu 24.04 LTS with verified SSH access, a firewall, automatic security updates, recovery checks, and a clear backup plan before deploying your app.

On this page
- 1. Confirm your administrator account and recovery access
- 2. Update the image before installing your application
- 3. Prove that a separate key-based SSH login works
- 4. Disable password and root SSH login
- 5. Enable the firewall with SSH explicitly allowed
- 6. Enable security updates and keep reboots deliberate
- 7. Inspect the server and verify a clean return from reboot
- 8. Arrange recovery before the first deployment
- FAQ
You will finish with an updated Ubuntu 24.04 LTS VPS, working key-based administration, restricted inbound access, and automatic security updates. Start by proving you can recover access through your provider. Verify a separate SSH login before disabling passwords, then enable the firewall with SSH allowed. Check the server after rebooting and arrange an off-server backup before deploying an application.
1. Confirm your administrator account and recovery access
Start with a fresh Ubuntu 24.04 LTS VPS and a non-root account that can use sudo. Keep your original SSH connection open throughout the access changes. Open your provider's browser console now and confirm that you can use its documented recovery method without relying on a working SSH connection.
The laptop examples use deploy as the administrator and 203.0.113.10 as the server address. Replace both with your actual details; that address is reserved for documentation. You can keep your provider's existing administrator username, and you do not need to rename it.
If your image provides only root access, first use the provider's account setup procedure to create a non-root sudo administrator and install your public key. Do not disable root login until that account works. If you are still choosing a provider, use the Hetzner review to assess the operational fit, including recovery access.
Run the server commands as your administrator. They use sudo -n so an unexpected password prompt stops the command instead of hanging; if your account requires a password, authenticate with sudo -v immediately before each command group. Keep passwordless administration separate from any permissions you later give an agent.
whoami
id
sudo -n /usr/bin/id -u
sudo -n ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub0. Compare the host-key fingerprint through the provider console before accepting that key on your laptop; a fingerprint obtained only through the connection you are questioning does not independently verify it.2. Update the image before installing your application
A newly provisioned server can still contain old packages because the provider builds images ahead of time. Update it while there is no application traffic to interrupt. Stay on Ubuntu 24.04 LTS for this procedure; a distribution upgrade is a separate maintenance task.
sudo -n apt-get -o DPkg::Lock::Timeout=120 update
sudo -n env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get -o DPkg::Lock::Timeout=120 -o Dpkg::Options::=--force-confold upgrade -y
sudo -n env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get -o DPkg::Lock::Timeout=120 -o Dpkg::Options::=--force-confold install -y openssh-server ufw unattended-upgrades
sudo -n dpkg --auditdpkg --audit produces no report of incomplete packages. Stop and resolve repository or package errors before continuing.The upgrade keeps existing configuration files and permits affected services to restart. That is appropriate for an empty server, but you should review configuration changes and maintenance timing once it hosts an application. If the package manager reports a lock, let the existing update process finish and retry; deleting its lock file does not stop that process.
3. Prove that a separate key-based SSH login works
Your current terminal proves only that an earlier login succeeded. Before changing authentication, establish a fresh connection using the key you intend to keep. We use a dedicated administration key so it can be replaced without disturbing unrelated access.
Run the following commands on your laptop if you need a new key, and choose a passphrase when prompted. If that filename already exists, keep the existing key or choose another filename rather than overwriting it. Only the public key belongs on the server.
ssh-keygen -t ed25519 -f ~/.ssh/vps_admin
ssh-copy-id -i ~/.ssh/vps_admin.pub [email protected]ssh-copy-id needs an authentication method that already works. If the provider has disabled passwords, use your existing login key or its documented public-key installation process. Adding a key to a provider account does not necessarily install it on an already running machine.
ssh -o ControlMaster=no -o ControlPath=none -o IdentitiesOnly=yes -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -i ~/.ssh/vps_admin [email protected]sudo -v, then sudo -n id -u; the latter must print 0.The connection options prevent an existing multiplexed session from making this check look successful. Leave both terminals open until the SSH and firewall changes are verified. If the fresh connection fails, fix key ownership or account access before proceeding.
4. Disable password and root SSH login
After the separate login succeeds, create /etc/ssh/sshd_config.d/00-local-access.conf with the following contents using your preferred privileged editor. This baseline assumes public-key authentication, without an SSH keyboard-interactive authentication requirement. Ubuntu supports these configuration snippets, but earlier settings can take precedence, so inspect the effective configuration afterward. Ubuntu OpenSSH documentation
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin nosudo -n /usr/sbin/sshd -t
sudo -n /usr/sbin/sshd -T | awk '$1 ~ /^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|permitrootlogin)$/ {print}'sshd -t returns silently with success. The effective settings show pubkeyauthentication yes, passwordauthentication no, kbdinteractiveauthentication no, and permitrootlogin no.If the values differ, inspect the main configuration and included snippets before reloading. A configuration containing Match rules also needs connection-specific inspection with sshd -T -C; the global output alone is insufficient. Keep the SSH port unchanged during this setup.
sudo -n /usr/sbin/sshd -t && sudo -n systemctl reload ssh.serviceIf the new connection fails, use your retained shell to move the new snippet outside the included configuration directory, validate again, and reload. Avoid changing account permissions while simultaneously debugging authentication. Before adding an automation identity, follow the SSH hardening procedure for agent access to separate human recovery access from routine automation.
5. Enable the firewall with SSH explicitly allowed
For an empty VPS, SSH should be the only deliberately exposed application service. Add its allow rule before enabling UFW, then deny other unsolicited inbound traffic. This procedure assumes SSH still uses its standard port; inspect the application profile before applying it. Ubuntu firewall documentation
sudo -n ufw app info OpenSSH
sudo -n ufw allow OpenSSH
sudo -n ufw default deny incoming
sudo -n ufw default allow outgoing
sudo -n ufw --force enable
sudo -n ufw status verboseStatus: active, a default deny policy for incoming traffic, and an allow rule for OpenSSH. Repeat a fresh SSH connection from your laptop; the existing terminal remaining open is not sufficient proof.Review every listed allow rule because enabling UFW does not remove rules already supplied by an image. If your provider also has a firewall, confirm that it permits SSH to this server. Keep the host and provider rules understandable enough that you can explain which layer permits each connection.
Do not open web ports until you actually deploy a web service. Keep a local database bound to a loopback address unless another machine has a defined reason to reach it. Check every public address assigned to the VPS, since an overlooked address family can expose a service you thought was private.
Revisit this firewall model if you later install Docker. Published container ports can bypass the filtering path you expect UFW to control, so an active UFW status is not proof that a container port is private. Follow the Docker firewall documentation before publishing containers.
6. Enable security updates and keep reboots deliberate
Enable unattended security updates before the server becomes something you are afraid to touch. The following configuration enables daily package checks and unattended upgrades while keeping automatic reboots disabled. The package's allowed origins still determine which updates qualify. Ubuntu automatic update documentation
sudo -n tee /etc/apt/apt.conf.d/99-local-updates >/dev/null <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Unattended-Upgrade::Automatic-Reboot "false";
EOF
sudo -n systemctl enable --now apt-daily.timer apt-daily-upgrade.timer
apt-config dump | awk '/APT::Periodic::(Update-Package-Lists|Unattended-Upgrade)|Unattended-Upgrade::Automatic-Reboot / {print}'
systemctl list-timers --all --no-pager apt-daily.timer apt-daily-upgrade.timer
sudo -n unattended-upgrade --dry-run --debugInspect the allowed origins instead of assuming every installed package is covered. Third-party repositories need a separate update policy. Updates can restart services even when automatic rebooting is disabled, so your application must tolerate ordinary service restarts.
Put a recurring maintenance appointment in your calendar to review update failures and pending reboots. Assign it to an actual person rather than leaving it as an intention. Automatic installation reduces repetitive work, but an unreviewed failure can leave the machine quietly falling behind.
7. Inspect the server and verify a clean return from reboot
Check the machine while its intended workload is still simple. Inspect listening sockets and identify the process behind each unexpected listener. A loopback-only resolver is different from an application listening on every interface, and neither should be judged from a port number alone.
sudo -n ss -lntup
systemctl --failed --no-pager
free -h
df -h /
sudo -n journalctl -p err -b --no-pager -n 40Verify the clock and the image's security enforcement on the actual VPS. Incorrect time can interfere with certificate checks and make incident logs confusing. If synchronization is inactive, inspect the installed time service rather than installing a competing daemon.
timedatectl status
sudo -n aa-status
if test -f /var/run/reboot-required; then
cat /var/run/reboot-required
fiWith recovery access ready and no workload running, reboot to verify that the machine can return to service. This disconnects your terminals, so perform it only after the fresh SSH checks succeed. Leave memory and kernel tuning alone until you have workload evidence; use the small VPS tuning guide when a specific resource becomes a constraint.
sudo -n systemctl reboot8. Arrange recovery before the first deployment
Your next task is to make this machine replaceable before it holds application data. Enable a scheduled backup destination outside the VPS and document how you would restore it. A provider snapshot is useful for recovering an entire machine, but it does not automatically provide application-consistent database recovery.
- Write down the server's purpose, its administrator account, and the recovery procedure in a private operations record. Store recovery credentials in your password manager.
- Enable the provider's scheduled backup facility or configure a separate backup destination. Check the retention settings and who can delete the backups.
- Restore a backup into an isolated replacement VPS. Confirm that you can log in and read a known file without overwriting the original server.
- Before accepting application writes, add the application's persistent files and database-native backups to the schedule. Arrange an alert for failed or overdue backups and verify delivery.
We recommend Claude Code for reviewing the resulting configuration and explaining unexpected service logs. Start with redacted command output or a narrowly scoped account, and approve individual changes before execution. Do not give it your recovery credentials or unrestricted sudo as a shortcut; the AI operations playbook explains how to bound that access.
Work through the Ubuntu hardening verification checklist before exposing your application. Then deploy one service under a dedicated, unprivileged account and open only the inbound ports that service requires. Add an external availability check when the application has an endpoint worth monitoring.
FAQ
What should I do first when setting up an Ubuntu server?
Confirm that you can recover access without SSH, then establish a working non-root administrator. This gives you a way back when an authentication change fails. Update the empty machine before installing application dependencies, and keep the original terminal open while checking fresh logins. Treat successful reconnection as a prerequisite for further access restrictions.
How do I harden an Ubuntu VPS without locking myself out?
Change one access layer at a time and verify a new connection after each change. Establish key authentication before removing password access, validate SSH configuration before reloading it, and add the SSH firewall rule before enabling filtering. Keep provider recovery access available throughout. An already connected terminal can survive a mistake that prevents every subsequent login.
Do I need Fail2ban if SSH passwords are disabled?
We would not make Fail2ban a prerequisite for this baseline. With password and keyboard-interactive authentication disabled, password guessing cannot authenticate an attacker, though connection attempts still create noise and consume resources. Consider Fail2ban when you have a specific service or abuse pattern to address, and verify its behavior against your actual logs before relying on it.
What belongs on a new VPS checklist before deployment?
Include evidence that you can administer and recover the machine, not just a list of installed packages. Record a successful fresh login, the intended network exposure, and the result of a reboot. Also require a recoverable backup before storing application data. A checklist becomes useful when each item has an observable success condition and someone responsible for failures.
Are automatic security updates enough to maintain Ubuntu?
They handle part of maintenance, but you still need to notice failures and complete work that requires a reboot. You also own the update policy for application dependencies and repositories you add later. Keep a regular review appointment and watch backup health alongside update status. A server can remain reachable while either process has been broken for some time.
Put this guide in the bigger picture
See how this topic connects to the rest of your product. Our free field guide explains apps, infrastructure and AI, with checklists to help you make business decisions.






