15 min.

Secure Linux Server

First steps

Essential Initial Security Measures for Linux Servers to Counter Common Threats

Securing a Linux server is crucial to protect it from unauthorized access, regardless of the distribution. This guide will help you secure your server efficiently. Execute all commands with administrative privileges, typically by prefixing sudo to your commands.



System Update


Keep your system updated to ensure you have the latest security patches:



sudo apt update
sudo apt upgrade



Creating a Non-Root User


Create a user with sudo privileges to avoid using the root account directly. This is also a step towards disabling root SSH logins:



sudo adduser new_user_name
sudo usermod -aG sudo new_user_name



System Safety Check with Rkhunter


Before proceeding, ensure your system is free from rootkits and backdoors using Rkhunter:



sudo apt install rkhunter
sudo rkhunter --check



Follow the prompts and address any issues found.



SSH Keys Generation


Generate a unique SSH key for each server from your local machine and send them to those servers:



ssh-keygen -t rsa -b 4096
ssh-copy-id user@server



To use a specific key for SSH login:



ssh -i ~/.ssh/specific_ssh_key user@server



SSH Configuration


To improve your server's security, edit the SSH configuration file:



sudo nano /etc/ssh/sshd_config



The configuration adjustments below are recommended for enhancing security without overly restricting access, ensuring a balance that suits most systems.


Tip: Look for an SSH cheat sheet for additional tips and best practices.


Change the Default SSH Port


Changing the default port (22) is a critical step to avoid automated attacks. If unsure which ports are available, consult /etc/services to choose an unassigned port, preferably from the private/dynamic range (49152-65535).



Port 49152



Disable Root Login


Prevent the root user from logging in via SSH for added security. Use a non-root user with sudo privileges instead.


PermitRootLogin no



Restrict SSH Access to Specific Users


Limit SSH access to specific users to reduce the attack surface.



AllowUsers new_user_name



Enable Public Key Authentication


Ensure that SSH logins are only permitted through public key authentication.



PubkeyAuthentication yes
PasswordAuthentication no



Disable Password and Interactive Authentication


Turning off password-based and interactive authentication methods enhances security by relying solely on key-based authentication.



ChallengeResponseAuthentication no



Disable Host-Based Authentication


Host-based authentication is considered insecure and should be disabled.



HostbasedAuthentication no
RhostsAuthentication no
IgnoreRhosts yes



Configure Connection Attempts


Adjust MaxStartups and MaxAuthTries to limit concurrent connections and authentication attempts, reducing the risk of brute-force attacks.



MaxStartups 5:50:30 #limits the rate of new connections.
MaxAuthTries 1 sets #the maximum number of authentication attempts to one.



Limit SSH Sessions


Reduce the number of sessions allowed per connection to one, mitigating the risk of session hijacking.



MaxSessions 1



Disable TCP and X11 Forwarding


For servers not requiring these features, disable TCP and X11 forwarding to prevent tunneling and GUI display forwarding.



AllowTcpForwarding no
X11Forwarding no



After making these changes, restart the SSH service to apply them:



sudo systemctl restart sshd



Firewall Secure Configuration


After securing the SSH service by changing its default port and making other recommended adjustments, follow these steps to configure the firewall for improved security.



Restart the SSH Service


Before modifying the firewall settings, ensure that the SSH service is restarted to apply any changes made to its configuration. Use the appropriate command based on your distribution:



sudo systemctl restart sshd



or, if your system uses a different service management:



sudo service ssh restart



Verify SSH is Running on the New Port


Ensure you're connected through the new SSH port (not the default port 22). To confirm the active SSH port, use:



sudo lsof -i -n -P | grep sshd



Enable the Firewall


If not already enabled, activate UFW (Uncomplicated Firewall) with the following command:



sudo ufw enable



Configure Firewall Rules


Allow connections on the new SSH port and deny the default port to minimize the risk of unauthorized access.

Replace new_ssh_port with the actual port number you've configured SSH to use:



sudo ufw allow new_ssh_port
sudo ufw deny 22



Restrict SSH Access by IP (Optional)


If you have a static IP address from your ISP, you can further secure your server by allowing SSH connections only from your IP address. Replace xxx.xx.xxx.x with your actual IP address and new_ssh_port with your SSH port:



sudo ufw allow from xxx.xx.xxx.x to any port new_ssh_port



Restart the Firewall


Apply all changes by restarting the firewall. This step may vary depending on your system, but generally, you can use:



sudo ufw reload



or if your system uses a different command to manage the firewall:



sudo service ufw restart



Fail2Ban Secure Configuration


Installing and configuring Fail2Ban can significantly enhance your server's security by preventing brute force attacks. Follow these steps to install Fail2Ban and configure it:


Install Fail2Ban



sudo apt install fail2ban



Start and Enable Fail2Ban Service:



sudo systemctl start fail2ban
sudo systemctl enable fail2ban



Fail2Ban works by monitoring log files for suspicious activity and banning IPs that show malicious signs. It's particularly effective against repeated login attempts.



Allow Access Based on Geographic Location


To implement GeoIP-based filtering, you'll first need to install GeoIP tools:



sudo apt install geoip-bin geoip-database



Next, create a script to filter incoming connections based on country codes. This script uses GeoIP to allow or deny SSH connections from specific countries.



Create the GeoIP Filter Script


Save the following script as /usr/local/bin/ipfilter.sh, adjusting the ALLOW_COUNTRIES variable as needed:



# License: WTFPL
# UPPERCASE space-separated country codes to ACCEPT
if [ $# -ne 1 ]; then
 echo "Usage: $(basename $0) <IP>"
 exit 0 # return true in case of config issue
COUNTRY=$(geoiplookup "$IP" | awk -F ': ' '{print $2}' | awk '{print $1}' | head -n 1)
if [[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]]; then
if [[ "$RESPONSE" == "ALLOW" ]]; then
 logger -p $LOGDENY_FACILITY "ALLOWED sshd connection from $IP ($COUNTRY)"
 exit 0
 logger -p $LOGDENY_FACILITY "DENIED sshd connection from $IP ($COUNTRY)"
 exit 1



Make the Script Executable



sudo chmod +x /usr/local/bin/ipfilter.sh



Configure SSH to Use the GeoIP Filter


To use this script with SSH, integrate it with your system's TCP Wrappers setup by editing /etc/hosts.allow and /etc/hosts.deny.


In /etc/hosts.allow, add:



sshd: ALL: spawn /usr/local/bin/ipfilter.sh %a



In /etc/hosts.deny, block all other IPs for SSH:



sshd: ALL





Following these recommendations will enhance your server's security posture significantly. Beyond these steps, consider adopting more stringent configurations as needed and regularly review security logs and updates.


Consider leveraging cloud environments that offer fully managed VM servers, such as Amazon EC2, which provide modern and more secure methods of access beyond traditional SSH. 


These platforms utilize robust IAM (Identity and Access Management) policies for authentication, offering options to connect without SSH. This approach enhances security by eliminating the need to manage SSH keys and ensuring precise user login tracking, complete with comprehensive history and logs. Explore connecting to AWS EC2 instances without SSH keys for a more secure and manageable solution.