Hardening New Ubuntu 20.04 Server
Step 1 — Logging in as root
To log into your server, you will need to know your server’s public IP address. You will also need the password or — if you installed an SSH key for authentication — the private key for the root user’s account.
If you are not already connected to your server, log in now as the root user using the following command (substitute the highlighted portion of the command with your server’s public IP address):
Accept the warning about host authenticity if it appears. If you are using password authentication, provide your root password to log in. If you are using an SSH key that is passphrase protected, you may be prompted to enter the passphrase the first time you use the key each session. If this is your first time logging into the server with a password, you may also be prompted to change the root password.
Step 2 — Creating a New User
Once you are logged in as root, we’re prepared to add the new user account. In the future, we’ll log in with this new account instead of root.
This example creates a new user called sammy, but you should replace that with a username that you like:
You will be asked a few questions, starting with the account password.
Enter a strong password and, optionally, fill in any of the
additional information if you would like. This is not required and you
can just hit ENTER
in any field you wish to skip.
Step 3 — Granting Administrative Privileges
Now, we have a new user account with regular account privileges. However, we may sometimes need to do administrative tasks.
To avoid having to log out of our normal user and log back in as the root account, we can set up what is known as superuser or root
privileges for our normal account. This will allow our normal user to
run commands with administrative privileges by putting the word sudo
before each command.
To add these privileges to our new user, we need to add the user to the sudo group. By default, on Ubuntu 20.04, users who are members of the sudo group are allowed to use the sudo
command.
As root, run this command to add your new user to the sudo group (substitute the highlighted username with your new user):
Now, when logged in as your regular user, you can type sudo
before commands to perform actions with superuser privileges.
Step 4 — Setting Up a Basic Firewall
Ubuntu 20.04 servers can use the UFW firewall to make sure only connections to certain services are allowed. We can set up a basic firewall very easily using this application.
You can activate or enable UFW firewall using the following command, which should load the firewall and enables it to start on boot.
$ sudo ufw enable
To disable UFW firewall, use the following command, which unloads the firewall and disables it from starting on boot.
$ sudo ufw disable
Applications can register their profiles with UFW upon installation. These profiles allow UFW to manage these applications by name. OpenSSH, the service allowing us to connect to our server now, has a profile registered with UFW.
You can see this by typing:
OutputAvailable applications:
OpenSSH
We need to make sure that the firewall allows SSH connections so that we can log back in next time. We can allow these connections by typing:
Afterwards, we can enable the firewall by typing:
Type y
and press ENTER
to proceed. You can see that SSH connections are still allowed by typing:
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Step 5 — Hardening SSH
The first step is to create a key pair on the client machine (usually your computer):
By default recent versions of
ssh-keygen
will create a 3072-bit RSA key pair, which is secure enough for most use cases (you may optionally pass in the-b 4096
flag to create a larger 4096-bit key).After entering the command, you should see the following output:
OutputGenerating public/private rsa key pair. Enter file in which to save the key (/your_home/.ssh/id_rsa):Press enter to save the key pair into the
.ssh/
subdirectory in your home directory, or specify an alternate path.If you had previously generated an SSH key pair, you may see the following prompt:
Output/home/your_home/.ssh/id_rsa already exists. Overwrite (y/n)?If you choose to overwrite the key on disk, you will not be able to authenticate using the previous key anymore. Be very careful when selecting yes, as this is a destructive process that cannot be reversed.
You should then see the following prompt:
OutputEnter passphrase (empty for no passphrase):Here you optionally may enter a secure passphrase, which is highly recommended. A passphrase adds an additional layer of security to prevent unauthorized users from logging in. To learn more about security, consult our tutorial on How To Configure SSH Key-Based Authentication on a Linux Server.
You should then see the output similar to the following:
OutputYour identification has been saved in /your_home/.ssh/id_rsa Your public key has been saved in /your_home/.ssh/id_rsa.pub The key fingerprint is: SHA256:/hk7MJ5n5aiqdfTVUZr+2Qt+qCiS7BIm5Iv0dxrc3ks user@host The key's randomart image is: +---[RSA 3072]----+ | .| | + | | + | | . o . | |o S . o | | + o. .oo. .. .o| |o = oooooEo+ ...o| |.. o *o+=.*+o....| | =+=ooB=o.... | +----[SHA256]-----+
You now have a public and private key that you can use to authenticate. The next step is to place the public key on your server so that you can use SSH-key-based authentication to log in.
The quickest way to copy your public key to the Ubuntu host is to use a utility called
ssh-copy-id
. Due to its simplicity, this method is highly recommended if available. If you do not havessh-copy-id
available to you on your client machine, you may use one of the two alternate methods provided in this section (copying via password-based SSH, or manually copying the key).Copying the Public Key Using
ssh-copy-id
The
ssh-copy-id
tool is included by default in many operating systems, so you may have it available on your local system. For this method to work, you must already have password-based SSH access to your server.To use the utility, you specify the remote host that you would like to connect to, and the user account that you have password-based SSH access to. This is the account to which your public SSH key will be copied.
The syntax is:
You may see the following message:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' can't be established. ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe. Are you sure you want to continue connecting (yes/no)? yesThis means that your local computer does not recognize the remote host. This will happen the first time you connect to a new host. Type “yes” and press
ENTER
to continue.Next, the utility will scan your local account for the
id_rsa.pub
key that we created earlier. When it finds the key, it will prompt you for the password of the remote user’s account:
Output/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 username@203.0.113.1's password:Type in the password (your typing will not be displayed, for security purposes) and press
ENTER
. The utility will connect to the account on the remote host using the password you provided. It will then copy the contents of your~/.ssh/id_rsa.pub
key into a file in the remote account’s home~/.ssh
directory calledauthorized_keys
.You should see the following output:
OutputNumber of key(s) added: 1 Now try logging into the machine, with: "ssh 'username@203.0.113.1'" and check to make sure that only the key(s) you wanted were added.At this point, your
id_rsa.pub
key has been uploaded to the remote account. You can continue on to Step 3.Add your
SSH
public key to remote server user'sauthorized_keys
file usingssh-copy-id
command.$ ssh-copy-id user@remote-host
Copying the Public Key Using SSH
If you do not have
ssh-copy-id
available, but you have password-based SSH access to an account on your server, you can upload your keys using a conventional SSH method.We can do this by using the
cat
command to read the contents of the public SSH key on our local computer and piping that through an SSH connection to the remote server.On the other side, we can make sure that the
~/.ssh
directory exists and has the correct permissions under the account we’re using.We can then output the content we piped over into a file called
authorized_keys
within this directory. We’ll use the>>
redirect symbol to append the content instead of overwriting it. This will let us add keys without destroying previously added keys.The full command looks like this:
You may see the following message:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' can't be established. ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe. Are you sure you want to continue connecting (yes/no)? yesThis means that your local computer does not recognize the remote host. This will happen the first time you connect to a new host. Type
yes
and pressENTER
to continue.Afterwards, you should be prompted to enter the remote user account password:
Outputusername@203.0.113.1's password:After entering your password, the content of your
id_rsa.pub
key will be copied to the end of theauthorized_keys
file of the remote user’s account. Continue on to Step 3 if this was successful.Copying the Public Key Manually
If you do not have password-based SSH access to your server available, you will have to complete the above process manually.
We will manually append the content of your
id_rsa.pub
file to the~/.ssh/authorized_keys
file on your remote machine.To display the content of your
id_rsa.pub
key, type this into your local computer:You will see the key’s content, which should look something like this:
Outputssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@testAccess your remote host using whichever method you have available.
Once you have access to your account on the remote server, you should make sure the
~/.ssh
directory exists. This command will create the directory if necessary, or do nothing if it already exists:Now, you can create or modify the
authorized_keys
file within this directory. You can add the contents of yourid_rsa.pub
file to the end of theauthorized_keys
file, creating it if necessary, using this command:In the above command, substitute the
public_key_string
with the output from thecat ~/.ssh/id_rsa.pub
command that you executed on your local system. It should start withssh-rsa AAAA...
.Finally, we’ll ensure that the
~/.ssh
directory andauthorized_keys
file have the appropriate permissions set:This recursively removes all “group” and “other” permissions for the
~/.ssh/
directory.If you’re using the root account to set up keys for a user account, it’s also important that the
~/.ssh
directory belongs to the user and not to root:In this tutorial our user is named sammy but you should substitute the appropriate username into the above command.
We can now attempt passwordless authentication with our Ubuntu server.
If you have successfully completed one of the procedures above, you should be able to log into the remote host without providing the remote account’s password.
The basic process is the same:
If this is your first time connecting to this host (if you used the last method above), you may see something like this:
OutputThe authenticity of host '203.0.113.1 (203.0.113.1)' can't be established. ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe. Are you sure you want to continue connecting (yes/no)? yesThis means that your local computer does not recognize the remote host. Type “yes” and then press
ENTER
to continue.If you did not supply a passphrase for your private key, you will be logged in immediately. If you supplied a passphrase for the private key when you created the key, you will be prompted to enter it now (note that your keystrokes will not display in the terminal session for security). After authenticating, a new shell session should open for you with the configured account on the Ubuntu server.
If key-based authentication was successful, continue on to learn how to further secure your system by disabling password authentication.
If you were able to log into your account using SSH without a password, you have successfully configured SSH-key-based authentication to your account. However, your password-based authentication mechanism is still active, meaning that your server is still exposed to brute-force attacks.
Before completing the steps in this section, make sure that you either have SSH-key-based authentication configured for the root account on this server, or preferably, that you have SSH-key-based authentication configured for a non-root account on this server with
sudo
privileges. This step will lock down password-based logins, so ensuring that you will still be able to get administrative access is crucial.Once you’ve confirmed that your remote account has administrative privileges, log into your remote server with SSH keys, either as root or with an account with
sudo
privileges. Then, open up the SSH daemon’s configuration file:Inside the file, search for a directive called
PasswordAuthentication
. This line may be commented out with a#
at the beginning of the line. Uncomment the line by removing the#
, and set the value tono
. This will disable your ability to log in via SSH using account passwords:/etc/ssh/sshd_configSave and close the file when you are finished by pressing
CTRL+X
, thenY
to confirm saving the file, and finallyENTER
to exit nano. To actually activate these changes, we need to restart thesshd
service:As a precaution, open up a new terminal window and test that the SSH service is functioning correctly before closing your current session:
Once you have verified your SSH service is functioning properly, you can safely close all current server sessions.
The SSH daemon on your Ubuntu server now only responds to SSH-key-based authentication. Password-based logins have been disabled.
Step 6 — Setting Up Fail2ban
Installing Fail2ban on Ubuntu
The Fail2ban package is included in the default Ubuntu 20.04 repositories. To install it, enter the following command as root or user with sudo privileges :
sudo apt update
sudo apt install fail2ban
Once the installation is completed, the Fail2ban service will start automatically. You can verify it by checking the status of the service:
sudo systemctl status fail2ban
The output will look like this:
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-08-19 06:16:29 UTC; 27s ago Docs: man:fail2ban(1) Main PID: 1251 (f2b/server) Tasks: 5 (limit: 1079) Memory: 13.8M CGroup: /system.slice/fail2ban.service └─1251 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
That’s it. At this point, you have Fail2Ban running on your Ubuntu server.
Fail2ban Configuration
The default Fail2ban installation comes with two configuration files,
/etc/fail2ban/jail.conf
and/etc/fail2ban/jail.d/defaults-debian.conf
. It is not recommended to modify these files as they may be overwritten when the package is updated.Fail2ban reads the configuration files in the following order. Each
.local
file overrides the settings from the.conf
file:
/etc/fail2ban/jail.conf
/etc/fail2ban/jail.d/*.conf
/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*.local
For most users, the easiest way to configure Fail2ban is to copy the jail.conf
to jail.local
and modify the .local
file. More advanced users can build a .local
configuration file from scratch. The .local
file doesn’t have to include all settings from the corresponding .conf
file, only those you want to override.
Create a .local
configuration file from the default jail.conf
file:
sudo cp /etc/fail2ban/jail.{conf,local}
To start configuring the Fail2ban server open, the jail.local
file with your text editor :
sudo nano /etc/fail2ban/jail.local
The file includes comments describing what each configuration option does. In this example, we’ll change the basic settings.
Whitelist IP Addresses
IP addresses, IP ranges, or hosts that you want to exclude from banning can be added to the ignoreip
directive. Here you should add your local PC IP address and all other machines that you want to whitelist.
Uncomment the line starting with ignoreip
and add your IP addresses separated by space:
ignoreip = 127.0.0.1/8 ::1 123.123.123.123 192.168.1.0/24
Ban Settings
The values of bantime
, findtime
, and maxretry
options define the ban time and ban conditions.
bantime
is the duration for which the IP is banned. When no suffix is specified, it defaults to seconds. By default, the bantime
value is set to 10 minutes. Generally, most users will want to set a longer ban time. Change the value to your liking:
bantime = 1d
To permanently ban the IP use a negative number.
findtime
is the duration between the number of failures before a ban is set. For
example, if Fail2ban is set to ban an IP after five failures (maxretry
, see below), those failures must occur within the findtime
duration.
findtime = 10m
maxretry
is the number of failures before an IP is banned. The default value is set to five, which should be fine for most users.
maxretry = 5
Comments
Post a Comment