Ubuntu Server Hardening Guide: Best Practices for Maximum Security

Ubuntu Server Hardening

🛡️ 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

SSH Key Authentication

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

Firewall Status

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

Active Listening Services

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.
Password Policy


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.

Leave a Reply