Port Knocking: Unseen Security
Security through obscurity is considered weak by itself. If the only problem to find the key is to look under a nearby carpet, it’s not much of a security.
However, port knocking differs from other obscuring measures (which should be applied along with other, “traditional” approaches, to be of any use). Imagine: there’s a solid, impenetrable wall in front of you, and a sturdy, reliable door. In order to get inside, you should knock in a correct sequence; otherwise, the alarm will be raised.
This is, omitting technical details, how port knocking works.
Computers nowadays are always protected with some sort of firewall – hardware, software, or combinations of both. Port knocking is based upon the following simple fact: even if port access is blocked, it still can be detected.
Basically, port knocking is just this: a sequence of port access attempts leads to doing something, such as granting access over a certain port. You can use any means to connect to the system in question: the very fact of a connection attempt is taken into account, all the rest is discarded.
For example: on can setup access to a Linux server, so that access to SSH port is only granted, if following subsequent ports have been probed: 45, 43254 and 244.
The way it’s probed isn’t of much importance. In fact, telnet calls like telnet remote-host-name port are enough, if done quickly enough. They can even be issued manually, if there are no other means to perform knocking. Now imagine: all incoming communication (say, via SSH) is locked, until known ports in a known sequence are probed from the same address, within a known time interval).
Since it’s impossible to guess what exact ports are used, even if the traffic is intercepted (an advanced technique can use “decoy” ports to be contacted as well, thus making guessing extremely hard), and what is expected if knocking was a success, this approach can be very convenient.
Implementing via Iptables
You will find a number of port knocking tutorials on the Net. The below is a concise implementation of a simple two-port knocking sequence that allows connection over a given port.
In this example, to get access to the system two ports should be knocked: <proto1>:<port1> and <proto2>:<port2>. For example, tcp:1324 and udp:5617 (you choose whatever you need).
First, introduce several chains prior to start any filtering:
iptables -N KNOCKING
iptables -N KTEST1
iptables -N KTEST2
iptables -N KPASSED
Then, after all initial tests are passed (such as allowing already established connections), insert a sequence like this:
iptables -A KTEST1 -p <proto1> --dport <port1> -m recent --name KSTAGE1 --set -j DROP iptables -A KTEST1 -j DROP
iptables -A KTEST2 -m recent --name KSTAGE1 --remove
iptables -A KTEST2 -p <proto2> --dport <prot2> -m recent --name KSTAGE2 --set -j DROP
iptables -A KTEST2 -j KTEST1
iptables -A KPASSED -m recent --name KSTAGE2 --remove
iptables -A KPASSED -p tcp --dport 22 -j ACCEPT
iptables -A KPASSED -j KTEST1
The above uses assigning tags (names) to channel all the traffic from stage to stage (every stage is choosing a correct protocol and port combination). Every time a mistake is made after stage1, all the traffic is rerouted back to stage 1 (otherwise, user’s second attempt will not be taken from the start of the sequence, and until two ports are tested, next attempt is not allowed).
The string with ‘–dport 22’ is the core of the whole security scheme: the action. Choose whatever other action (allowing access) is taken, if SSH connection doesn’t match.
It’s a good idea to establish a timeout, to restrict possible attacks to narrow the time frame (60 seconds is a wide interval; you might need to choose a shorter one):
iptables -A KNOCKING -m recent --rcheck --seconds 60 --name KSTAGE3 -j KPASSED
If more than 60 seconds have passed since knocking tests, no attempts will be accepted.
The below also imposes a 20-second restriction on the first knock:
iptables -A KNOCKING -m recent --rcheck --seconds 10 --name KSTAGE1 -j KTEST2
Finally, let’s route all unknown traffic to the first test:
iptables -A KNOCKING -j KTEST1
To test the above in action, insert proper ports and protocol names of your choice, restart iptables and test.
Note: I strongly recommend using VPS or whatever else you can discard/rebuild, in case something goes wrong. Alternately, make sure there are other access means, such as a VNC console.
You can grow the number of the tests arbitrarily; you will need chains and names (tags) like KTESTn and KSTAGEn for every additional test (stage), following the pattern above. Just don’t forget to use the rules like
iptables -A KTESTn -j KTEST1
for every additional stage so as to guarantee the user won’t have to enter all N stages to restart the sequence anew.
Using Knock Daemon
There are several port knocking daemons, that can help you avoid iptables tampering. For example, Zeroflux knock daemon (a free tool).
I will not describe all possible configurations in details as they are explained on the product pages quite well. Note that if knock daemon fails to run, your system might become inaccessible. So, please leave an additional access control possible, such as VNC console mentioned above (or physical access to server’s console, when possible).
If port knocking isn’t using the same strict short sequence, and if a non-standard port is used to connect to SSH, it can become quite tricky to gain access to the system via traditional automated means.
Jumping to Conclusions
As with every “security through obscurity” approach, port knocking should be used as a security amplifier only. Note that variations of the approach should be used when possible, using available means to prevent eavesdropping and traffic monitoring to make it harder to detect the correct sequence.
Experiment only if additional access means are available, in case something goes wrong.
May your Internet be secure!