Enhancing VPS Security on Ubuntu and Debian: A Practical Guide
Enhancing VPS Security on Ubuntu and Debian: A Practical Guide
This cheat sheet contains a minimal set of steps to improve the security of your Ubuntu or Debian-based server. These recommendations are especially useful for VPS intended for VPN operation.
🛡️ Basic Security Principles
Server security settings are not the main defense. The main thing is the administrator’s common sense. Here are the basic rules:
-
Do not store your server account password in online password storage (there have been many password leaks) or in a TXT file on your desktop. It is best to keep the password only in your head and periodically update it; in extreme cases, use a paper notebook. You can also use open-source password managers like KeePassXC or Bitwarden, which are relatively safe. If you store passwords in the browser and don’t want to change your habits, be sure to use a master password.
-
Use complex passwords with case sensitivity and special characters.
-
Strengthen the protection of the Email linked to your server’s control panel account as much as possible.
-
Use two-factor authentication for Email and the server administrator’s personal account. It is advisable to use 2FA programs with token-based authentication like Aegis, 2FA, Yandex Key, etc., since SMS can be intercepted by attackers using a clone of your SIM card (a rare case, but it happens). In most cases, I use Aegis.
-
Do not save passwords in FTP clients — viruses often extract information from FTP clients.
-
Do not share the main administrator account credentials with anyone, and if there is a need to grant access, create a new account with limited rights for that purpose. Don’t forget to delete the temporary account afterward.
🔐 Installing an SSH Key: Secure Passwordless Authentication
Using SSH keys is a simple and reliable way to ensure security when connecting to a server. The main advantage of SSH keys over a password is that there is no need to transmit a password over the network each time you authenticate, making server access more secure.
Generating SSH Keys
To set up key-based authentication, you need to generate two files: private and public keys. Here’s how to do it:
-
Enter the following command to generate an RSA key pair:
ssh-keygen -t rsa -b 2048
-
The program will ask for a directory to save the keys and offer to enter a passphrase for additional protection. This password can be left empty, but it’s better to enter a complex passphrase for greater security. If you want to use the default settings, press Enter — the keys will be saved in the
~/.ssh
directory.
Viewing Generated Files
After generating the keys, navigate to the ~/.ssh
directory where they were saved:
cd ~/.ssh
In this directory, you will see two files:
-
id_rsa — this is your private key, which should be stored securely on your local computer and never shared with others.
-
id_rsa.pub — this is the public key, which needs to be transferred to the server.
Copying the Public Key to the Server
To authenticate on the server using the SSH key, transfer the public key to the server. One convenient way to copy the key is to use programs that support SFTP, such as Filezilla, or other SFTP managers.
After copying, open the authorized_keys file on the server to register your public key:
-
Copy the contents of
id_rsa.pub
into theauthorized_keys
file, appending it to the end of the file:cat id_rsa.pub >> ~/.ssh/authorized_keys
This
authorized_keys
file should be located in the~/.ssh
directory on the server.
Configuring OpenSSH for Key-Based Authentication
Now you need to make changes to the OpenSSH configuration on the server to enable key-based authentication:
-
Open the OpenSSH configuration file:
nano /etc/ssh/sshd_config
-
Find or add the following lines to activate key-based authentication and disable undesirable methods:
PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords no
-
To completely disable password authentication, set the
PasswordAuthentication
parameter tono
. This is also done in thesshd_config
file:PasswordAuthentication no
Note: In Ubuntu 24.04, this parameter may be overridden in a separate configuration file
/etc/ssh/sshd_config.d/50-cloud-init.conf
. Make the change there if editingsshd_config
does not work. -
Additionally, for Ubuntu 24.04, you may need to add the following to ensure RSA algorithm support:
PubkeyAcceptedAlgorithms +ssh-rsa
Setting File Permissions for Key Files
Ensure the correct permissions on the SSH directories and files so that only the current user can read them:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Restarting the SSH Server
To apply all changes, restart the SSH server:
systemctl restart ssh
Now the SSH key-based authentication setup is complete! You can securely connect to the server without a password, using only your private key.
🚫 Installing and Configuring Fail2ban
To prevent password brute-force attempts via SSH, use Fail2ban. After incorrect password attempts, Fail2ban will block the IP address from which the password was being guessed. You can define the number of allowed password attempts and the duration of the block yourself. For example, you can set up a one-hour block after five failed SSH login attempts.
Installing Fail2ban on Ubuntu
apt update -y && apt upgrade -y
apt-get install fail2ban
To start the Fail2ban service, enter the following commands (for reference, since Fail2ban should start automatically):
systemctl enable fail2ban
systemctl start fail2ban
To check the operational status of the Fail2ban service:
systemctl status fail2ban
Basics of Configuring Fail2ban: Understanding Configuration and Key Parameters
Fail2ban is a tool that protects your server from attacks by blocking IP addresses that too frequently make unsuccessful access attempts. This is especially useful for protecting SSH, FTP, HTTP, and other services. Fail2ban configuration is universal and does not depend on a specific Linux distribution.
Fail2ban Configuration Files
All Fail2ban configuration files are located in the /etc/fail2ban
directory. The main configuration file is jail.conf
. However, it is not recommended to modify it directly: when Fail2ban is updated, this file may be overwritten, and the changes you made will be lost.
For safe configuration changes, you should use additional files located in /etc/fail2ban/jail.d
. They allow you to add and modify parameters for specific services, while the main settings remain unchanged. These files use sections called jails — each rule is responsible for protecting a specific service, such as SSH, HTTP, or FTP.
Example of a simple enabling of protection for SSH:
[sshd]
enabled = true
Main Fail2ban Configuration Parameters
When configuring Fail2ban, the following parameters are important, which can be set for each jail in the configuration file:
-
ignoreip
— a list of IP addresses that should never be blocked by Fail2ban, regardless of their activity. This allows you to add your own IP address to avoid accidental blocking. You can also specify a subnet or DNS name.ignoreip = 192.168.1.1 10.0.0.0/24 mytrustedhost.com
-
bantime
— the duration of the IP address block in seconds. Once this time expires, the address will automatically be removed from the blocked list.bantime = 3600 # Block for 1 hour
-
maxretry
— the number of unsuccessful access attempts before blocking. This parameter defines how many times a user can incorrectly enter a password or perform other suspicious actions before the IP is blocked.maxretry = 3
-
port
— specifies on which port or ports the protected service operates. You can specify one or multiple ports.port = ssh
-
filter
— the name of the filter that Fail2ban will use to detect suspicious activity. Each filter searches for certain patterns in log files. For example, for SSH, thesshd
filter is used, which is located at/etc/fail2ban/filter.d/sshd.conf
.filter = sshd
-
logpath
— the path to the log file where Fail2ban will monitor events. Typically, for SSH, this is/var/log/auth.log
.logpath = /var/log/auth.log
-
action
— actions that are performed when Fail2ban detects activity matching the search criteria. For example, the action may include blocking the IP using iptables.action = %(action_)s
Fail2ban Configuration Files Reading Order
Fail2ban reads configuration files in a certain order. .local
files have priority over .conf
, which makes it easy to override settings without changing the original files. The file reading order:
-
/etc/fail2ban/jail.conf
— default base settings. -
/etc/fail2ban/jail.d/*.conf
— settings added by the administrator for additional services. -
/etc/fail2ban/jail.local
— user-defined settings. -
/etc/fail2ban/jail.d/*.local
— administrator settings that have the highest priority.
Additional Fail2ban Configuration Files
In addition to jail.conf
, Fail2ban uses other files for management and configuration:
-
action.d/*.*
— defines what actions will be performed when suspicious activity is detected. -
fail2ban.conf
— the main configuration file for general settings. -
fail2ban.d/*.*
— user settings for Fail2ban. -
filter.d/*.*
— patterns for detecting suspicious actions in logs. -
paths-arch.conf
,paths-common.conf
,paths-debian.conf
,paths-opensuse.conf
— files for defining paths depending on the operating system.
Using these files and parameters, you can finely tune protection for various services, minimizing the risk of hacking and increasing the security of your server.
Configuring Fail2ban for SSH
Source: https://homehosted.ru/ustanovka-i-nastrojka-fail2ban
The SSH jail works in Fail2Ban by default immediately after the service is installed. But if you need to make changes to its operation, you need to create a new jail file. To do this, we will use the nano editor:
nano /etc/fail2ban/jail.d/ssh.conf
Add the following lines to the created file:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
backend = systemd
sshd
— name for the rule;
enabled
allows you to quickly enable (true) or disable (false) the rule;
port
— target service port. Accepts a name or numerical designation;
filter
— the filter (search criterion) that will be used to search for suspicious actions. Essentially, this is the name of a file from the /etc/fail2ban/filter.d
directory without the .conf
at the end;
logpath
— the location of the log file where the filter will look for suspicious activity based on the described criteria;
maxretry
— the number of actions allowed before a ban;
findtime
— the time in seconds during which maxretry
is counted.
To apply the changes, restart the service:
systemctl restart fail2ban
The configuration we specified will block IP addresses after 3 failed login attempts to your server via SSH. The block lasts for 300 seconds, and all suspicious actions will be logged in the /var/log/auth.log
file.
You can adjust the parameters to suit your needs.
🔄 Changing the Default SSH Port on Ubuntu and Debian
By default, the SSH server listens for incoming connections on TCP port 22. This port is well-known, and attackers often target it with brute-force attempts. Changing the port reduces the risk of such attacks, making your server less visible to automated scanners.
📌 How to Change the SSH Port
-
Connect to the Server
Connect to your server via SSH, using, for example, PuTTY (on Windows) or standard SSH commands on macOS and Linux. -
Install Required Utilities
Ensure thatnet-tools
is installed on your server to check available ports:sudo apt install net-tools
-
Check Open Ports
Identify which ports are currently in use on the server to select a free one for SSH:sudo ss -tuln | grep LISTEN
-
Change the Port in the SSH Configuration
For most versions of Ubuntu and Debian, open thesshd_config
file and make the necessary changes:sudo nano /etc/ssh/sshd_config
Locate the line
#Port 22
, remove#
, and replace22
with your chosen port, for example:Port 2222
Save the file and restart SSH:
sudo systemctl restart ssh
-
Adjust Firewall Settings
Ensure that the new port is open in your firewall (if using UFW):sudo ufw allow 2222/tcp
If you are using
iptables
, add a rule for the new port:sudo iptables -I INPUT -p tcp --dport 2222 -j ACCEPT
-
Test the Connection
Now the SSH server will accept connections on the new port. Connect using the new port to verify access, and finalize the setup.
Additional Steps for Ubuntu 24.04
On Ubuntu 24.04, changing the port requires modifications in two locations: the main sshd_config
file and the SSH socket configuration file.
-
Change the Port in
sshd_config
Open the main configuration file:sudo nano /etc/ssh/sshd_config
Locate the line
#Port 22
, remove#
, and specify the new port, for example:Port 2222
-
Change the Port in the Socket Configuration
Open the SSH socket configuration file:sudo nano /lib/systemd/system/ssh.socket
Find the
ListenStream=22
parameter and replace it with your new port:ListenStream=2222
-
Save and Restart
Save your changes and reload the configuration:sudo systemctl daemon-reload sudo systemctl restart ssh.socket sudo systemctl restart ssh
For Ubuntu 24.04, remember to configure the firewall as well!
Connecting to the Server via the New Port
Now, to connect to the server via SSH, use the specified port. For example, to connect through the terminal, you can specify the port using the -p
flag:
ssh -p 2222 username@server_ip
⚠️ Important: Don’t forget to record the new port and update the firewall settings to avoid losing access to the server.
Automation Script:
For everyone who has read up to this point, a bonus.
An automation script to change the SSH port:
bash <(wget -qO- https://dignezzz.github.io/server/ssh-port.sh)
After running the script, you will be prompted to enter the new port, and the script will change everything by itself. It will even add the corresponding entry in UFW/iptables.
🔥 Configuring UFW Firewall Rules to Protect the Server
Using Uncomplicated Firewall (UFW) is a convenient way to set up server protection. UFW is a front-end for iptables
that greatly simplifies firewall rule management.
🔥 Essential UFW Commands and Configuration for Server Security
Uncomplicated Firewall (UFW) is a convenient tool for managing firewall rules on Ubuntu and Debian. It allows you to easily configure and control access to your server, providing a robust defense against unauthorized access. Here are the main commands and explanations for working with UFW.
Installing UFW
If UFW is not yet installed, you can set it up with the following command:
sudo apt install ufw
Enabling and Disabling UFW
Before enabling UFW, it’s essential to set up access rules, especially if your server is accessed via SSH. You can enable UFW with the command:
sudo ufw enable
To temporarily disable UFW (e.g., for testing purposes), use:
sudo ufw disable
Warning: Disabling UFW temporarily removes all restrictions, so proceed with caution.
Checking UFW Status and Rules
To check the status of UFW and view all active rules, use:
sudo ufw status verbose
This command will display which ports are allowed or denied, along with other configurations.
Setting Default Rules
UFW allows setting default rules for incoming and outgoing traffic. It is recommended to deny all incoming connections (except those you explicitly allow) and to allow all outgoing connections:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allowing and Denying Ports
To open a port for a specific service, such as SSH, you can use:
sudo ufw allow 22/tcp
Note: If you have changed the SSH port, replace
22
with the desired port number. For example,sudo ufw allow 2222/tcp
.
For a web server, you might need the following commands to allow HTTP and HTTPS:
sudo ufw allow 80/tcp # Open port for HTTP
sudo ufw allow 443/tcp # Open port for HTTPS
To block access to a port, use:
sudo ufw deny 25/tcp
This, for instance, blocks port 25
, commonly used for mail services (SMTP).
Allowing Access by IP Address
Sometimes, it’s necessary to allow server access only from a specific IP address. For this, use:
sudo ufw allow from 192.168.1.100
This allows access from IP 192.168.1.100
to all services. You can also specify a specific port by adding to any port 22
:
sudo ufw allow from 192.168.1.100 to any port 22
Deleting Rules
To remove a previously set rule, use the same command with the delete
flag. For example, to remove access to port 22:
sudo ufw delete allow 22/tcp
Limiting Connections
To prevent brute-force attacks on specific services, UFW allows you to limit connection attempts. For example, to limit SSH connections, use:
sudo ufw limit 22/tcp
This command allows up to 6 connection attempts in 30 seconds from a single IP. If the limit is exceeded, the IP is temporarily blocked.
Reloading UFW
If you want to restart UFW and apply all new rules, use:
sudo ufw reload
Resetting UFW Settings
If you need to reset all UFW settings and start fresh, run:
sudo ufw reset
Important: This command removes all current rules, so use it with caution.
Now UFW is configured and active, blocking all unnecessary incoming connections and opening only the necessary ports.
Enhanced SSH Security and Hardening - SSH-Audit
There is a well-established site: https://www.ssh-audit.com/
What can it help you do?
- It allows you to test the security of your SSH connection based on a strict security policy.
- On the site, you will find all the essential and critical steps to configure your server.
For a complete set of security commands, refer to this page: https://www.ssh-audit.com/hardening_guides.html
Let’s walk through an example for Ubuntu 24.04:
1. Regenerating RSA and ED25519 Keys
-
Remove existing SSH keys:
rm /etc/ssh/ssh_host_*
Description: This command deletes all existing SSH keys in
/etc/ssh/
to ensure a clean start for generating new keys. -
Generate a new RSA key:
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
Description: Creates a new RSA key with a length of 4096 bits, stored at
/etc/ssh/ssh_host_rsa_key
. The-N ""
parameter sets an empty passphrase. -
Generate a new ED25519 key:
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
Description: Creates a new ED25519 key stored at
/etc/ssh/ssh_host_ed25519_key
. ED25519 keys offer a faster and more secure alternative to RSA.
2. Removing Weak Diffie-Hellman Groups
Small Diffie-Hellman groups are sets of numbers used for secure key exchanges in the Diffie-Hellman algorithm. Groups with inadequate length pose a security risk.
What is a Diffie-Hellman Group?
Diffie-Hellman (DH) is a method for secure cryptographic key exchange, enabling two parties to establish a shared secret key over an unsecured connection. It relies on complex mathematical operations with very large numbers, known as Diffie-Hellman groups.
Why Are Small Groups Insecure?
Larger groups are more resistant to brute-force attacks. Small groups (less than 3072 bits) are vulnerable, as they can be cracked more easily with modern computational power.
How This Affects Security
Using small groups increases the risk of attack. To mitigate this, filter out groups smaller than 3072 bits.
Command Context
awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe
Description: This command uses awk
to filter out Diffie-Hellman groups with sizes below 3072 bits, saving the secure groups in /etc/ssh/moduli.safe
.
mv /etc/ssh/moduli.safe /etc/ssh/moduli
Description: Moves the filtered, secure groups back to /etc/ssh/moduli
.
3. Enabling RSA and ED25519 Keys
- Enable HostKey directives for RSA and ED25519:
Description: Usessed -i 's/^\#HostKey \/etc\/ssh\/ssh_host_\(rsa\|ed25519\)_key$/HostKey \/etc\/ssh\/ssh_host_\1_key/g' /etc/ssh/sshd_config
sed
to edit the SSH configuration file, uncommenting lines associated with HostKey for RSA and ED25519 keys, allowing OpenSSH to use these keys.
4. Restricting Supported Algorithms
- Add strict restrictions for key exchange, cipher, and MAC algorithms:
Description: Creates a new fileecho -e "\n# Restrict key exchange, cipher, and MAC algorithms, as per sshaudit.com\n# hardening guide.\nKexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256\nCiphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr\nMACs [email protected],[email protected],[email protected]\nHostKeyAlgorithms ssh-ed25519,[email protected],[email protected],[email protected],rsa-sha2-256,rsa-sha2-512,[email protected],[email protected]" > /etc/ssh/sshd_config.d/ssh-audit_hardening.conf
/etc/ssh/sshd_config.d/ssh-audit_hardening.conf
, setting restrictions on supported key exchange, cipher, and MAC algorithms to enhance security.
5. Restarting the SSH Server
- Restart the OpenSSH service:
Description: Restarts the SSH server to apply all changes.service ssh restart
6. Implementing Connection Rate Limits
-
Enable connection rate limiting with iptables for IPv4:
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
Description: Configures iptables to limit incoming connections on port 22 (SSH), allowing only 10 new connections within 10 seconds from a single source, protecting against DDoS attacks on SSH.
-
Apply the same limit for IPv6:
ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
Description: A similar setup for IPv6 to ensure consistent protection.
7. Persisting iptables Rules After Reboot
-
Install
netfilter-persistent
andiptables-persistent
:DEBIAN_FRONTEND=noninteractive apt install -q -y netfilter-persistent iptables-persistent
Description: Installs utilities to save and restore iptables rules on system reboot.
-
Save iptables rules:
service netfilter-persistent save
Description: Saves current iptables rules to apply them automatically after reboot.
Conclusion
Implementing the commands outlined at https://www.ssh-audit.com/hardening_guides.html is highly recommended for all production servers. Rest assured, these steps will enhance security without breaking functionality.
📌 Conclusion
By following these recommendations, you will significantly enhance the security of your VPS. These steps will protect the server from most attacks and help maintain a high level of security.
Follow my TG channel: https://t.me/neonode_cc
TG group for discussion: https://t.me/+cFdHT8DiMUA2MWVi
- Our community Openode.XYZ OpeNode.xyz
- Aeza VPS (+15% on payment) Aeza.net
- Best EU hosting (+1 month free) Kamatera.com
- VPS hosting - 4vps.su (-10% discount!) 4VPS.su
- TG Channel TG-Channel Neonode.cc