Hardening Internet-Facing Linux Servers: A Practical Security Guide
Exposing a Linux server to the public Internet always introduces risk. Attackers constantly scan for open ports, weak SSH credentials, and unpatched services. With a few targeted configuration steps, you can significantly strengthen your security posture without increasing operational complexity.
This guide walks you through a practical baseline for securing Linux servers that are reachable from the Internet:
- Move SSH from port 22 to port 9022
- Use RSA SSH keys for authentication
- Create an
.ssh/configfile for easier and more secure access - Disable root SSH login and disable password authentication
- Configure UFW to expose only the ports you explicitly require
- Install and configure fail2ban
- Enable automatic security updates
All steps apply to Ubuntu 20.04 → 24.04 and most modern Debian-based distributions.
1. Move SSH from Port 22 to Port 9022 or any other Port you like
While not a primary security measure, shifting SSH away from the default port dramatically reduces bot-driven login attempts. It’s a simple and effective hardening step.
Step 1: Edit the SSH daemon config
sudo nano /etc/ssh/sshd_config
Find:
#Port 22
Uncomment it to:
Port 9022
Save and exit.
Step 2: Allow the new SSH port in UFW
sudo ufw allow 9022/tcp
More details on the UFW firewall later.
Step 3: Restart SSH (mandatory)
sudo systemctl restart sshd
Step 4: Test the new port before closing your existing session
ssh -p 9022 user@yourserver.com
Only continue once this works.
2. Create and Use an RSA Key Pair for SSH
Key-based authentication is significantly more secure than passwords and prevents brute-force attacks.
Step 1: Generate an RSA key pair on your client
To start, we need to create an RSA key.
ssh-keygen -t rsa -b 4096 -C "yourname@example.com"
This creates:
~/.ssh/id_rsa→ private key~/.ssh/id_rsa.pub→ public key
Step 2: Copy your public key to the server
To enable this key on the server, you need to copy the public key to the ˜/.ssh/authorized_keys file of the user that needs to be able to log in to the server using the key and SSH.
ssh-copy-id -p 9022 user@yourserver.com
Manual fallback:
cat ~/.ssh/id_rsa.pub | ssh -p 9022 user@yourserver.com 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
Permissions:
ssh -p 9022 user@yourserver.com "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
3. SSH Into the Server Using Your RSA Key
If you are using the default key name (id_rsa).
ssh -p 9022 user@yourserver.com
To specify a non-default key, use:
ssh -i ~/.ssh/custom_key -p 9022 user@yourserver.com
4. Create an .ssh/config File for Easier Logins
This makes using SSH to log in much easier as we don't have to specify the key, port, user and full host name when we want to connect to a remote host.
nano ~/.ssh/config
Example:
Host myserver
HostName yourserver.com
Port 9022
User username
IdentityFile ~/.ssh/id_rsa
The login command now becomes:
ssh myserver
5. Disable Root SSH Login and Password Authentication
sudo nano /etc/ssh/sshd_config
Set:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart SSH:
sudo systemctl restart sshd
6. Configure UFW and Allow Only Required Ports
UFW is the built-in firewall for many Unix system. It's effective and easy to configure.
Default deny posture
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow workload-specific ports
sudo ufw allow 9022/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Enable UFW
sudo ufw enable
sudo ufw status verbose
7. Install, Enable, and Configure Fail2ban
Fail2ban stops users from repeatedly trying to log in by blacklisting them for a set amount of time before they can try to log in again. Fail2ban uses UFW rules to accomplish this.
Install
sudo apt update
sudo apt install fail2ban
Configure jail overrides
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8
[sshd]
enabled = true
port = 9022
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
Restart and verify
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
8. Enable Automatic Security Updates
Keeping your system updated is critical, especially for Internet-facing machines. Ubuntu includes unattended-upgrades, a service that automatically applies security patches.
Step 1: Install the required package
Most Ubuntu systems already have it, but ensure it’s installed:
sudo apt install unattended-upgrades
Step 2: Enable unattended upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
This creates or updates /etc/apt/apt.conf.d/20auto-upgrades with:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Step 3: Optional — Review or customize the update policy
Main config file:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Key options:
- Allow only security updates (recommended)
- Automatically remove unused packages
- Enable reboot if required (use with caution on production systems)
Step 4: Test it manually
sudo unattended-upgrade --dry-run --debug
This shows what would be applied without making changes.
Conclusion
Hardening Internet-facing Ubuntu servers doesn’t require complex tooling. By moving SSH to a nonstandard port, enforcing RSA key authentication, disabling root and password logins, configuring a strict firewall, installing fail2ban, and enabling automatic security updates, you eliminate the vast majority of attack vectors used by automated bots and low-effort attackers.
This setup provides a strong and reliable security baseline for any production or personal workload — and can be easily automated using Ansible, cloud-init, or shell scripts.