Debian Server 18.04 with UFW & Fail2Ban
debian, server, ssh, fail2banThis is how I set up my VPS as a base for whatever I’m going to do with it. When done we’ll have Debian 18.04 server with a user with root privelieges, a SSH key to login with instead of a password and UncomplicatedFirewall (UFW) and Fail2Ban which will block IP addresses of failed authentication tries.
SSH
An SSH key is an important step to take to keep your server out of reach for non-authorized people. If this is unfamiliar to you I recommend to take a look at: ssh.com. In this example we will create a RSA key pair.
If you don’t already have an SSH key we need to create one. This key is required to connect to the server.
Open the terminal and run the command ssh-keygen
. Without any options we will create a standard RSA
key.
Important: Make sure to create a strong password and keep it in a safe place. If the password is forgotten or the keyfile is gone, you’ll never get access to the server again.
Creating the key
First off, we will create the key
ssh-keygen
We will then see an output like this
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
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:BTX7[...]qa0Q user@host
The key's randomart image is:
+---[RSA 3072]----+
|*+ooo ..o . |
|. o+ o o o + . + |
| + + * o + + . o|
|oE o o . o = + |
|o S = X o|
| o . % * |
|. . B = |
| o o |
|. |
+----[SHA256]-----+
This will generate two files for us in ~/.ssh
- A public key called
id_rsa.pub
is the public key that we will upload to the server. This keyfile is not sensitive at all. - A private key called
id_rsa
is the private key that we will keep on our machine. This keyfile is very sensitive and should never be shared with anyone.
This means that it’s not possible to brute force the server as the server needs the private key to actually allow login.
If we cat
the public key, we see something like this
$ cat .ssh/id_rsa.pub
ssh-rsa AAAA[...]LI8= user@host
Copy the key to server
To copy the key to the server we can use following command
ssh-copy-id -i ~/.ssh/id_rsa.pub user@ip-of-server
The key will be added to a file called authorized_keys
and we need to make sure it has the right permissions which should be 700
for the directory and 600
for the file itself
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Log in to the server
We will now connect via SSH to our server with our key
ssh user@ip-of-server
Note: If you choose a different name or path for the key we need to use the -i
option to specify the path for it. To avoid this we can create a SSH config which I’ve a post about here.
First time connecting we will se a message like this, just type “yes” and give the password for the SSH key
The authenticity of host '<ip> (<ip>)' can't be established.
ECDSA key fingerprint is SHA256:p5Ew[...]a/PQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '<ip>' (ECDSA) to the list of known hosts.
user@<ip>'s password:
Make sure the system is up to date
apt update
apt upgrade
Create a user
Now we can create our user and give it root privileges. We will in a later step remove the ability to login as root throught SSH. We will need this user to login.
adduser <user>
usermod -aG sudo user
With the first command we creating the user and give it a user name, but we also added it to the sudo
group.
-a
: Add the user to a group-G
: Specifies which groups we want to add the user to.
SSH
We need to copy the SSH public key from the root user to our new user
rsync --archive --chown=<username>:<username> /root/.ssh /home/<username>/
Notice the /
after the path, this is to prevent the folder .ssh
to be moved as well
Since we now have the key in our user we can deny the root user to login with SSH and require the SSH key to be able to login
vim /etc/ssh/sshd_config
Find these rows, uncomment them and change the values to no
PermitRootLogin
PasswordAuthentication
UsePAM
ChallengeResponseAuthentication
To put the changes to action we can restart the SSH daemon
systemctl reload ssh
Firewall
We will use UFW (Uncomplicated Firewall)
as our firewall
By default UFW
blocks all incoming connections, so we will need to allow the ports for ssh
, http
and https
and activate the firewall
ufw default deny
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
Fail2Ban
Fail2Ban keeps track of who tries to connect to your server via SSH. With the help of this program, we can ban IPs that repeatedly attempt to connect but fail.
Download Fail2Ban
# apt install fail2ban
We need to copy the default configuration file:
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Then edit the file we just created jail.local
vim /etc/fail2ban/jail.local
Here we will change a few things, these are the settings I like
bantime = 60
findtime = 30
maxretry = 3
What the value means:
bantime = Number of minutes the ban should apply
findtime = The login attempts interval maxretry = How many tries that needs to be done in the findtime interval to be banned
And then we need to find the row with [sshd]
and add this below it
enabled = true
Now we’ve:
- Created a user with sudo right
- Activated a firewall and allowed ports for SSH, HTTP and HTTPS
- Activated Fail2Ban to find and ban recurrent failed login attempts via SSH