How to Further Secure SSH With a Port-knocking Sequence on Ubuntu 18.04

Updated on November 21, 2023
How to Further Secure SSH With a Port-knocking Sequence on Ubuntu 18.04 header image

Introduction

Besides changing the default port for SSH, and using a key pair for authentication, port knocking can be used to further secure (or more accurately, obscure) your SSH server. It works by refusing connections to your SSH network port. This essentially hides the fact that you're running an SSH server until a sequence of connection attempts are made to predefined ports. Very secure and simple to implement, port knocking is one of the best ways to protect your server from malicious SSH connection attempts.

Prerequisites

  • A Vultr server running Ubuntu 18.04.
  • Sudo access.

Before following the steps below, if you're not logged in as the root user, please obtain a temporary root shell by running sudo -i and entering your password. Alternatively, you may prepend sudo to the commands shown in this article.

Step 1: Knockd installation

Knockd is the package that is used in combination with iptables to implement port knocking on your server. The 'iptables-persistent' package is also required.

apt update
apt install -y knockd iptables-persistent

Step 2: iptables rules

Run the following commands in order:

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --destination-port 22 -j DROP
iptables-save > /etc/iptables/rules.v4

These commands will do the following, respectively:

  • Instruct iptables to keep existing connections alive.
  • Instruct iptables to drop any connection to port tcp/22 (if your SSH daemon is listening on a port other than 22, you should modify the above command accordingly.)
  • Save these two rules so they will persist after a reboot.

Step 3: Knockd configuration

Using a text editor of your choice, open the file /etc/knockd.conf.

You will see the following:

[openSSH]
sequence    = 7000,8000,9000
seq_timeout = 5
command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags    = syn

You should change the sequence of ports (choose port numbers above 1024 and unused by other services), and store it safely. This combination should be treated like a password. If forgotten, you will lose access to SSH. We will be referring to this new sequence as x,y,z.

the seq-timeout line is the number of seconds Knockd will wait for the client to complete the port-knocking sequence. It would be a good idea to change this to something larger, especially if the port-knocking will be done manually. However, a smaller timeout value is safer. Changing it to 15 is recommended since we'll be knocking manually in this tutorial.

Change the opening sequence to you chosen ports:

[openSSH]
sequence    = x,y,z

Change the command value to the following:

command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

Now change the closing sequence accordingly:

[closeSSH]
sequence    = z,y,x

Save your changes and exit, and open the file /etc/default/knockd:

  • Replace START_KNOCKD=0 with START_KNOCKD=1.
  • Add the following line to the end of the file: KNOCKD_OPTS="-i ens3" (replace ens3 with the name of your public network interface if it differs.)
  • Save and exit.

Now start Knockd:

systemctl start knockd

If you now disconnect from your server, you'll have to knock on ports x, y, and z to connect again.

Step 4: Testing

You now will not be able to connect to your SSH server.

You can test port knocking with a telnet client.

Windows users can launch telnet from the command prompt. If telnet isn't installed, access the "Programs" section of Control Panel, then locate "Turn Windows features on or off". On the features panel, locate "Telnet Client" and enable it.

In your terminal/command prompt type the following:

telnet youripaddress x
telnet youripaddress y
telnet youripaddress z

Do this all in fifteen seconds, as that's the limit imposed in the configuration. Now, attempt to connect to your server via SSH. It will be accessible.

To close access the SSH server, run the commands in reverse order.

telnet youripaddress z
telnet youripaddress y
telnet youripaddress z

Conclusion

The best part about using port knocking is that if it is configured alongside of private key authentication, there's virtually no chance that someone else could get in unless someone knew your port-knocking sequence and had your private key.