Use Port Knocking To Secure SSH Service (Debian/Ubuntu)
In this tutorial, I’m going to show you how to use port knocking to secure SSH service on Debian and Ubuntu servers.
What is Port Knocking in SSH
Port knocking is a way to allow only legitimate users to access services on a server and the service in this tutorial is the SSH service. SSH service is running on the server but the SSH port is closed from the outside world by firewall rules, so no one can connect directly to SSH port 22.
The server also runs a knockd
daemon, which has the ability to change firewall rule and temporarily open SSH port 22 to a user if that user hit (or knock) some specific ports in a sequence. So the knock sequence is kind of like a password for the SSH port. Only legitimate users with the right knock sequence can trigger knocked
to open SSH port. When the legitimate user wants to log out, another knock sequence is used to close the SSH port.
Now we will discuss how to install and configure knockd
and set up firewall rule. This tutorial assumes you are using Linux on the client computer.
Step 1: Install and Configure Knockd on Debian/Ubuntu Server
Run the following command to install knocked from the default software repository.
sudo apt-get install knockd
Edit main configuration file with a command-line text editor like Nano.
sudo nano /etc/knockd.conf
You need to change three items in this file. In the [openSSH]
section, the default opening knock sequence is 7000,8000,9000
. You can change this to your own liking, such as 10001,10002,10003
. You can also define 4 or more ports for the sequence. You don’t need to open these ports in firewall.
Then in the iptables
command, change -A
to -I
, so this iptables rule will be the first in the rule chain. Order in iptables rule chain matters. When you send the right knock sequence, knockd
will execute this iptables command to open SSH port for your IP address only. All other IP addresses are still not allowed to connect to the SSH port.
Next, in the [closeSSH]
section, change the default closing knock sequence to your liking, such as 10003,10002,10001
.
Save and close the file.
Next, run the following command to find out the name of main network interface on the server.
ip addr
As you can see, mine is ens18
. Now edit /etc/default/knockd
config file.
sudo nano /etc/default/knockd
Find this line
START_KNOCKD=0
Change 0
to 1
to enable autostart at system boot.
START_KNOCKD=1
knockd
by default listens on eth0
interface. You server’s network interface might not be eth0
, so in this case you need to change it. Find the following line.
#KNOCKD_OPTS="-i eth1"
Remove #
and change eth1
to the name of the main network interface on your server.
KNOCKD_OPTS="-i ens18"
Save and close the file. Then start knockd
daemon
sudo systemctl start knockd
Enable autostart.
sudo systemctl enable knockd
Check its status to see if it’s running.
systemctl status knockd
Step 2: Close SSH Port 22
To close SSH port 22 in UFW firewall, first you need to list the current firewall rules.
sudo ufw status nubmered
As you can see, the first rule and the third rule open the SSH port. To close TCP port 22, delete these two rules.
sudo ufw delete 3 sudo ufw delete 1
Hint: You should delete the rule with a bigger index number first.
Now if you try to SSH into your server, the SSH service won’t respond to your request.
Step 3: Use Knock Client to Send Knock Sequence
The knockd
daemon is bundled with a knock client called knock
, so on your Debian or Ubuntu client computer, you can install it by running:
sudo apt-get install knockd
In order to trigger the server firewall to TCP port 22, you need to send the correct knock sequence from the client computer.
knock -v 10.0.0.104 10001 10002 10003
Output:
hitting tcp 10.0.0.104:10001 hitting tcp 10.0.0.104:10002 hitting tcp 10.0.0.104:10003
Knock attempt can fail if there’s a high latency between your client and your server. You may need to send the knock sequence multiple times if the SSH port is still closed.
Once the knock attempt is successful, you can SSH into your server. After you’ve done all your work, you can use port knocking to close SSH port for your IP.
knock -v 10.0.0.104 10003 10002 10001
Note that knockd
will only respond to knock sequence sent to the main network interface (aka the main IP address). If the server has multiple IP address, and you try to send the knock sequence on another IP address, knockd won’t be able to open SSH port.
Auto Restart Knockd
If the knockd
daemon stops running on the server, then you can’t SSH into your server. To prevent this from happening, you can create a cron job to automatically restart the knockd once an hour.
Edit root user’s crontab file.
sudo crontab -e
Add the following line in the file.
@hourly systemctl restart knockd
Save and close the file.
Note: Even if knockd
stops running, you can still access your server by using your hosting provider’s web-based console, then you can manually start knockd
, so you will have SSH access again.
SSH Passwordless Login
You can further strength the security of your SSH service by enabling public key authentication (passwordless login).
Wrapping Up
I hope this tutorial helped you set up port knocking on Debian/Ubuntu server. You may also want to check out other security tutorials.
- How to Use UFW Firewall on Debian, Ubuntu, Linux Mint
- Set Up Automatic Security Update (Unattended-Upgrade) on Ubuntu
- Canonical Livepatch Service: Patch Linux Kernel on Ubuntu without Reboot
- 5 Effective Tips to Harden SSH Server on Ubuntu
- How to Secure Email Server Against Hacking with VPN (Debian/Ubuntu)
As always, if you found this post useful, then subscribe to our free newsletter to get new tutorials.
Muchas gracias por compartir
Another incredibly complex sequence that could be done more elegantly. How is this any safer than simply SSH entry through keys and not passwords? I can see how you could accidentally get locked out of your server.
Simple elegant solutions are always preferred.
And I thought the new convention is nftables not iptables. Although, nftables is so much more complex
Hello Philip, this article should not be named Secure SSH Service, it is more about attacks on the open ports. After finding an open port you will be under permanent attack. So closing “all” ports is an elegant solution.
Just What I have been looking for!!
As an ancient, but not-very-erudite linux user/experimenter I have been reluctant to open my holiday home server to access from from my laptop when I am away. I have used various linux distros mainly Ubuntu for everyday use. I discovered “Breezy Badger” and shortly afterwards I went Windows-free. Your article fits the bill perfectly Thank you,
as the old saying goes don’t applaud — throw money
I will certainly make a donation when I have successfully set it up.
Very best wishes
Richard Ayres
great article. have you looked at moxie marlinspikes knockknock implementation? i would very much like a tutorial on how to make that work. it seems like a more secure alternative to this solution.
that article, if anyone is interested is at https://github.com/moxie0/knockknock
Doesn’t sound like there’s any point to this since the sequences can be caught and used to abuse the system with more requests than it was already having. Might as well just use ed25519 AES256-CBC keypairs protected by a hard password and fail2ban (or DigitalRuby IPBan for Window$, it seems).
what this sudo ufw status nubmered ?
list firewall rules.
Step 2: Close SSH Port 22, has
spelled incorrectly. You might want to change that.
Good article! Thanks!
I used portqry for windows but it not working for linux .
With Knockd now my connection works in Linux too.
Just change the command below:
(At Step 2: Close SSH Port 22)
sudo ufw status nubmered
with
sudo ufw status numbered