🛡️ Ubuntu Server Hardening Guide for Maximum Security
Securing your Ubuntu server is critical before deploying it in a production environment. This guide covers the best practices for hardening your server, including securing SSH, configuring firewalls, restricting root access, managing services, and ensuring system monitoring. Following these steps will significantly reduce potential attack vectors.
1️⃣ Update the System
Start by updating your system to ensure you’re running the latest security patches and stable versions of packages.
apt-get update
apt-get upgrade -y
The apt-get update
command updates the package repository information, and apt-get upgrade -y
installs the available updates for all installed packages, ensuring your system is up-to-date with the latest security patches.
2️⃣ Remove UFW (Uncomplicated Firewall)
If you’re using firewalld for firewall management, it’s best to remove UFW (Uncomplicated Firewall) to avoid conflicts. Firewalld provides a more flexible and modern approach to firewall management.
systemctl stop ufw
sudo ufw disable
sudo apt remove --purge ufw -y
sudo rm -rf /etc/ufw /lib/ufw
sudo rm -f /var/log/ufw.log
sudo apt autoremove -y
sudo apt update
The above commands stop UFW, disable it, remove all associated files, and perform a cleanup to ensure UFW is fully removed from your system.
3️⃣ Install Essential Security and Monitoring Tools
Install essential security tools to help protect and monitor your system. Key packages include:
- fail2ban: Prevents brute-force attacks by banning IP addresses showing malicious activity.
- telnet: Useful for testing network connectivity.
- htop: A real-time system monitoring tool that shows resource usage.
- net-tools: Includes legacy tools like
netstat
for network monitoring. - firewalld: A dynamic firewall manager.
- openssl: For managing SSL certificates.
- unzip: Utility for extracting `.zip` files.
apt-get install fail2ban telnet htop net-tools firewalld openssl unzip -y
The above command installs all of these tools in one go.
4️⃣ Create a Non-Root Admin User
Running a server as the root user is risky. Create a non-root user with sudo
privileges to manage the system securely.
adduser sysadmin
usermod -aG sudo sysadmin
The sysadmin
user is created, and the usermod -aG sudo sysadmin
command grants administrative privileges to the user.
5️⃣ Enforce SSH Key Authentication Only
To enhance security, disable password-based logins for SSH and require SSH key authentication only. This eliminates the risk of brute-force attacks targeting SSH passwords.
Edit the SSH configuration file:
nano /etc/ssh/sshd_config
Set the following parameters:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Then, add your public key to the user’s ~/.ssh/authorized_keys
file:
mkdir -p /home/sysadmin/.ssh
nano /home/sysadmin/.ssh/authorized_keys
chmod 700 /home/sysadmin/.ssh
chmod 600 /home/sysadmin/.ssh/authorized_keys
chown -R sysadmin:sysadmin /home/sysadmin/.ssh
Finally, restart SSH:
systemctl restart ssh
6️⃣ Disable Root SSH Access
Disabling root login over SSH reduces the attack surface. By preventing root SSH access, attackers can’t target the most privileged account.
Edit the SSH configuration file again:
nano /etc/ssh/sshd_config
Set the following:
PermitRootLogin no
Then, restart SSH:
systemctl restart ssh
7️⃣ Lock Root User
Lock the root account to prevent login attempts. This ensures that no one can log in as root, either locally or remotely.
passwd -l root
usermod -s /sbin/nologin root
The first command locks the root password, and the second command sets the root shell to /sbin/nologin
, preventing root login.
8️⃣ Set Default Boot Target to Multi-User (CLI)
If you’re not using a graphical user interface (GUI), configure the server to boot in multi-user mode (CLI only) for better security and performance.
systemctl set-default runlevel3
9️⃣ Configure Firewalld
Use firewalld to create rules that allow only necessary inbound and outbound traffic. By default, block all inbound traffic and allow specific ports like HTTP (80) and HTTPS (443).
# Allow basic HTTP and HTTPS services
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Allow outbound established and related traffic
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow outgoing HTTP and HTTPS requests
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --dport 80 -j ACCEPT
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 2 -p tcp --dport 443 -j ACCEPT
# Block all other outbound traffic
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 3 -j DROP
# Apply all rules
sudo firewall-cmd --reload
🔟 Verify Firewall and Port Status
After configuring the firewall, verify its status and ensure the rules are applied:
# Check if firewalld is active
sudo firewall-cmd --state
# List allowed services and ports
sudo firewall-cmd --list-all
# Show custom direct rules
sudo firewall-cmd --direct --get-all-rules
1️⃣1️⃣ Check Open Ports
It’s important to know which ports are open and which services are running on your server. This helps you ensure that only necessary services are exposed to the network.
# Modern way using ss
sudo ss -tuln
# Traditional method with netstat
sudo netstat -tuln
1️⃣2️⃣ Monitor WHEEL Group
Monitor users with administrative access via sudo
, particularly those in the wheel
group. Ensuring only authorized users have administrative privileges is key.
# View users with ALL sudo privileges
cat /etc/sudoers | grep ALL
# Check members of the 'wheel' group
cat /etc/group | grep wheel
1️⃣3️⃣ List Active Listening Services
Listing active services helps identify potential vulnerabilities by showing which applications are open to the network.
# Shows active listening TCP/UDP ports with associated processes
netstat -plntu
1️⃣4️⃣ Monitor Auto-Run Programs
Minimize unnecessary auto-start services to reduce the attack surface and improve system performance.
# Disable shell access for a service user
usermod -s /sbin/nologin
1️⃣5️⃣ Password Policy
Enforce a strong password policy to secure access to the server. Set minimum password length, expiration policy, and prevent password reuse.
This can be configured through the /etc/login.defs
file or pam_pwquality.so
in the /etc/pam.d/common-password
file.
Key Takeaways
Securing your server is a critical step before going live with any service. By implementing the practices above, you can drastically reduce the attack surface of your server and ensure that your system is more resilient to potential attacks. Regularly auditing your configuration and keeping your software updated will help maintain a high level of security.