Every open port on a firewall or a router is a security risk. That's why a technique called "port knocking" can be valuable. Port knocking is a method of allowing access to firewalled services given a preconfigured "knock." The knock consists of a sequence of access attempts to closed ports on a system. These attempts are logged and a daemon, which is preconfigured to watch for the sequences, opens up the corresponding port.
This provides the advantage of being able to keep a port closed until it is needed. Having a closed port makes it very difficult for a hacker to remotely compromise its associated service. For instance, having SSH running on a public server may be beneficial for remote management, but it also allows anyone to attempt to access the system. You can limit the range of IP addresses that are allowed to access a port, but that presents both security and access challenges of its own. Port knocking can allow you to have the best of both worlds: a port closed most of the time with the ability to be opened from anywhere by those in the know.
Most security breaches initiated from outside a network occur due to problems with well-known services. FTP and SSH have traditionally been susceptible to a variety of attacks because they use well-known ports. Since these services are typically used mostly by internal users, they are prime candidates for port knocking.
Port knocking is obviously not recommended for services you wish to be publicly accessible, such as HTTP and SMTP. These services need to allow connections from anywhere to provide access to Web pages and the e-mail system. However, for all other services, the best practice is to keep all non-essential ports locked down. Thus, a helpful service such as SSH is often kept closed due to security concerns.
This is where port knocking can be extremely helpful. First of all, a server configured to allow access based on knocks cannot be detected. Any port scan or direct connection attempt is automatically denied by the firewall software. And by selecting non-sequential port numbers for the knock (which we'll cover in minute), you can also alleviate concerns that a standard port scanner would be able to stumble upon the correct sequence. In this way, security can be maintained while making remote access available.
You may ask yourself, Why do I need this? The truth is, you may not. It merely adds on to current security, creating an undetectable layer between would-be attackers and your protected service. If a remote user doesn't know your server is listening on a particular port, then you can greatly reduce the number of attempts to compromise it. Furthermore, it is impossible to tell if a server is using port knocking, so a brute force attempt to guess an appropriate sequence is highly unlikely.
The details of port knocking
Port knocking can be configured in a number of ways. You can have access granted based on a static port sequence. For instance, a server can be set up to open TCP port 22 when it receives connection attempts on ports 2033, 3022, 6712, 4998, and 4113, in that order. The server can then be configured to close the port when another sequence is received, or based on a timer. The daemon that monitors the firewall log intercepts these denied attempts and can then grant access by injecting a new firewall rule to open the needed port.
Ports can also be configured to be opened dynamically. First you would establish a set of ports; in this example, we'll use 1040 through 1049. By providing a start sequence—such as 1042, 1044, 1043—you could prepare the server to next receive information on the desired port. The sequence of 1042, 1044, and 1043 could then be sent to let the server know you would like port 443 opened. Such a design allows for increased flexibility and the option of opening different ports as needed without a static configuration.
Encrypted communication is also possible to add an additional level of security. This can be beneficial if you're worried about your packets getting sniffed and someone stealing the knock sequence. Using encryption is the most secure approach to port knocking and is the method used in the prototype we will look at next.
Using knockclient and knockdaemon
A Perl prototype implementing port knocking is available for download from Portknocking.org. The file portknocking-0.1.tgz contains the knockclient and knockdaemon. This version allows ports 0 through 255 to be opened and automatically performs the encryption with Crypt::Blowfish. You simply call knockclient from the remote system with the necessary command options. For example, to open up port 22 to a particular IP on a remote system, you would use a command such as this.
In this example, we're requesting that port 22 be opened on the server at IP address 10.1.42.1 and that only a connection from IP address 192.168.0.1 be allowed. With a –time flag of zero, we're requesting it be opened with no time limit. A time value of 255 would close it. Any other value from 1 through 254 would open the port for that number of minutes. The shared cipher between the knockclient and knockdaemon allows the knock sequence to be encrypted and understood between the local and remote host. Also, in this implementation ports 745 through 1000 on the remote host are used. They will need to be closed and firewall logging will need to be turned on. The daemon will then listen for a default of eight knocks to these ports. The Perl module File::Tail is used to detect new lines added to the firewall log, and those lines are then parsed by the knockdaemon.
Although this is just a prototype, it works very well as is. Obviously, at the heart of port knocking is the idea that a remotely initiated sequence of knocks can open up a port. Writing such a program or adding to currently available resources is not difficult and can be customized for individual systems. If accessing a NAT IP address, for instance, you could configure rules to dynamically forward SSH access to internal hosts depending on the knock sequence. A port knock could also kick off a backup or run another job, based on your configuration.
Port knocking can be beneficial for adding an invisible layer of authentication. Only someone providing the correct sequence of port numbers can even have a chance to reach an available service, such as SSH. It adds the ability to accept connections from any IP address, such as a mobile/dynamic one, and create a level of trust based on that remote system knowing the correct knock sequence. Port knocking is best when used to complement more hardened security already in place.