Skip to content

Instantly share code, notes, and snippets.

@kakoni
Last active April 11, 2025 05:44
Show Gist options
  • Save kakoni/99e68e0e70f97cda5fbc26873e6d1927 to your computer and use it in GitHub Desktop.
Save kakoni/99e68e0e70f97cda5fbc26873e6d1927 to your computer and use it in GitHub Desktop.

Basic Ubuntu Server Hardening Steps

This checklist covers essential baseline security measures for a new Ubuntu VPS.

1. Update and Upgrade the System

Ensure all packages are up-to-date to patch known vulnerabilities.

sudo apt update
sudo apt upgrade -y

2. Create a Non-Root User with sudo Privileges

Avoid using the root user for daily tasks. Create a new user and grant it sudo rights. Replace newusername with your chosen username.

# Create the new user (follow prompts for password, etc.)
sudo adduser newusername

# Add the new user to the 'sudo' group
sudo usermod -aG sudo newusername

3. Set Up SSH Key Authentication

Using SSH keys is significantly more secure than passwords for logging in.

First, on your local machine (not the server), generate an SSH key pair if you don't already have one:

# (Run on your LOCAL machine) - Press Enter to accept defaults if unsure
ssh-keygen -t rsa -b 4096

Next, copy the public key to your server. Replace newusername and your_server_ip accordingly:

# (Run on your LOCAL machine)
ssh-copy-id newusername@your_server_ip

You will be prompted for newusername's password one last time to copy the key. After this, you should be able to SSH in using your key:

# (Run on your LOCAL machine) - Test login (should not ask for password)
ssh newusername@your_server_ip

4. Secure SSH Configuration

Disable root login and password authentication over SSH to enforce key usage and improve security.

Edit the SSH daemon configuration file:

sudo nano /etc/ssh/sshd_config

Find the following lines, uncomment them if necessary, and change their values as shown:

# Disable root login over SSH
PermitRootLogin no

# Disable password-based authentication (ensure SSH keys work first!)
PasswordAuthentication no

# Optional but recommended: Only allow specific users
# Add this line at the end, replacing newusername with the user(s) you want to allow
AllowUsers newusername anotheruser # List allowed users separated by spaces

# Optional but recommended: Change listening port
Port 2222 # From default 22

Save the file (Ctrl+X, then Y, then Enter in nano) and restart the SSH service making sure you have another terminal open and logged in via SSH key just in case something goes wrong:

sudo systemctl restart sshd

Warning: Ensure your SSH key authentication (Step 3) is working correctly before setting PasswordAuthentication no, otherwise you might lock yourself out.

5. Configure Firewall (UFW)

Set up Uncomplicated Firewall (UFW) to block unwanted incoming connections.

# Install UFW (usually installed by default on recent Ubuntu)
sudo apt install ufw

# Set default policies: deny incoming, allow outgoing
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH connections (!!IMPORTANT!!)
# If you changed the SSH port in step 4, use your custom port here
sudo ufw allow 22/tcp # Or use 'sudo ufw allow OpenSSH'

# Allow other necessary services (e.g., web server)
# sudo ufw allow 80/tcp  # HTTP
# sudo ufw allow 443/tcp # HTTPS

# Enable the firewall
sudo ufw enable

# Check the status
sudo ufw status verbose

6. Install and Configure Fail2ban

Fail2ban scans log files and bans IPs showing malicious signs (like too many password failures).

# Install Fail2ban
sudo apt install fail2ban

# Copy the default config file to a local config file (updates won't overwrite this)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Edit the local configuration file to customize settings
sudo nano /etc/fail2ban/jail.local

Inside jail.local, review the settings. At a minimum, ensure the [sshd] jail is enabled:

[sshd]
enabled = true
# You can customize bantime, findtime, maxretry here if desired
# port    = ssh # Uses default SSH port
# logpath = %(sshd_log)s
# backend = %(sshd_backend)s

Enable and start the Fail2ban service:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check status (optional)
sudo systemctl status fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd # Check status of specific jail

7. Set Up Automatic Security Updates

Configure the system to automatically install security updates.

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

This will open a configuration dialog. Select "Yes" to enable automatic updates. Review /etc/apt/apt.conf.d/50unattended-upgrades for more granular control if needed (e.g., enable auto-reboot, email notifications).

8. Harden System Network Settings (sysctl)

Modify kernel parameters to mitigate certain network-based attacks.

Edit the sysctl configuration file:

sudo nano /etc/sysctl.conf

Add or uncomment/modify the following lines (usually added at the end):

# Ignore ICMP broadcast requests
# net.ipv4.icmp_echo_ignore_broadcasts = 1 # Often default

# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Enable SYN cookies to help against SYN floods
net.ipv4.tcp_syncookies = 1

# Enable reverse path filtering to prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

Apply the changes without rebooting:

sudo sysctl -p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment