This article will explain how to hide your SSH daemon from port scanners and attackers on CeonOS 7 Linux by using FirewallD with KnockD (port knocking daemon).
What does knockd?
Port knocking server is a daemon running on the server and waiting for a specific port knocking sequence.
Such a sequence usually consists of three random port numbers that you need to knock on to automatically perform a task on server.
After registering these three ports being knocked in the correct order and in the predefined time frame, knockd executes a command.
In our case, it will be – open a specific port in the firewall and then close a specific port in the firewall.
How does knockd make things secure?
To open a specific port, you need to knock on three (or more) random ports, these port numbers can be completely random – 5248,2637,4235.
For example, after you have knocked your server on ports 5248,2637,4235, port 22 will get open.
The security consists of a large number of combinations of port numbers that need to be knocked to trigger a command executed by knockd.
The attackers will never guess the right combination to trigger Knockd to execute a predefined command.
We can go even further and increase the order of port numbers that need to be knocked.
Something like: 32512,8425,27705,26643,31689,17272,39972,21762,17213,9136,17752,45700.
Now the attacker has to knock all these port numbers in the correct order so that the port knocking daemon opens port 22 in the firewall of your server.
Well, theoretically, the attacker can guess the right combination of ports, but this task will take him like 14.6 billion years.
So let’s hope the attacker will not be so stubborn and will not waste all the time to attack your server.
Aside from the need to execute this sequence in the correct order, the attacker is also time-limited because we can set the time limit to execute the entire sequence.
Now let’s go to the practical part of the story.
First and foremost, you need the “FirewallD” installed on your Linux CentOS 7 distribution, which is the default firewall for the latest CentOs distributions.
yum install firewalld -y
yum install libpcap* -y
Go to https://pkgs.org/download/knock and choose the right package for your Linux distribution.
Copy the link to the package and run the wget command.
Then install the package:
rpm -ivh knock-server-0.7-1.el7.nux.x86_64.rpm
> rpm -ivh knock-server-0.7-1.el7.nux.x86_64.rpm warning: knock-server-0.7-1.el7.nux.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 85c6cd8a: NOKEY Preparing... ######################################## Updating / installing... knock-server-0.7-1.el7.nux ########################################
Now we need to configure knockd to execute a command after the correct port-knock-sequence has been received.
Open the port-knocking-server configuration file, which is usually located on CentOs in /etc/knockd.conf and edit it with a text editor of your choice.
[options] UseSyslog [openSSH] sequence = 32512,8425,27705 seq_timeout = 5 command = firewall-cmd --add-port=22/tcp tcpflags = syn [closeSSH] sequence = 9136,17752,45700 seq_timeout = 5 command = firewall-cmd --remove-port=22/tcp tcpflags = syn
The above configuration causes the knock demon to log all its activities in the system log.
If you want to use a different log file. Or, like me, to use a separate log file, you can change it as follows:
[options] LogFile = /var/log/port_knocking.log [openSSH] sequence = 32512,8425,27705 seq_timeout = 5 command = firewall-cmd --add-port=22/tcp tcpflags = syn [closeSSH] sequence = 9136,17752,45700 seq_timeout = 5 command = firewall-cmd --remove-port=22/tcp tcpflags = syn
Explaining the options
seq_timeout = 5
Is the time in seconds within which the entire sequence must be completed. Otherwise it will be ignored.
cmd_timeout = 10
Is the time in seconds after which the knock daemon executes a desired command when triggered by a proper sequence of port knocks.
tcpflags = syn
Will instruct klockd to listen only to packets that have a specific flag set. In this example – only packets with flag syn can trigger knockd. All other packets will be ignored. Possible flags: syn, rst, fin, ack, psh, urg. Multiple selection possible.
In our case, the “Port Knocking Daemon” will open a port number 22 inside the FirewallD.
For this reason, we set up knockd to execute this command “firewall-cmd –add-port = 22 / tcp”, which immediately opens port number 22.
Which command should I use?
firewall-cmd --add-port = 22/tcp
– opens the port immediately and the command lasts until the next reboot of the server.
firewall-cmd --permanent --add-port = 22/tcp
– will not open the port immediately, but after the next server reboot, and it will last forever.
It is up to you which command you will use, but for our purpose the command “firewall-cmd –add-port = 22/tcp” is the only correct command.
To close a port, we use the opposite command “firewall-cmd –remove-port = 22 / tcp”, which closes the port after we send a “closing sequence” to knockd.
So, what do we have?
Your SSH port will remain closed by the firewall all the time until you knock on ports 32512,8425,27705 in the correct order within 5 seconds.
After you do, the port knocking daemon will open port 22 after 10 seconds.
After you’ve done your job through SSH, you can close port 22 by knocking on port number 9136,17752,45700.
Close the port automatically after a certain time
If you do not want to close the port manually, you can choose to automatically close it after a certain amount of time.
Use “start_command” to execute the first command (open port).
Then “cmd_timeout” to set a time frame between the two commands.
And “stop_command” to execute the next command (close port).
Example configuration would look like this:
[options] logfile = UseSyslog [opencloseSSH] sequence = 32512,8425,27705 seq_timeout = 5 tcpflags = syn start_command = firewall-cmd --add-port=22/tcp cmd_timeout = 1800 stop_command = firewall-cmd --remove-port=22/tcp
This configuration automatically closes port number 22 after half an hour.
As mentioned above, we can use more than three port numbers, but there may also be 10 or 20 random port numbers in a row.
You can also vary the protocol by appending “:udp” to a port number.
For example: “32512:tcp,8425:udp,27705:tcp”.
In this example, ports number 32512 and 27705 must be knocked via TCP and port number 8425 must be knocked via UDP.
This makes the set of all possible combinations even wider.
We can also instruct the Port Knock Daemon to execute any other command of our choice.
It could be “httpd service restart” to remotely restart the Apache web server without logging into the terminal or the Control Panel.
The configuration would look like this:
[options] LogFile = UseSyslog [openSSH] sequence = 32512,8425,27705 seq_timeout = 5 command = httpd service restart tcpflags = syn
It could also be server reboot command “shutdown -r” that lets you restart the server like in a blink of an eye.
The configuration would look like this:
[options] LogFile = UseSyslog [openSSH] sequence = 32512,8425,27705 seq_timeout = 5 command = shutdown -r tcpflags = syn
Now you can trigger the port knocking daemon by sending a command like this:
knock <your server ip> <port number> <port number> <port number>
Example port knocking command would look like this:
knock 126.96.36.199 32512,8425,27705