Securing an Ubuntu Server: A Practical Guide
Sept. 28, 2024 (updated) by @anthonynsimon
In this guide, I'll cover some common steps I've used to secure many Ubuntu servers over the years.
While this is not meant to be an exhaustive list, these are well-understood security measures to reduce the risk of unauthorized access, data breaches and loss of service.
1. Keep your system up-to-date
Regularly updating your system is one of the most important steps to keep your server secure. It ensures that you have the latest security patches and bug fixes.
apt update && apt upgrade -y
2. Set up a firewall
Ubuntu comes with a firewall called ufw
. You can enable it and only allow the necessary ports. For example:
ufw allow ssh
ufw allow http
ufw allow https
ufw enable
3. Disable Password Authentication
Disable password authentication and use SSH keys instead. This will reduce the risk of brute-force attacks.
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords no/g' /etc/ssh/sshd_config
echo 'ChallengeResponseAuthentication no' >> /etc/ssh/sshd_config
You'll need to reload the SSH agent for these changes to take effect:
sudo systemctl reload ssh
4. Disable root login
Disable root login to prevent attackers from directly logging in as root. Instead, create a regular user with the necessary permissions and when needed, use sudo
to run commands as root.
First, create a new user without a password (we only want to use SSH keys):
adduser --disabled-password --gecos "" nonroot
Add the new user to the sudo
group by appending this line to the /etc/sudoers
file:
echo "nonroot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
Next, allow the new user to log in via your SSH key:
AUTHORIZED_KEYS=$(cat ~/.ssh/authorized_keys)
sudo -H -u nonroot bash -c '
mkdir ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
'
sudo -H -u nonroot bash -c "echo '$AUTHORIZED_KEYS' >> ~/.ssh/authorized_keys"
If you're using Docker, you may also want to add the nonroot
user to the docker
group:
sudo usermod -aG docker nonroot
Exit the nonroot
user shell to go back to the root user. Now, you can disable root login:
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
Restart the SSH service:
systemctl restart ssh
You can now log in as the nonroot
user and use sudo
to run commands as root.
5. Install Fail2ban
Fail2ban helps mitigate brute-force attacks by banning IPs after too many failed login attempts.
To install:
sudo apt install fail2ban
You can then configure Fail2ban by editing the /etc/fail2ban/jail.local
file. For example:
cat <<EOF > /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 5
findtime = 600
bantime = 600
ignoreip = 127.0.0.1/8
logpath = /var/log/auth.log
EOF
After making changes, restart Fail2ban:
sudo systemctl restart fail2ban
You can then view SSH log in attempts with:
sudo tail -f /var/log/auth.log
6. Secure Shared Memory
Shared memory is a common attack vector. On one hand, it's an efficient way for processes to communicate, but it can also be exploited since multiple processes can access it and use it to escalate privileges or execute arbitrary code.
To secure shared memory, add the following line to /etc/fstab
:
sudo echo "tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0" >> /etc/fstab
You'll need to reboot the server for this change to take effect.
sudo reboot
Command cheatsheet
Here are some useful commands to check the security of your Ubuntu server:
Ensure only root has UID 0
awk -F: '($3 == 0) {print}' /etc/passwd
List all users
cut -d: -f1 /etc/passwd
List users without password
awk -F: '($2 == "") {print}' /etc/shadow
Check disk usage in human-readable format
df -h
Only in current dir, order by size:
du -h -d 1 | sort -h
Check for listening ports
netstat -tuln
ss -tuln
Show active user sessions
w
Check banned IPs
zgrep 'Ban' /var/log/fail2ban.log*
Show Ubuntu version
lsb_release -a
Conclusion
These steps improve the security posture of an Ubuntu server. However, security is an ongoing process, and additional steps can further harden the system.
For example, you may also want to consider:
- Scheduling automated backups
- Checking your disks are encrypted
- Setting up monitoring and alerting
- Configuring your cloud provider's firewall or security groups
- Use a private network to isolate your server from the public internet
- Regularly scan for vulnerabilities and do system audits
I hope this guide is helpful to you. If you have any questions or suggestions, feel free to reach out to me on X/Twitter.