What is Port Knocking?
Port knocking is a method by which you can dynamically open ports on your server to a single IP address. Port knocking allows you to transparently run a service on your server without exposing the services of that port to all IP addresses.
In practice, it is very similar to having a whitelist of IP addresses which are allowed to access your server. The advantage of this setup is that you can grant the machine you are using access to the ports on your server dynamically without having to reconfigure your firewall or access list.
How Does it Work?
You create a pre-defined knocking sequence on your server which is known only to you. It’s not possible to determine this sequence via port scanning as all ports appear closed and an attacker would essentially need to sniff your traffic in order to determine the knocking sequence.
In its simplest form, the knock can be a series of tcp, udp or icmp requests to specific ports on your server in a pre-defined order. A daemon on your server could either scan the firewall log or sniff traffic directly to determine when a successful knock has been completed. After a successful knock, the protected port would then be accessible to the IP from which you completed the knock.
It’s not an end-all to security by any means, but it does provide an additional layer of protection for your server. It’s one more thing that an attacker much overcome in order to gain access to your machine. If you are already following best practices for securing your server, this is an excellent next step to boost your security profile even further.
Configure a Simple Port Knock
Because I consider this to be an additional layer of protection and not the ONLY layer of protection I use, I wanted this to be simple to use. I don’t want to carry a specific knocking program on a usb key and I want to be able to quickly and easily open the ports from any computer I may be using.
For this reason, using tcp requests makes the most sense. It’s very easy to create a firewall configuration to check for incoming knock requests and open ports without having to run any special daemons on my server. The other key being simplicity which means that I’m not going to be implementing a complex knocking sequence either. A single knock on a randomly defined port should offer the additional layer of protection I wanted in the first place. It also means that I can quickly open a port using a simple web browser or any other utility which can sent tcp packets.
#SAMPLE IPTABLES RULES iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m recent --rcheck --name SSH -j ACCEPT iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 31599 -m recent --name SSH --remove -j DROP iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 31600 -m recent --name SSH --set -j DROP iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 31601 -m recent --name SSH --remove -j DROP iptables -A INPUT -p tcp --dport 22 -j DROP
The above iptables rules should be applied in accordance with your current firewall script. The rules above apply to a server running ssh on port 22 (which I recommend you change to another port altogether). The knocking sequence is a single tcp packet to ports 31600 & 31601 on my server. Sending a single packet to port 31600 will open port 22 for my machine only and it will remain open until either the server is rebooted or I sent a tcp packet to port 31601 to close the port again.
The above is a simple implementation which requires no special knocking software nor any special daemons on your server. You can increase the security of this setup by introducing a knocking sequence (multiple sequential knocks to pre-defined ports in order) or by using payloads or encrypted content in your packets. Both of these approaches introduce more complexity in the setup, but both are more robust approaches than what I have outlined above.
Performing the Knock
As I said, I wanted simplicity and the above rules give me just that. Sending the tcp packets I need can be done quite easily with either a browser or a telnet program. This basically ensures that I’ll always be able to open my server regardless of the computer I’m using.
To perform the knock via my browser, I would simply type the following in my address bar:
to open >>http://MYSERVERIP:31600
to close >>http://MYSERVERIP:31601
That should send the request I need and afterwards I should be able to ssh in no problem.
To perform the knock via telnet, I could type in the following:
to open telnet MYSERVERIP 31600
to close telnet MYSERVERIP 31601
Port knocking should offer you a bit more security than you presently have. It’s really simple to setup and there’s really not much of a downside to having it enabled. In additional to the added security you get from this setup, you also still have all of the usual security features of ssh (or any other service you may wish to protect via this method).