How to Secure a Linux Server: A Comprehensive Guide to Enhance System Protection

Securing a Linux server involves implementing various measures to protect the system from unauthorized access, malicious attacks, and potential vulnerabilities. Ensuring your system's safety is extremely crucial. Keep it updated, control who can access it, and use strong passwords. Use tools like firewalls and special systems that watch for problems. Turn off things you don't need and check security regularly. This not only keeps your info safe but also makes sure your Linux server stays reliable. Here are some general guidelines to help you secure a Linux server:

Keep the System Updated:

Keep your system and installed software up to date by regularly using the package manager, such as apt for Debian/Ubuntu or yum/dnf for CentOS and Fedora.

Here's a step-by-step guide for keeping a Linux system updated:

  • Debian/Ubuntu-based systems:

    Update Package Lists using the following command:

    apt update

    After updating the package lists, upgrade the installed packages to their latest versions:

    apt upgrade
  • Red Hat/Fedora-based systems:

    Update Package Lists using the following command:

    dnf update

    After updating the package lists, upgrade the installed packages to their latest versions:

    dnf upgrade

Securing SSH with a Non-Standard Port

Changing the default SSH port can be a good security practice to make your server less susceptible to automated attacks targeting the default SSH port(22). Changing the SSH port doesn't make your server immune to attacks but can reduce the number of automated scans.

Here are the steps to change the SSH port on a Linux system:

Update SSH configuration file

Edit the SSH daemon configuration file on your server. The configuration file is located at /etc/ssh/sshd_config

vi /etc/ssh/sshd_config

Find the line that specifies the SSH port. It looks like,

#Port 22

Change the 22 to your desired port number (e.g., 2222) and Make sure you remove the '#' symbol from the beginning of the line to uncomment it.

Save the changes and Exit the text Editor.

Update Firewall rules to allow the new SSH port

Update the firewall rules to permit traffic on the new SSH port. Utilize the IPtable commands if your system uses IPtables, use ufw command If your system uses UFW (Uncomplicated Firewall) and use firewalld if your system uses Firewalld.

  • For IPtables:

    iptables -A INPUT -p tcp --dport 2222 -j ACCEPT 
  • For UFW (Uncomplicated Firewall):

    ufw allow 2222/tcp
  • For firewalld:

    firewall-cmd --zone=public --add-port=2222/tcp --permanent 
    firewall-cmd --reload

Make sure to replace 2222 with the new port number you chose.

After making changes, restart the SSH service. Use the appropriate command based on your operating system.

  • Debian/Ubuntu-based systems:

    systemctl restart ssh
  • Red Hat/Fedora-based systems:

    systemctl restart sshd
Test connecting to the server using the new port

Attempt to connect to the server using the new port to ensure everything is configured correctly.

ssh -p 2222 user@your_server_ip

Replace 2222 with the new port number and your_server_ip with your server's IP address, and Make sure you remove the '#' symbol from the beginning of the line to uncomment it.

Disable root login via SSH:

Disabling direct root login via SSH is a recommended security practice. By restricting root login, it enhances the overall security posture by reducing the exposure of the root account to potential threats and adding an extra layer of defense against unauthorized access.

Create a new user:

Before disabling root user login via SSH, it's crucial to create a sudo user to maintain administrative access and avoid the possibility of locking out of the server.

adduser your_username

Replace your_username with the desired username.

Add the new user to the sudo group:

usermod -aG sudo your_username

After creating the new user and adding them to the sudo group, it's a good practice to log out and log back in to apply the changes.

Now, you can use the new user account to log in via SSH and perform administrative tasks with sudo when needed.

Edit the sshd_config file:

Since you have created a sudo user, you can proceed to disable root login. Here's a step-by-step guide:

Open and edit the sshd_config file to modify SSH configuration settings:

vi /etc/ssh/sshd_config

Find the line containing PermitRootLogin and modify it:

#PermitRootLogin no

It's currently set to 'yes'; Need to change it to 'no', and Make sure you remove the '#' symbol from the beginning of the line to uncomment it.

Save the changes and restart the SSH service based on your operating system for the changes to take effect

  • Debian/Ubuntu-based systems:

    systemctl restart ssh
  • Red Hat/Fedora-based systems:

    systemctl restart sshd

Now, the root user login via SSH is disabled. Ensure that you have tested the new configuration by logging in with the sudo user before closing your current SSH session to avoid being locked out.

Limit the users who can SSH into the server:

SSH is a widely used protocol for secure remote access to servers, and implementing access restrictions is crucial for security purposes. There are several ways to limit SSH access to a server.

SSH Configuration File:

By explicitly specifying the users allowed to access the server via SSH using the AllowUsers directive in the SSH configuration file, you control who can connect remotely. This restriction is an additional access control measure, preventing unauthorized users from attempting to log in. Regularly reviewing and updating the list of allowed users enhances the overall security posture.

Open the sshd_config file:

Edit the SSH daemon configuration file on your server. The configuration file is located at /etc/ssh/sshd_config

sudo vi /etc/ssh/sshd_config

Find the AllowUsers directive and specify the usernames allowed to log in.

sudo AllowUsers username1 username2

Replace the username1 username2 with your actual username which you want to allow for SSH.

Save the changes and restart the SSH service based on your operating system for the changes to take effect

  • Debian/Ubuntu-based systems:

    systemctl restart ssh
  • Red Hat/Fedora-based systems:

    systemctl restart sshd

Use key-based authentication instead of passwords:

Key-based authentication is a more secure method than password-based authentication. It involves using a pair of cryptographic keys, a private key (kept on the user's local machine) and a public key (added to the server's ~/.ssh/authorized_keys file). This eliminates the need to transmit passwords over the network, reducing the risk of password-related attacks such as brute-force attempts.

Implementing key-based authentication involves several steps. You can refer this wiki for more details

Configure your server with Firewall/UFW/Firewalld:

Securing your Linux server involves configuring a firewall to manage incoming and outgoing traffic effectively. Define rules that allow only the necessary ports and services, ensuring that your server remains protected while permitting essential communication. This proactive approach enhances the overall security posture of your Linux system.

Using Uncomplicated Firewall (UFW):

First, check if UFW is installed and its status.

sudo ufw status

If UFW is not currently installed, you can install it based on your operating system using the following commands.

Note: If the UFW in not instlled on your server and there is IPtable already, you can use it to restrict the SSH access. you will find the Iptables configuration in the subsequent section of this wiki.

  • Debian/Ubuntu-based systems:

    sudo apt install ufw
  • Red Hat/Fedora-based systems:

    sudo dnf install ufw
    sudo ufw enable

Set default policies to deny incoming and allow outgoing traffic.

Ensure that the SSH port is allowed to prevent the server from becoming inaccessible.

sudo ufw default deny incoming
sudo ufw default allow outgoing

These commands help create a more restrictive firewall configuration. With these defaults, incoming connections are blocked by default, and outgoing connections are allowed by default. You can then selectively open specific ports or allow traffic for particular services as needed.

However, you have to allow Other Necessary Services as your needed, For example, SSH, HTTP, HTTPS, etc.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
Using iptables:

Confirm whether iptables is installed and check its status.

sudo iptables -L

If iptables is not installed, you can install it based on your operating system using the following commands. install it using the following command:

  • Debian/Ubuntu-based systems:
    sudo apt-get install iptables
  • Red Hat/Fedora-based systems:
    sudo dnf install iptables

Set default policies to deny incoming and allow outgoing traffic.

Ensure that the SSH port is allowed to prevent the server from becoming inaccessible.

sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT

This sets the default policy for incoming traffic to "DROP," which means that by default, all incoming connections will be dropped (blocked) and outgoing traffic to "ACCEPT," which means that by default, all outgoing connections are allowed unless there are specific rules allowing/blocking them.

However, you have to allow Other Necessary Services as your needed, For example, HTTP and HTTPS for a web server

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT  
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Using Firewalld:

First, check if firewalld is installed and its status

sudo firewall-cmd --state

If firewalld is not installed, you can install it based on your operating system using the following commands:

  • Debian/Ubuntu-based systems:

    sudo apt-get install firewalld
  • Red Hat/Fedora-based systems:
    sudo dnf install firewalld

Set default policies to deny incoming and allow outgoing traffic.

Ensure that the SSH port is allowed to prevent the server from becoming inaccessible

sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --reload

This sets the default policy for incoming traffic to "DROP," which means that by default, all incoming connections will be dropped (blocked) and outgoing traffic to "ACCEPT," which means that by default, all outgoing connections are allowed unless there are specific rules allowing/blocking them.

However, you have to allow Other Necessary Services as your needed, For example, HTTP and HTTPS for a web server

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload

Set Up Fail2Ban:

Setting up Fail2Ban is a crucial step in enhancing the security of your Linux server. Fail2Ban is a log-parsing application that monitors system logs for repeated failed login attempts or other suspicious activities. Once detected, Fail2Ban takes preventive actions, such as blocking the IP address of the offending entity, to mitigate potential security threats. This tool is effective in safeguarding your server against brute-force attacks and unauthorized access.

Here's a steps on how to set up Fail2Ban:

Installation:

Python is a prerequisite for Fail2Ban. Fail2Ban is a Python application, and it relies on the Python programming language to execute its functionality.

Most Linux distributions come with Python pre-installed. However, it's essential to ensure that Python is available on your system before installing Fail2Ban. If Python is not present, you may need to install it using your system's package manager.

  • Debian/Ubuntu-based systems:

    sudo apt install python
  • Red Hat/Fedora-based systems:
    sudo dnf install python

    After ensuring that Python is installed, you can proceed with installing and configuring Fail2Ban on your system

Install Fail2Ban using your package manager.

  • Debian/Ubuntu-based systems:

    sudo apt install fail2ban
  • Red Hat/Fedora-based systems:

    sudo dnf install fail2ban
Configuration:

Open the main configuration file for editing (usually /etc/fail2ban/jail.conf or /etc/fail2ban/jail.local).

sudo vi /etc/fail2ban/jail.local

Customize the configuration according to your needs. Important sections include sshd for SSH configuration, Adjust ban time and retry count (The ban time is the duration for which an IP address is blocked, and the retry count is the number of failed login attempts that trigger a ban).

For example,

[sshd]
enabled = true          # Enable the jail for SSH
port = ssh              # Specify the SSH port
filter = sshd           # Use the 'sshd' filter
logpath = /var/log/auth.log  # Set the path to the authentication logs
banaction = iptables-multiport  # Specify the ban action as 'iptables-multiport'
maxretry = 3            # Adjust the number of allowed retries
bantime = 600           # Adjust the ban time in seconds (600 seconds = 10 minutes)

If server uses firewalld instead of iptables, simply comment the banaction line.

This configuration is designed to monitor authentication logs for SSH (/var/log/auth.log), and if it detects three or more failed login attempts within a 10-minute window, it will ban the corresponding IP address using the iptables-multiport ban action.

however, if needed, you can create custom filters for specific services. Filter definitions are usually stored in /etc/fail2ban/filter.d/

Restart Fail2Ban:

After making changes, restart the Fail2Ban service to apply the new configuration.

sudo systemctl restart fail2ban
Check Status:
sudo fail2ban-client status
Testing:

Test Fail2Ban by deliberately triggering failed login attempts. Confirm that the corresponding IP gets banned.

Monitor Log Files:

Regularly monitoring system logs in the directory /var/log/ is crucial for identifying any unusual activities or security incidents on your Linux server.

If you have installed a Fail2ban as per the above mentioned instruction, you can check the logs generated by Fail2Ban in the directory /var/log/fail2ban.log.

By reviewing log files, you can detect suspicious login attempts, unauthorized access, or other potentially malicious activities. Additionally, setting up log rotation is important to manage log file sizes and prevent them from consuming excessive disk space. Log rotation ensures that log files are archived or deleted after reaching a certain size or age, helping to maintain system performance and manage storage resources efficiently.

Use Strong Password Policies:

Implementing strong password policies is essential for enhancing the security of user accounts on your Linux server. By enforcing strong password policies, you significantly enhance the security of user accounts on your Linux server, making it more resilient against password-related attacks.

Here are steps for implementing strong password policies:

Update Password Policy:

Open the /etc/security/pwquality.conf file or create it if it doesn't exist. This file is used to define password quality requirements.

vi nano /etc/security/pwquality.conf

Add or modify parameters based on your requirements.

For example:

minlen = 12        # Minimum password length
minclass = 3       # Minimum character classes (uppercase, lowercase, digits, special characters)
minclassrepeat = 3 # Minimum characters repeated from the previous password
maxrepeat = 3      # Maximum identical consecutive characters
minclassrepeat = 3 # Minimum number of characters in a new password that differ from the old password

By using these strong security steps, you make your Linux server safer and create a strong.