General idea
The general idea behind server security is the whitelist-only approach, meaning that communication to the server is only accepted from authorized sources. It’s usually okay for the server itself to be able to reach out to the outside internet, but not always. This post doesn’t concern itself with the latter case.
Reset root user password
In the case were your remote server was set up by someone else other than you, immediately change the root user’s password.
Never use a remote server where you don’t have root access in production.
passwd
<enter old password>
<enter new password>
SSH
Key-based authentication
A common way someone accesses any remote machine is via ssh
and so we’ll begin by disabling password authentication. This will prevent password brute-force attacks.
Begin by creating an ssh key (eg. my_key) on your local machine and adding it to the keychain.
ssh-keygen -t ed25519 -C "some comment"
# Enter password
# Save in a secure location
eval "$(ssh-agent)"
ssh-add my_key
You must then copy the contents of my_key.pub
file created as a result of the process above to the remote machine’s $USERHOME/.ssh/authorized_key
file. If this file doesn’t exist, then you can create it yourself. This file MUST have the following permissions: 0644
Next, open the the ssh daemon
’s config file located at /etc/ssh/sshd_config
and set PubKeyAuthenticaion yes
, then restart the ssh service:
sudo systemctl restart sshd.service
Now attempt to connect to the server like so. You should log-in to your user without being prompted for password.
ssh user@your_server_ip
WARNING! Be absolutely certain that key-based authentication works before following the next step, otherwise you will be permanently locked out of your server and may have to trigger a system reinstall.
If the above step was successful – you could log in to your remote machien without being prompted for a password – open the the ssh daemon
’s config file once more and set PasswordAuthentication no
, and restart the ssh service.
There are some other settings here worth knowing about:
- You can prevent root access over ssh. This means to become root, you must first ssh into the server as a normal user before switching to root user. This is useful in cases where your ssh key is compromised, and you happen to have a strong root user password. However, if your user is somehow wiped or inaccessible, you will lose access to the machine altogether.
- You could also change the default ssh port. Some people recommend this, but I don’t see any security benefits at all. Any attacker worth their salt will quickly scan the server’s ports and find the alternative ssh port.
Fail2Ban
The final step to achieve decent ssh security is Fail2Ban
. This is an application that will IP ban anyone who attempts brute-force an ssh login. Fail2Ban configuration is decent enough out of the box. Simply install the package and start the service:
sudo apt install fail2ban
sudo systemctl enable fail2ban.service --now
If you wish, you could take a look at the contents of /etc/fail2ban
and modify some of the configuration parameters to suit your needs.
Firewall
Next, we will set up a whitelist-only firewall. This means that by default all access to the server will be blocked, save from the specific locations we allow. Linux firewall is a kernel component managed by the application iptables
. However, instead of modifying the eponymous ip tables directly, we will do so through a simple and user-friend application by the name of ufw
. Install the ufw package and enable its service file:
sudo apt install ufw
sudo systemctl enable ufw.service --now
The firewall service is up, but no rules are currently enforced. We need to first configure the policies and then enable the firewall through the application itself.
Let’s begin by setting default access policies. These are blanket rules that affect in/outcoming in a general way:
sudo ufw default allow outgoing # This allows the server to reach out to the external world without any restrictions.
sudo ufw default deny incmoing # This prevents all incoming traffic. Nobody will be able to reach the server in any way.
sudo ufw allow ssh # This opens all traffic on port 22 by default. If you change the default ssh port in the previous step, make sure to open that instead (sudo ufw allow ssh <port number>)
sudo ufw allow nginx # (optional) The nginx profile will automatically allow traffic on porst 80 and 443. This is how you will publish your applications over the internet.
WARNING! Ensure that you have white-listed the ssh port correctly. Otherwise you will lose access to the server altogether.
The End?
Congratulations, by this point your server is rather well secured from most outside threats. Keep your system updated (especially with security updates), use strong authentication, and disallow all unauthorized remote and/or physical access to the server. That is the essence of system security.
Resources
- LearnLinuxTV’s video on ufw configuration - https://www.youtube.com/watch?v=XtRXm4FFK7Q