How to secure your Ubuntu server
OpenPanel Team
11/14/2024
Securing your Ubuntu server is one of the most important things to do when you have your own server (VPS). There are a ton of horror stories about people who have had their servers hacked and data stolen.
Security is a broad and hard topic to cover and usually the best way in for hackers is actually not from your servers but rather your software (your code).
In this article, we'll cover some basic steps to secure your Ubuntu server.
1. Update your system
Keep always your system up to date. This can be done with a simple command:
sudo apt update && sudo apt upgrade -y
2. Create a new user
Create a new user with sudo privilages. By doing this you can manage your server without giving full root access to your server. But for this to be secure, you should also disable root login over SSH.
sudo adduser <username>
sudo usermod -aG sudo <username>
3. Secure your SSH
Securing your SSH is like securing your front door. You want to make sure it's always locked and only accessible to people you trust. Since SSH is how you access your server, you want to make sure it's as secure as possible.
We'll disable root login and only allow access with ssh keys.
sudo nano /etc/ssh/sshd_config
Find the line that says PermitRootLogin yes
and change it to PermitRootLogin no
.
Also find or add these lines to disable password authentication and only allow SSH keys:
PasswordAuthentication no
PubkeyAuthentication yes
Then restart the SSH service:
sudo systemctl restart ssh
3.1 Change SSH port
You can change the SSH port to make it harder to brute force your server.
3.2 Add fail2ban
Fail2ban is a tool that can help you protect your server from brute force attacks. It works by monitoring your SSH logs and banning IPs that show suspicious activity. With this and a good ssh key you should be pretty safe.
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
3.3 Two factor authentication
Adding two factor authentication is a good idea. There are many tools for this, but a simple one is Google Authenticator. You can install it with this command:
sudo apt install -y libpam-google-authenticator
sudo sed -i 's/^#*\s*KbdInteractiveAuthentication\s.*$/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config
sudo echo 'AuthenticationMethods publickey,password publickey,keyboard-interactive' | sudo tee -a /etc/ssh/sshd_config
echo "auth required pam_google_authenticator.so" | sudo tee -a /etc/pam.d/sshd
echo "auth required pam_permit.so" | sudo tee -a /etc/pam.d/sshd
sudo sed -i '/^@include common-auth/s/^/#/' /etc/pam.d/sshd
sudo runuser -l "CHANGE_THIS_TO_YOUR_USERNAME" -c 'google-authenticator -t -d -f -r 3 -R 30 -W'
sudo systemctl restart ssh
Enable your firewall
This maybe goes without saying, but you should always enable a firewall and only allow traffic on the ports you need.
Common ports
- SSH: 22
- HTTP: 80
- HTTPS: 443
- FTP: 21
- SFTP: 2222
sudo ufw enable
sudo ufw allow OpenSSH # Allow SSH
sudo ufw allow 80,443/tcp; # Allow HTTP and HTTPS traffic
Easy to use code snippet
Create a file called secure.sh
and add the code below. Then run it with sudo bash secure.sh
. It'll prompt you for a username and generate a password and SSH key for you.
#!/bin/bash
# Update and upgrade system
echo "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
# Install necessary packages
echo "Installing necessary packages..."
sudo apt install -y whois # For mkpasswd
sudo apt install -y libpam-google-authenticator fail2ban ufw
# Create a new user with sudo access
read -p "Enter the new username: " username
if id "$username" &>/dev/null; then
echo "User $username already exists!"
exit 1
else
# Generate a random password
password=$(openssl rand -base64 12)
# Create the user and assign the password
sudo adduser --gecos "" "$username" --disabled-password
echo "$username:$password" | sudo chpasswd
sudo usermod -aG sudo "$username"
echo "User $username created with sudo access."
echo "Generated password for $username: $password"
# Generate SSH key for the new user
sudo -u "$username" mkdir -p /home/"$username"/.ssh
sudo -u "$username" ssh-keygen -t rsa -b 4096 -f /home/"$username"/.ssh/id_rsa -q -N ""
echo "SSH key generated for $username."
# Copy the existing authorized_keys from root or initial user to the new user's .ssh directory
if [ -f /root/.ssh/authorized_keys ]; then
sudo cp /root/.ssh/authorized_keys /home/"$username"/.ssh/
fi
sudo chown -R "$username":"$username" /home/"$username"/.ssh
if [ -f /home/"$username"/.ssh/authorized_keys ]; then
sudo chmod 600 /home/"$username"/.ssh/authorized_keys
fi
echo "Authorized keys copied to new user's .ssh directory."
# Outputs the public key
public_key=$(cat /home/"$username"/.ssh/id_rsa.pub)
fi
# Set up SSH to use keys only (disable password login)
echo "Configuring SSH to use keys only..."
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo sed -ri 's/^(#)?PasswordAuthentication\s+.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -ri 's/^(#)?PermitRootLogin\s+.*/PermitRootLogin no/' /etc/ssh/sshd_config
# Enables Google Authenticator
sudo sed -i 's/^#*\s*KbdInteractiveAuthentication\s.*$/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config
sudo echo 'AuthenticationMethods publickey,password publickey,keyboard-interactive' | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart ssh
# Enable and configure the firewall
echo "Enabling and configuring the firewall..."
sudo ufw allow OpenSSH
# sudo ufw allow 80,443,3000,996,7946,4789,2377/tcp;
# sudo ufw allow 7946,4789,2377/udp;
sudo ufw allow 80,443,3000/tcp;
sudo ufw enable
# Configure Google Authenticator
echo "Configuring Google Authenticator for the user..."
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
echo "auth required pam_google_authenticator.so" | sudo tee -a /etc/pam.d/sshd
echo "auth required pam_permit.so" | sudo tee -a /etc/pam.d/sshd
sudo sed -i '/^@include common-auth/s/^/#/' /etc/pam.d/sshd
sudo runuser -l "$username" -c 'google-authenticator -t -d -f -r 3 -R 30 -W'
sudo systemctl restart ssh
# Configure Fail2Ban
echo "Configuring Fail2Ban..."
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check if Docker is installed
if ! command -v docker &> /dev/null
then
echo "Docker is not installed. Installing Docker..."
# Install required packages
sudo apt-get install -y \
ca-certificates \
curl \
gnupg \
lsb-release \
apt-transport-https
# Add Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set Up Docker’s Stable Repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update the package index
sudo apt update
# Install Docker
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Check if Docker is running
sudo systemctl is-active docker
# Add current user to the Docker group
sudo usermod -aG docker $USER
sudo usermod -aG docker $username
# Check if the script is being run interactively, then change group without needing re-login
if tty -s; then
newgrp docker
fi
echo "Docker installed successfully."
else
echo "Docker is already installed."
fi
echo "Server security enhancement is complete."
echo ""
echo "------------"
echo "Host: $(hostname)"
echo "Username: $username"
echo "Password: $password"
echo "------------"
echo "Public key: $public_key"
echo "------------"
echo "2FA: $(cat /home/"$username"/.google_authenticator)"
echo "------------"
Conclusion
This is a good starting point to secure your Ubuntu server. There are many more things you can do to secure your server, but this should give you a good foundation.