How to secure your Ubuntu Server installation
Learn how to secure your Ubuntu server installation with this practical guide, covering essential steps such as updating the system, configuring the firewall, and installing security tools.
Are you a developer who needs to set up a server from scratch to host your applications? It can be time-consuming to keep up with best practices for server configuration while focusing on coding. Additionally, any server could be vulnerable to breaches if left unattended or misconfigured. In this post, I have curated a list of steps you can take to harden your Ubuntu Server installation, which can also apply to other distributions.
Update the server
The first and most crucial step is to update the apt package index, upgrade outdated packages, and install the latest security patches:
# apt update && apt upgrade -y
Keep your server Up-To-Date
New vulnerabilities are periodically discovered in certain packages installed on your server, so it is essential to update them to the newest version and install security patches. This process can be automated by enabling automatic updates.
Let's install and configure unattended-upgrades:
# apt install unattended-upgrades
# dpkg-reconfigure --priority=low unattended-upgrades
Remove Unnecessary Packages
To keep an Ubuntu server secure, it's important to get rid of any packages that aren't needed. Having too many packages can make it easier for hackers to break in. By removing these packages, you can lower the risk of a security breach and reduce the chances of an attack being successful.
Apart from making the server more secure, removing unnecessary packages can also make it easier to maintain and update security patches. This is because with fewer packages to manage, it becomes easier to keep the server secure. Having too many packages can take up important resources like disk space and RAM, which could be used for more important services. Therefore, it's a good idea to regularly review the installed packages and remove any that are not required. You can do this using the apt package manager on Ubuntu.
Here's an example command to remove unnecessary packages using apt on Ubuntu:
# apt autoremove
This command will remove any packages that were automatically installed as dependencies but are no longer required by any other installed packages. It is a safe way to clean up the system and remove any unnecessary packages. However, it is important to review the list of packages to be removed before proceeding, as there may be some packages that you want to keep. You can preview the packages that will be removed by running the command apt autoremove --dry-run
. If you want to remove specific packages, you can use this command.
# apt remove [package-name]
Create a non-root user
Creating a non-root user can significantly improve the security of an Ubuntu server. By default, the root user has full administrative privileges, which means that any process or command executed as root has complete control over the system. This can be dangerous if a malicious actor gains access to the root account, as they could potentially compromise the entire system.
By creating a non-root user, you can control who can access the system and what they can do. Non-root users have restricted privileges, so they can only do what they're allowed to do. This helps prevent unintentional or harmful damage to the system and reduces the damage caused by a successful attack.
It is also a good security practice to disable direct root login and use sudo
instead. This means that users must log in with their non-root account and then use the sudo
command to execute privileged commands. This provides an extra layer of security and accountability, as it is easier to track who performed a privileged action when using sudo
.
To create a new non-root user in Ubuntu, you can use the adduser
command with sudo privileges. For example, the command adduser newuser
will create a new user named "newuser". You can then grant this user permissions as needed using the sudo
command.
# adduser newuser
# usermod -aG sudo newuser
Use Strong Passwords
Using strong passwords is essential for securing an Ubuntu server. A password is the first line of defense against unauthorized access to a system, and a weak or easily guessable password can make it trivial for an attacker to gain access to the system.
A strong password is one that is long, complex, and contains a mixture of uppercase and lowercase letters, numbers, and symbols. The longer and more complex the password, the harder it is to crack using brute force methods. It is also important to use unique passwords for each account and to change passwords regularly.
There is a simple technique that can produce a secure password and function on any distro, among the numerous other approaches available. The generated password is a string of 24 characters, consisting of uppercase letters, lowercase letters, and numbers.
# tr -cd A-Za-z0-9 < /dev/urandom | head -c 24; echo '';
Secure SSH
Securing SSH is an important aspect of securing an Ubuntu server, as SSH is a common method used for remote access to a system. By default, SSH is already secured with encryption and authentication mechanisms, but there are additional steps that can be taken to further enhance its security.
One recommended step is to change the default SSH port number from 22 to a custom port. This can help prevent automated attacks that scan for systems with SSH listening on the default port.
Another important step is to disable root login over SSH. This means that users must log in with their non-root account and then use sudo
or a similar tool to execute privileged commands. This provides an extra layer of security and accountability, as it is easier to track who performed a privileged action when using sudo
.
To make these changes, edit the /etc/ssh/sshd_config
file by modifying these directives:
# This is the sshd server system-wide configuration file. See sshd_config(5) for more information.
...
Port 22
.
# rest of configuration
.
PermitRootLogin no
...
It is also important to use key-based authentication instead of password-based authentication for SSH. Key-based authentication is more secure than passwords, as it requires a private key to be present on the client machine in addition to a passphrase. This makes it much harder for an attacker to gain unauthorized access to the system.
Creating the Key Pair
To start the process of creating a key pair on the client machine (usually your computer), use the following command:
$ ssh-keygen
After entering the command, you will see the following output:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
You can choose to save the key pair into the .ssh/ subdirectory in your home directory by pressing enter, or specify an alternate path.
At this point, you have the option to enter a secure passphrase, which is highly recommended. By doing so, you add an extra layer of security to prevent unauthorized access to your account.
Enter passphrase (empty for no passphrase):
Upon completing this step, you will see an output similar to the following:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:zsnJfaLcZ7cw42X9RbUyoKM6Ugzo6U7+6tr53wz5Ia8 user@host
The key's randomart image is:
+---[RSA 3072]----+
| .+..o=.. |
| . =+.= |
| o +. +. |
| o o o . |
| + * S |
| o.=.o.o |
| E + +. . |
| .o . |
| ..+ |
+----[SHA256]-----+
Note that the randomart image is a visual representation of the SSH key's fingerprint, which can help you easily verify the key's authenticity.
Copying the Public Key to Your Ubuntu Server
One efficient method to transfer your public key to the Ubuntu Server is by utilizing a tool called ssh-copy-id, which is often pre-installed on various operating systems, including yours.
To utilize this tool, you must specify the remote host you wish to establish a connection with and the user account that you have password-based SSH access to. Your public SSH key will then be automatically copied to this account.
$ ssh-copy-id -p [Your_Custom_SSH_Port] username@remote_host
you will be prompted to enter the password for the remote user's account.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user@remote_host's password:
Type in the password and press Enter. now the contents of your ~/.ssh/id_rsa.pub key will be transferred to a file named authorized_keys, which is located in the remote account's home ~/.ssh directory. An output resembling this one should appear:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'user@remote_host'"
and check to make sure that only the key(s) you wanted were added.
Disabling Password Authentication on Your Server
Once you have generated and copied your SSH key to the server, you can disable password authentication to further enhance the security of your system.
To turn off password authentication on an Ubuntu Server, you must modify the /etc/ssh/sshd_config
file as mentioned previously. Locate the line that says PasswordAuthentication yes
and change it to PasswordAuthentication no
. Save the file and exit. Now it's time to restart the SSH service to activate the changes.
# systemctl restart sshd
Set up a Firewall
To set up a firewall, we will use "UFW," which stands for "Uncomplicated Firewall." It is a simplified firewall management tool built upon iptables and is less complex than nftables or iptables.
apt install ufw
.Setting up default policies
To get started, we should define default policies that control how to handle traffic that does not explicitly match specific rules. By default, UFW denies all incoming connections and allows all outgoing connections. This means that after enabling the firewall, no one can connect to your server, but any application within your server can reach the outside world.
Let's set the rules back to the defaults using these commands:
# ufw default deny incoming
# ufw default allow outgoing
These firewall defaults might work well for a personal computer, but servers typically need to respond to incoming requests from outside users. First, the firewall should allow SSH connections, so you can connect to and manage your server remotely.
Allow SSH connections
To allow SSH connections, use this command:
# ufw allow ssh
UFW knows what port the SSH service is listening on since it is listed in the /etc/services
file. However, you can rewrite the rule by specifying the port number instead of the service name. For example, if your SSH server is listening on port 2345, you can use this command:
# ufw allow 2345
Now that your firewall allows incoming SSH connections, we can move forward and enable it:
# ufw enable
You will receive a warning message saying that the command may disrupt existing SSH connections. Respond with "y" and hit ENTER. The firewall is now active, and you can use the ufw status numbered
command to see the rules that are set:
Status: active
To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
Notice the [1]
written next to the rule. it's the "rule number" which you can use to further delete or modify a specific rule.
Enabling Access to Other Services
You can configure new rules on your server based on the services you are running. For instance, if you want to host a website using a web server like Apache or Nginx, you need to allow incoming connections to the TCP port 80 (and the TCP port 443 for HTTPS) on your server:
# ufw allow 80/tcp
# ufw allow 443/tcp
Alternatively, you can use these commands to allow HTTP and HTTPS traffic respectively:
# ufw allow http
# ufw allow https
Deleting Rules
As important as it is to add rules to your firewall, it's also crucial to know how to delete them. There are two ways to delete rules: by their rule number or by the actual rule.
By Rule Number:
To delete a rule by rule number in ufw on Ubuntu, you can use the following command:
# ufw delete [rule_number]
Replace [rule_number]
with the number of the rule you want to delete. For example, if you want to delete the rule number 3, you would use the command:
# ufw delete 3
By Actual Rule:
To delete a rule by actual rule in UFW on Ubuntu, you can use the following command:
# ufw delete [rule]
Replace [rule]
with the actual rule you want to delete. For example, if you want to delete the rule that allows traffic from IP address 192.168.0.2 to port 22, you would use the command:
# ufw delete allow from 192.168.0.2 to any port 22
This command will delete the rule that matches that specific criterion.
Conclusion
In this article, we reviewed how to harden the security of your Ubuntu server by examining its configuration and implementing protective measures. It's important to note that there's no absolute security in the IT world, but by applying the tips outlined in this article, you can reduce the attack surface of your server.
Make sure to consult the documentation of every service or package installed on your server to ensure proper configuration. Stay informed about the latest security best practices and keep your knowledge up to date. Remember, knowledge is power!