How to Secure Your Ubuntu 24.04 Server (Initial Setup)

Beginner
Updated Mar 24, 202614 min read~25 minutes total
Ubuntu
Security
Linux
DevOps
Best Practices

On This Page

Prerequisites

A Raff VM running Ubuntu 24.04 with at least 1 vCPU and 1 GB RAM (CPU-Optimized Tier 1 or higher), root access via SSH or the Raff web console

Don't have a server yet? Deploy a Raff VM in 60 seconds.

Deploy a VM

Introduction

Every Ubuntu 24.04 server exposed to the internet faces automated attacks within minutes of going online. Bots scan IP ranges continuously, attempting SSH brute-force logins, probing open ports, and exploiting default configurations. Securing your server immediately after deployment is not optional — it is the first task you should complete before installing any application.

This tutorial walks you through the essential security hardening steps for a fresh Raff Ubuntu 24.04 VM. You will create a non-root user with sudo privileges, configure SSH key authentication and disable password logins, set up the UFW firewall to block unauthorized access, install Fail2Ban to automatically ban brute-force attackers, and enable automatic security updates so your server stays patched without manual intervention.

By the end of this tutorial, your server will have a hardened SSH configuration, an active firewall allowing only the ports you choose, and automated intrusion prevention — a solid security baseline for any workload you deploy next.

Step 1 — Logging In as Root and Creating a Sudo User

When you first deploy a Raff Ubuntu 24.04 VM, you receive a root password or can log in with the SSH key you added during creation. Connect to your server using its public IP address:

bashssh root@your_server_ip

Operating as root for daily tasks is dangerous because every command executes with full system privileges — a single typo can destroy your server. Create a regular user account that can escalate to root privileges only when needed via sudo.

Create a new user (replace sammy with your preferred username):

bashadduser sammy

You will be prompted to set a password and fill in optional profile information. Use a strong password — at least 16 characters with a mix of letters, numbers, and symbols.

Grant the new user sudo privileges by adding them to the sudo group:

bashusermod -aG sudo sammy

Verify the user was added to the group:

bashgroups sammy

You should see sudo in the output. From this point forward, you will use this account instead of root.

Step 2 — Configuring SSH Key Authentication

Passwords can be brute-forced. SSH keys cannot — they use cryptographic key pairs that are practically impossible to guess. If you did not add an SSH key when creating your Raff VM, generate one now on your local machine (not the server):

bashssh-keygen -t ed25519 -C "your_email@example.com"

Press Enter to accept the default file location. Optionally set a passphrase for additional security. The ed25519 algorithm is modern, fast, and produces shorter keys than RSA while maintaining strong security.

Copy the public key to your server:

bashssh-copy-id sammy@your_server_ip

If ssh-copy-id is not available on your system, manually copy the key:

bashcat ~/.ssh/id_ed25519.pub | ssh root@your_server_ip "mkdir -p /home/sammy/.ssh && cat >> /home/sammy/.ssh/authorized_keys && chown -R sammy:sammy /home/sammy/.ssh && chmod 700 /home/sammy/.ssh && chmod 600 /home/sammy/.ssh/authorized_keys"

Test the key-based login by opening a new terminal (keep your current session open as a backup):

bashssh sammy@your_server_ip

You should log in without being prompted for a password. If this works, proceed to the next step. If it does not work, do not close your root session — troubleshoot the key permissions first.

Step 3 — Hardening the SSH Configuration

Now that key-based authentication works, disable password logins and root SSH access to eliminate the two most common attack vectors.

Open the SSH daemon configuration file:

bashsudo nano /etc/ssh/sshd_config

Find and modify the following directives (some may be commented out with # — remove the # and set the value):

bashPermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers sammy

Here is what each setting does:

  • PermitRootLogin no — Blocks all SSH logins as root, even with a valid key
  • PasswordAuthentication no — Disables password-based logins entirely
  • PubkeyAuthentication yes — Ensures key-based authentication is active
  • MaxAuthTries 3 — Disconnects clients after 3 failed authentication attempts
  • LoginGraceTime 30 — Gives users 30 seconds to authenticate before disconnecting
  • X11Forwarding no — Disables X11 forwarding, which is unnecessary on a server
  • AllowUsers sammy — Only the specified user can log in via SSH

Save the file and validate the configuration:

bashsudo sshd -t

If there are no errors, restart the SSH service:

bashsudo systemctl restart ssh

Test the new configuration in a new terminal before closing your current session:

bashssh sammy@your_server_ip

Also verify that root login is blocked:

bashssh root@your_server_ip

You should see Permission denied (publickey). This confirms the hardened configuration is working.

Step 4 — Setting Up the UFW Firewall

UFW (Uncomplicated Firewall) is Ubuntu's default firewall management tool. It provides a simple interface for managing iptables rules. By default, UFW is installed but inactive on Ubuntu 24.04.

Before enabling UFW, allow SSH connections so you do not lock yourself out:

bashsudo ufw allow OpenSSH

Enable the firewall:

bashsudo ufw enable

Type y when prompted. Check the firewall status:

bashsudo ufw status verbose

You should see that OpenSSH is allowed on both IPv4 and IPv6, and the default incoming policy is deny. This means all incoming traffic is blocked except SSH on port 22.

As you install applications, you will add rules for their specific ports. Common rules you might add later:

bashsudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw allow 3306/tcp  # MySQL (only if needed remotely)

Tip

Only open ports that your application requires. Each open port is a potential attack surface. You can always add rules later with sudo ufw allow and remove them with sudo ufw delete allow.

Step 5 — Installing and Configuring Fail2Ban

Fail2Ban monitors log files for repeated failed login attempts and automatically bans the offending IP addresses using firewall rules. Even with password authentication disabled, Fail2Ban adds an extra layer of defense against SSH key brute-force attempts and reduces log noise.

Install Fail2Ban:

bashsudo apt update
sudo apt install -y fail2ban

Fail2Ban uses jail configuration files to define what services to monitor and how to respond. Create a local configuration file (never edit the default jail.conf directly, as it gets overwritten during updates):

bashsudo nano /etc/fail2ban/jail.local

Add the following configuration:

ini[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 3
banaction = ufw
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

This configuration bans any IP address that fails SSH authentication 3 times within 10 minutes. The ban lasts 1 hour. The banaction = ufw directive tells Fail2Ban to use UFW for blocking, which keeps your firewall rules consistent.

Start and enable Fail2Ban:

bashsudo systemctl enable fail2ban
sudo systemctl start fail2ban

Verify Fail2Ban is running and monitoring SSH:

bashsudo fail2ban-client status sshd

You should see output showing the jail is active with the current number of banned IPs. After a few hours online, you will likely see banned IPs from automated scanners.

To check which IPs are currently banned:

bashsudo fail2ban-client status sshd

To manually unban an IP if needed:

bashsudo fail2ban-client set sshd unbanip 203.0.113.50

Step 6 — Enabling Automatic Security Updates

Ubuntu 24.04 includes the unattended-upgrades package, which can automatically install security patches. This is critical for a production server — vulnerabilities are discovered and patched regularly, and manual updates are easy to forget.

Install and enable unattended upgrades:

bashsudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Select Yes when prompted to automatically download and install stable updates.

Verify the configuration file includes security updates:

bashsudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Confirm these lines are uncommented (no // prefix):

bashUnattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

While you still have /etc/apt/apt.conf.d/50unattended-upgrades open, scroll to the bottom and optionally add these two lines to enable automatic reboots when a kernel update requires it:

bashUnattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

This schedules automatic reboots at 4:00 AM UTC only when a kernel update requires a restart. For production servers that cannot tolerate unexpected reboots, skip these lines and schedule reboots manually. Save and close the file when you are done.

Test that unattended upgrades are working:

bashsudo unattended-upgrade --dry-run --debug

This runs a simulation without actually installing anything. You should see output listing available security updates.

Step 7 — Verifying Your Security Configuration

Run through this verification checklist to confirm everything is properly configured.

Check that only your sudo user can log in via SSH:

bashssh root@your_server_ip
# Expected: Permission denied (publickey)

Check the firewall status:

bashsudo ufw status numbered

You should see only the rules you explicitly added (SSH at minimum).

Check that Fail2Ban is active:

bashsudo fail2ban-client status

Check that automatic updates are enabled:

bashsudo systemctl status unattended-upgrades

Check for any pending security updates:

bashsudo apt update
sudo apt list --upgradable

Install any pending updates:

bashsudo apt upgrade -y

Your server now has a solid security baseline. Every future tutorial on the Raff Learn Hub assumes you have completed these steps.

Note

Security is an ongoing process. Periodically review your firewall rules, check Fail2Ban logs for patterns, and keep your system updated. Consider enabling automated backups on your Raff VM for disaster recovery.

Conclusion

You have secured your Raff Ubuntu 24.04 server with a non-root sudo user, SSH key authentication with password login disabled, UFW firewall blocking all unauthorized incoming traffic, Fail2Ban automatically banning brute-force attackers, and automatic security updates for unattended patching.

This configuration significantly reduces your attack surface and protects against the most common threats targeting cloud servers. From here, you can:

Raff VMs deploy in 60 seconds with NVMe SSD storage and AMD EPYC processors, giving you a fast, reliable foundation for any workload. Combined with DDoS protection included on all tiers and configurable firewall rules, your infrastructure is protected at both the network and server level.

Get notified when we publish new tutorials

Cloud tips, step-by-step guides, and infrastructure insights — straight to your inbox.

Frequently Asked Questions

Ready to get started?

Deploy an Ubuntu 24.04 VM and follow along in under 60 seconds.

Deploy a VM Now