Ubuntu, securing SSH accesses with the listening port and ufw (Uncomplicated Firewall)

Logo

Introduction

The three first steps to secure its own new Ubuntu server, in the cloud or not :

  • Change the default port for SSH connections.
  • Disable direct access through SSH with the root account.
  • Enable ufw (Ubuntu Uncomplicated Firewall) allowing incoming SSH connections.
Putty ufw ssh

This article does not explain how to enable and use ufw, there are many tutorials about ufw, this article focuses on how to safely enable ufw for the first time allowing SSH connections with SSH running on the non default port. In many articles, the reader is told to be cautious when enabling ufw without mentioning the command ufw show added, this command will guarantee there is no human error before enabling ufw, human error that could break and disrupt existing SSH connections without the ability to establish new ones otherwise than having to contact the supplier or physically accessing the server.

In this article, ssh service will listen on port 1857 and ufw is enabled allowing SSH incoming connections on this port. Some extra checks are performed before enabling ufw (IP v6 and default policies).

Changing default port for SSH connections

By default, SSH service listens on port 22. Without any security or firewall configurations defined, many connection attempts appear in the log file /var/log/auth.log

/var/log/auth.log
Mar 26 12:29:18 vps sshd[26691]: Failed password for invalid user cb from 103.36.30.157 port 56224 ssh2
Mar 26 12:29:18 vps sshd[26691]: Received disconnect from 103.36.30.157 port 56224:11: Bye Bye [preauth]
Mar 26 12:29:18 vps sshd[26691]: Disconnected from invalid user cb 103.36.30.157 port 56224 [preauth]

So, first thing to do, change the default SSH port 22 to another one : here 1857.

Modify the port of the SSH service in the file /etc/ssh/sshd_config

/etc/ssh/sshd_config
Port 1857

Then restart the SSH service :

root@vps$ /etc/init.d/ssh restart

All new SSH connections with Putty, or any other tool (FTP Filezilla…), will be defined with the new port.

Putty new port

netstat or lsof are useful binaries to check ssh service listening ports and process id :

root@vps$ lsof -i -P -n | grep LISTEN | grep 'sshd'
          
sshd       939            root    3u  IPv4  18880      0t0  TCP *:1857 (LISTEN)
sshd       939            root    4u  IPv6  18891      0t0  TCP *:1857 (LISTEN)
root@vps$ netstat -tulpn | grep LISTEN | grep 'sshd'
          
tcp        0      0 0.0.0.0:1857            0.0.0.0:*               LISTEN      939/sshd
tcp6       0      0 :::1857                 :::*                    LISTEN      939/sshd

Disabling direct access from root user

To strengthen security, disable direct access from user root through SSH connections.

Create an account that will be a bounce account for root access, for example an account named gateway :

root@vps$ useradd -d /home/gateway -m -g wapp -s/bin/bash gateway

Set a strong password for the account gateway :

root@vps$ passwd gateway

Enter new UNIX password:...
passwd: password updated successfully

In the file /etc/ssh/sshd_config, set the parameter PermitRootLogin to no in the section Authentication :

/etc/ssh/sshd_config
# Authentication:
…
PermitRootLogin no
…

Restart the SSH service :

root@vps$ /etc/init.d/ssh restart

The account gateway previously created will now be used for root access :

gateway@vps$ su - root

Configuring and enabling ufw

A non default port is now defined for SSH and direct access from root user is not allowed. So let’s enable ufw for the first time with SSH incoming connections allowed on port 1857.

First of all, IP v6 and default policies are checked.

IP v6

Before enabling ufw, check if IP v6 is disabled or not in the Ubuntu system.

IP v6 is supported and activated if the file /proc/net/if_inet6 exists.

root@vps$ ls /proc/net/if_inet6

This file lists all network interfaces with IP v6 enabled :

root@vps$ cat /proc/net/if_inet6
          
fe80000000000000f8163efffeb7a0f0 02 40 20 80     ens3
00000000000000000000000000000001 01 80 10 80       lo

Here, IP v6 is enabled for the network interfaces ethernet (ens3, formerly eth0) and loopback (lo).

If the Ubuntu server has IP v6 enabled, ensure that ufw is configured to support IP v6 so that it will manage firewall rules for IPv6 in addition to IP v4. Check that the parameter IPV6 is set to yes in the file /etc/default/ufw.

/etc/default/ufw
IPV6=yes

With this parameter, when ufw is enabled, both IP v4 and IP v6 firewall rules will be configured.

Policies

In the file /etc/default/ufw, ensure also that the parameters DEFAULT_INPUT_POLICY and DEFAULT_OUTPUT_POLICY are defined respectively to DROP and ACCEPT.

/etc/default/ufw
DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="ACCEPT"

With these parameters values, when ufw is enabled for the first time, the firewall rules will be : allow outgoing and deny ingoing connections.

Allowing SSH incoming connections

Then add the firewall rule allowing SSH incoming connections on port 1857 :

root@vps$ ufw allow 1857

Rules updated
Rules updated (v6)

Verify the rule is properly added with the command show added :

root@vps$ ufw show added

Added user rules (see 'ufw status' for running firewall):
ufw allow 1857

Enabling ufw

Now ufw can be safely enabled, existing and future SSH connections won’t be disrupted :

root@vps$ ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

To verify ufw status :

root@vps$ ufw status verbose
          
Status: active
Logging: off
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
1857                       ALLOW IN    Anywhere
1857 (v6)                  ALLOW IN    Anywhere (v6)

2 rules are created allowing incoming connections on port 1857 : one rule for IP v4, the second one for IP v6.