Bauteile-Verwaltung part-db

miscellaneous stuff

portknocking -- adding an extra layer of security to your openSSH installation

This text is still under construction. It is already available on the web as some of the information might be useful.

First of all, what is portknocking? Portknocking is a technique to externally open ports on the firewall after the external host has sent network traffic predefined by the system administrator. For instance the external host could try to connect (i.e. "knock") to a predefined sequence of closed ports. After connection attempts to all ports in the right order, the protected port is opened. Note that the host carrying out the sequence does not get any response from the firewall what the current state is or if the protected port is now open.

There are very sophisticated portknocking implementations around, which feature protection by cryptographic techniques. Here, however, we restrict ourselves to a simple approach using just connection attempts to a predefined sequence of ports. The very simple implementation presented here relies on the recent extension of the IPtables firewall implementation. These building blocks are available on virtually any Linux installation. Moreover, the knocking sequence can be generated using programs that are present on almost all client systems. Even web browsers are suitable as the only requirement is that the program can open a TCP connection.

Obviously, while the implementation presented here is very simple on the server and client side, it is susceptible to replay attacks. This means that an attacker that has the ability to eavesdrop the communication somewhere between the client and the server can open the protected port.

See this Wikipedia article for an overview over the different implementations.


To gain access to my home network, I have a secure shell server running on standard port 22 of the dynamic IP address of my DSL internet connection. However, there are many (unsuccessful) attempts to log in as root via ssh. To get an impression, some unix magic is in place.
cl@raspberrypi ~ $ sudo zgrep ssh /var/log/auth.log.2 | perl -n -e'/.*Failed password for root from ([\.0-9]+) port/ && print "$1\n";' | sort | uniq -c | sort -n
This lists the IPs of the hosts from which the failed login attempts originated from.

To keep these scans from even reaching my ssh installation, I installed portknocking on my Raspberry Pi.

Importance of a time limit for the steps in the sequence

Let's consider the following very simple model of a portknocking implementation. For illustration, we restrict ourselves to a configuration with two ports to knock until the ssh port is open. So, after port p1 has been contacted, port p2 has to be knocked. Knocking port p2 before port p1 has been contacted has no effect. After knocking p2, the ssh port is open.

We introduce the symbols:

  • 1 -- port p1 knocked
  • 2 -- port p2 knocked
  • S -- connection to ssh port established
There are 6 possible combinations to probe these three ports in a brute force scan: 12S, 2S1, S12, 21S, 1S2, and S21. As there is no timeout, the time spend by the attacker while probing other ports (that have no effect) is irrelevant. This means that the probability to hit the right combination is 1/(3!) = 16.7%. For a sequence of 4 ports (including the ssh port), one finds 1/(4!) or about 4.2%. For longer sequences the factorial will grow rapidly, resulting in very small probabilities to find the correct sequence. (One might argue that since ssh is always among the most important targets on a Linux installation, the number of possible permutations is smaller with the third step always being to attempt a connection to the ssh port.)

Implementation with time limit

We consider the same installation, but now with a timeout at each state transition. After transitioning to the next state, one has to proceed again before a timeout occurs. This makes it considerably more challenging for the attacker to succeed just by random, brute force scanning.

To study this, I set up a Monte Carlo simulation in MATLAB (Files: port_knock_study.m and port_knock_study_worker.m).

Probability of success to find correct sequence by chance when port scanning a host
Figure: Probability to succeed finding the correct sequence while performing brute force scan. The Monte Carlo simulation assumes a timeout of 5 seconds and a sequence length of 3. For example, to be successful in more than 5% of all scans, the attacker had to do more than 3300 port probes per second. This is quite aggressive and could be thwarted by throttling SYN packets on a per-host basis. For very aggressive scanning the timing becomes meaningless and the simulation obtains the probability already derived in the considerations above.
In the Figure, a simulation result is shown. The probability to find the right sequence when doing a brute force scan is indicated as a function of the aggressiveness of the scan. For typical scenarios, a clear improvement can be seen. Especially, this very simple implementation is already superior to running without portknocking. And random scans for the ssh root login do no longer swamp your logfiles.

Of course, the implementation of portknocking must not result in a disregardful administration attitude. It is just an additional layer of security and software maintenance (i.e. deployment of security updates and reasonable configuration) has to continue.

An attacker "just" has to hit the sensitive ports in the right order within the time window. Any other ports touched in between are irrelevant. Therefore, do not make the time window too long; otherwise increases the likelihood that the SSH port is exposed to the attacker. 5 seconds should be OK.

A few remarks concerning port scanners:

  • Do not use neighboring TCP ports for the different steps of the knocking procedure. Otherwise, a linear port scan might open the SSH port.
  • Additionally, do not use ports used by standard protocols, as those are more likely to be scanned by scanners such as nmap. See the nmap-services file from the download archive of nmap version 6.49BETA5.
  • If you happen to sit behind an Internet router and you forward the ports (SSH ports and portknocking signal ports) to the protected machine (for instance when you want to connect to your home network from the outside): Ensure that the TCP ports used for port knocking give the same signature as the ports rejected by the Internet router's firewall, for instance timeout (in iptables this corresponds to DROP).
  • As there is a remote chance for an attacker to identify the proper port knocking sequence, consider hardening the SSH server as well. For instance, you may consider disabling root logins (directive PermitRootLogin). Most brute force scans aim at the root account, so this adds an extra layer of security to your SSH installation.
  • This simple implementation can be tricked by replaying the captured sequence. So any attacker who can eavesdrop on your network traffic can break this portknocking implementation. There are implementations that rely on cryptographic methods, so use these if possible replay attacks are a problem for you.