Below, you will find 10 practical ways to secure Ubuntu from hackers and bad actors. The tips in this post are not comprehensive because as you know, anything that is connected to the internet is never 100% secure, but these tips are fundamental best practices for securing your server.
HEY THERE! Don’t feel like reading? Go down to the bottom for a video tutorial!
1. Automatically Install Security Updates
Updates, and more importantly security updates, are released all the time for the packages that you have installed on your system, and because of this, it’s very hard to stay up to date. My recommendation is to automatically install security updates.
You can do this with the unattended-upgrades package which gives you complete control over which type of updates you want to automatically install. A video tutorial is below, and here is a full blog post with instructions and code snippets.
At the very least, I recommend installing security updates. If you have a production server, you can exclude certain packages, specify if a reboot should happen, and if so what time of day would be acceptable.
2. Don’t Use root. Use sudo Instead
As you know, the root user is a very powerful user. It’s for that reason we want to limit the need to even use this user. Instead, it’s a better idea to temporarily elevate your privileges with the sudo command.
You can give a user sudo privileges with the usermod command like this.
usermod -aG sudo someuser
Here’s a complete tutorial on granting sudo privileges in Ubuntu.
Don’t go crazy and give all of your users sudo access. Instead, limit the number of user’s with sudo access to just one user at most.
You can get a list of users in the sudo group with this command, so check just to be sure.
grep -Po '^sudo.+:\K.*$' /etc/group
3. Enforce Password Complexity
Check to see if any of your current users have empty passwords. You can do this by looking at the /etc/shadow file.
cat /etc/shadow | awk -F: '($2==""){print $1}'
After confirming that none of your users are passwordless, install the libpam-pwquality package.
sudo apt-get install libpam-pwquality
Configure the password complexity requirements at /etc/security/pwquality.conf. I suggest adding at least a minimum length requirement of 16 characters.
# Minimum acceptable size for the new password (plus one if # credits are not disabled which is the default). (See pam_cracklib manual.) # Cannot be set to lower value than 6. minlen = 16
With that in place, any newly created user and password changes will have to abide by your complexity requirements.
4. Use SSH Keys, Not Passwords
Speaking of passwords, we don’t want to use a password to login to the server via SSH. Instead of a password, we want to use a key to access the remote server.
To set this up, use the ssh-keygen command to generate a key on your local system like this.
ssh-keygen -t ed25519
Next, copy that key to the server with the ssh-copy-id command.
ssh-copy-id -i ~/.ssh/id_ed25519.pub tony@50.116.22.72
Finally, test it out, and you will be able to login to your remote server without a password.
With that in place, next disable password-based authentication for SSH. To do this, open the ssh config file at /etc/ssh/sshd_config, uncomment the PasswordAuthentication line and change the value to no. Also uncomment the PermitEmptyPasswords line and change this value to no, and set UsePAM to no as well.
# To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes PermitEmptyPasswords no # Change to yes to enable challenge-response passwords (beware issues with # some PAM modules and threads) ChallengeResponseAuthentication no # Kerberos options #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosGetAFSToken no # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes #GSSAPIStrictAcceptorCheck yes #GSSAPIKeyExchange no # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass # the setting of "PermitRootLogin without-password". # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and ChallengeResponseAuthentication to 'no'. UsePAM no
Restart the SSH daemon to apply changes.
systemctl restart sshd
Now, when someone tries to access your server via SSH without a valid public key, they’ll see a permission denied error.
Be careful here because if you lose access to your public key, you lose access to your server because you disabled password logins.
5. Forbid Root Login
Disallowing the root user to login via SSH is also another good Ubuntu security practice.
Similar to before, open the sshd_config file and change PermitRootLogin to no.
#LoginGraceTime 2m PermitRootLogin no #StrictModes yes
Restart the ssh daemon with systemctl restart sshd
for the changes to take effect, and now the root user will not be able to login to the server via SSH.
6. Change the SSH Port
Another SSH security technique is to change the SSH port. The default SSH port is 22, and every hacker knows this.
Open the ssh_config file again, uncomment the port line, and change it from 22 to a random number.
Include /etc/ssh/sshd_config.d/*.conf Port 5823 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress ::
I suggest looking through this wikipedia page of port numbers to find one that’s not used by another application.
As always, restart the SSH daemon to apply changes, and now when someone tries to login to your server with the default port, they’ll get a connection refused error.
For this point forward, you can specify your port with the -p flag and access your server that way.
ssh -p 5823 user@server
7. Disable IPv6
The next tip is to disable IPv6 systemwide (assuming that you’re not using it). By turning off IPv6 completely, this reduces the attack surface of your system.
To turn off IPv6, edit the /etc/sysctl.conf file and add these lines to the end.
# disable ipv6 on the system net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1
Apply the changes with sysctl -p
, and verify that IPv6 has been turned off with cat /proc/sys/net/ipv6/conf/all/disable_ipv6
. A value of 1 means that IPv6 is disabled on your system.
As an extra layer of security, you can also explicitly turn off IPv6 connections for SSH. In your ssh_config file, change the AddressFamily option to inet and restart the sshd server to apply the changes.
Include /etc/ssh/sshd_config.d/*.conf Port 5823 AddressFamily inet #ListenAddress 0.0.0.0 #ListenAddress ::
8. Use a Firewall with Intrusion Prevention Software
A firewall allows you to restrict incoming and outgoing traffic based on a set of rules. Combine this with intrusion prevention software like fail2ban, you can automatically block an IP address after a predetermined number of failed login attempts. This is sometimes referred to as brute force protection.
Here is an entire video on configuring a basic fail2ban setup for SSH.
By default, fail2ban automatically creates these firewall rules in the iptables firewall, but you can also configure fail2ban to use ufw (or Uncomplicated Firewall) instead.
9. Use Basic Authentication
Assuming that you are running a web server, it’s a great idea to add an extra layer of security on top of your admin pages with basic authentication.
While some web applications have their own methods for authentication, it’s never a bad idea to also leverage the server itself to further restrict access.
With basic authentication, the browser will prompt the user for a username and password when they navigate to an area of your website that you have locked down. Without the proper credentials, the user will be prevented from loading the page.
Check out these videos for setting up basic authentication on Apache, Nginx, and OpenLiteSpeed web servers.
10. Remove Unnecessary Packages
There is no need to run an FTP server alongside your web server if you aren’t even using FTP. The same goes for a bunch of other protocols that open up holes into your system.
Assuming you are not using these services, execute this command to remove unnecessary packages that could otherwise give hackers another door into your system.
apt-get purge --auto-remove telnetd ftp vsftpd samba nfs-kernel-server nfs-common