Search

Port Knocking

Firewall administrators are challenged to
balance flexibility and security when designing a comprehensive
rule set. A firewall should provide protection against malfeasants,
while allowing trusted users to connect. Unfortunately, it is not
always possible to filter out the bad guys, because filtering on
the basis of IP addresses and ports does not distinguish connecting
users. Bad guys can and do come from trusted IP addresses. Open
ports remain a necessary vulnerability: they allow connections to
applications but also may turn into open doors for attack. This
article presents a new security system, termed port
knocking, in which trusted users manipulate firewall
rules by transmitting information across closed ports.

Briefly, users make connection attempts to sequences of
closed ports. The failed connections are logged by the server-side
packet filtering firewall and detected by a dæmon that
monitors the firewall log file. When a properly formatted knock
sequence, playing the role of the secret used in the
authentication, is received, firewall rules are manipulated based
on the information content of the sequence. This user-based
authentication system is both robust, being mediated by the kernel
firewall, and stealthy--it's not possible to detect whether a
networked machine is listening for port knocks. Port knocking does
not require any open ports, and it can be extended to transmit any
type of information encoded in a port sequence.

In commonly deployed firewalls, filtering is done either by
the IP address of the connecting host or by the port to which this
host is connecting. Firewalls examine and interact with packets
before any user authentication takes place; therefore, they do not
discriminate amongst the users making the connection. It is
expected that once the firewall has approved the packet and allowed
it to enter the network, downstream applications will handle user
authentication. Normally, this provides a sufficient balance
between protection and flexibility. Some IP ranges, say
cracker-friendly Internet cafés, may be closed completely to
incoming traffic, while hosts in other IP ranges may be allowed to
connect to ports otherwise unavailable to the general public
(proprietary/sensitive applications). Unfortunately, this type of
IP-based filtering has the potential to lock out trusted users from
your system. Flexibility is limited by the fact that nobody from
the blocked IP ranges can connect, regardless of their trust
statuses. At the same time, protection is undermined by the fact
that anyone from the blocked IP range physically can travel and
connect from an unfiltered host.

In the end, as long as ports remain open, network
applications are susceptible to attack. Using intrusion detection
systems and keeping applications up to date can go a long way
towards providing protection, but they do so against only known,
derivative or anticipated attacks.

To eliminate the risk associated with publically open ports,
port knocking provides an authentication system that works across
closed ports. The use of these ports, however, has to be subverted
because all packets are denied. Fortunately, in most firewalls that
perform even the most rudimentary logging, information already is
flowing across closed ports in the form of entries in a log file
indicating connection attempts.

Consider the following example. A handful of ports (100-109)
are configured to deny all traffic--no ICMP error packets are sent
back to the connecting client--and all attempted connections are
logged. In this example, the firewall IP is IPF and the connecting
client IP is IPC. The appropriate ipchains command to close the
ports and log connections is:

ipchains -A input -p tcp -s 0/0 -d IPF/32 100:109 -j DENY -l

A user attempts to connect from IPC to the following firewall
ports in sequence: 102,100,100,103. From the point of view of the
user, the connections fail silently. On the firewall, though, the
102,100,100,103 number sequence has been recorded.

The knock sequence appears in the firewall log, and the user
has transmitted data across the closed ports.

Any implementation of the port knocking system needs to
provide some basic functionality. First, some way to monitor the
firewall log file needs to be devised. A simple Perl application
that tails the file is presented in Listing 2, discussed more fully
later in the article. Second, a method is required to extract the
sequences of ports from the log file and translate their payload
into usable information. In this step it is important to be able to
(a) detect when a port sequence begins and ends, (b) correctly
detect a port sequence in the presence of spurious connection
attempts that are not part of the sequence and (c) keep track of
multiple port sequences arriving at the same time from different
remote IPs. The encoding used to generate the port sequence can be
designed to minimize the length of the sequence. For example, the
sequence 100,102 could correspond to one or a series of predefined
operations (for example, open port ssh/22 for 15 minutes for a
specific IP and then close the port). Finally, once the information
is derived from the sequence, the implementation must provide some
way to manipulate the firewall rules.

Benefits of Port Knocking

One of the key features of port knocking is it provides a
stealthy method of authentication and information transfer to a
networked machine that has no open ports. It is not possible to
determine successfully whether the machine is listening for knock
sequences by using port probes. Thus, although a brute-force attack
could be mounted to try to guess the ports and the form of the
sequence, such breach attempts could be detected easily.

Second, because information is flowing in the form of
connection attempts rather than in typical packet data payload,
without knowing that this system is in place it would be unlikely
that the use of this authentication method would be detected by
monitoring traffic. To minimize the risk of a functional sequence
being constructed by the intercepting party, the information
content containing the remote IP of the sequence can be
encrypted.

Third, because the authentication is built into the port
knock sequence, existing applications need not be changed.
Implementing one-time passwords is done easily by adjusting the way
particular sequences are interpreted. A sequence could correspond
to a request that a port be opened for a specific length of time
and then closed and never opened again to the same IP. Furthermore,
a one-time pad could be used to encrypt the sequence, making it
indecipherable by those without the pad.

Disadvantages of Port Knocking

To use port knocking, a client script that performs the knock
is required. The client and any associated data should be
considered a secret and kept on removable media, such as a USB key.
The use of the client imposes an overhead for each connection.
Certain locations, such as libraries or Internet cafés, may
not allow execution of arbitrary programs.

In order to use port knocking, a number of ports need to be
allocated for exclusive use by this system. As the number of such
ports increases, the knock sequences becomes shorter for a given
amount of information payload, because the number of coding symbols
is increased. Practically, 256 free privileged ports (in the 1-1024
range), not necessarily contiguous, usually can be allocated and
used to listen for port knocks.

Finally, any system that manipulates firewall rules in an
automated fashion requires careful implementation. For the scenario
in which no ports are initially open, if the listening dæmon
fails or is not able to interpret the knocks correctly, it becomes
impossible to connect remotely to the host.

Applications

In this section, three examples are outlined that illustrate
how the port knocking system can be used.

1. Single Port, Fixed Mapping

Connection to only one port (ssh/22) is required. The ssh
dæmon is running; all privileged ports are closed, including
ssh/22; and packets addressed to ports 30,31,32 are being logged.
The following port sequences are recognized:

31,32,30 open ssh/22 to connecting IP
32,30,31 close ssh/22 to connecting IP
31,30,32 close ssh/22 to connecting IP and disregard further knocks from this IP

The justifiably paranoid administrator can open the ssh/22
port on his system by initiating TCP connections to ports 31,32,30.
At the end of the ssh session, the port would be closed by using
the second sequence shown above. If the host from which the
administrator is connecting is not trusted (if, say, keystrokes may
be snooped), the use of the third sequence would deny all further
traffic from the IP, preventing anyone from duplicating the
session. This assumes the port sequence and system login
credentials are not captured by a third party and used before the
legitimate session ends.

In this example, only three sequences are understood by the
system, as the requirements call for only a handful of well-defined
firewall manipulations. The sequences were chosen not to be
monotonically increasing (30, 31, 32), so they would not be
triggered by remote port scans. If multiple ports are to be
protected by this system, a mapping needs to be derived between the
port sequence and a flexible firewall rule. This is covered in the
next example.

2. Multiple Port, Dynamic Mapping

In this example, a network may be running any number of
applications. Ports 100-109 are used to listen to knocks. The port
sequence is expected to be of the form:

The first and last three ports let the port knocking
dæmon know that a sequence is starting and ending. The next
four ports encode the port (abcd) to be opened. For example, if a
connection to port 143 is required, the sequence would be
100,101,104,103. The final element in the sequence is a checksum
that validates the sequence payload. In this example, the checksum
is 8 (1+4+3 mod 10). The sequence element therefore is 108, and the
full sequence would be

102,100,103 100,101,104,103 108 103,100,102

When this sequence is detected, port 143 would be made
available to the incoming IP address. If the port is open already,
the knock would rendered it closed. The knock can be extended to
include additional information, such as an anticipated session
length, that can be used to close the port after a set amount of
time.

3. Mapping with Encryption

The information contained in the knock sequence can be
encrypted to provide an additional measure of security. In this
example, 256 ports are allocated and logged. A knock map of the
form

remote IP port time checksum

is used where the remote IP, port, time and checksum (sum of
other fields mod 255) are encrypted. The encrypted string can be
mapped onto eight unsigned chars using Perl's pack("C*",STRING)
command, see Listing 1.

A minimal prototype Perl implementation of port knocking is
presented. The implementation is comprised of a knockclient,
responsible for originating the knock sequence, and a
knockdæmon, responsible for monitoring the firewall log and
manipulating the rules.

Knockclient

The complete client is shown in Listing 1. Lincoln Stein's
Crypt::CBC module is used as proxy to Crypt::Blowfish to carry out
encryption. The unencrypted knock sequence is comprised of seven
values: four IP bytes, a port (limited to the range 0-255 in this
implementation), a time flag and a checksum (mod 255). The time
flag determines how the dæmon reacts: 0 to open the port, 255
to close the port and any other value in the 1-254 range to open
the port and then close it after that many minutes. The knock on
the firewall (IP=IPF) to open port ssh/22 on IP=IPC and then have
the port close after 15 minutes would be executed by calling the
client as follows:

knockclient -i IPC -r IPF -p 22 -t 15

The client packs the list of seven integers, performs the
encryption and unpacks the string into unsigned chars (0-255).
These values are then mapped onto a sequence of ports in the
745-1000 range.

Knockdæmon

The knockdæmon is shown in Listing 2. This application
uses File::Tail to look for new lines in the firewall log file.
Lines corresponding to connection attempts to ports 745-1000 are
parsed for the remote IP and port number. An 8-element queue
storing the ports is maintained for each incoming IP. When the
queue size reaches 8, its contents are decrypted. If the decryption
is successful and the checksum is correct, appropriate action is
taken and the queue is cleared. If the decryption fails, the oldest
queue port element is removed and the dæmon continues
monitoring.

The firewall rules are manipulated by a system call to the
ipchains binary, although the IPChains Perl module by Jonathan
Schatz also may be used. If the port is to be closed, as indicated
by the time flag, Jose Rodrigues' Schedule::At module is used to
schedule the deletion of the rule using the at queue system.

Conclusion

Port knocking is a stealthy authentication system that
employs closed ports to carry out identification of trusted users.
This novel method provides the means of establishing a connection
to an application running on a completely isolated system on which
no ports initially are open.