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:
#!/bin/bash
# License: WTFPL
# UPPERCASE space-separated country codes to ACCEPT
ALLOW_COUNTRIES="IN US"
LOGDENY_FACILITY="authpriv.notice"
if [ $# -ne 1 ]; then
echo "Usage: $(basename $0) <IP>"
exit 0 # return true in case of config issue
fi
IP=$1
COUNTRY=$(geoiplookup "$IP" | awk -F ': ' '{print $2}' | awk '{print $1}' | head -n 1)
if [[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]]; then
RESPONSE="ALLOW"
else
RESPONSE="DENY"
fi
if [[ "$RESPONSE" == "ALLOW" ]]; then
logger -p $LOGDENY_FACILITY "ALLOWED sshd connection from $IP ($COUNTRY)"
exit 0
else
logger -p $LOGDENY_FACILITY "DENIED sshd connection from $IP ($COUNTRY)"
exit 1
fi
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
Summary
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.