Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Contact Us
Online Help
Domain Status
Man Pages

Virtual Servers

Topology Map

Server Agreement
Year 2038

USA Flag



Man Pages

Manual Reference Pages  -  DOORMAND (8)


doormand - The doorman daemon


See Also


doormand [-h] [-v] [-D] [-f config-file]


The doorman daemon "guards the door" of a host running TCP servers, admitting only recognized parties. (The current implementation of the doorman can only protect TCP services.) It allows a server which is not intended for general public access to run with most (or even all) of it’s TCP ports closed to the outside world.

A server may thus be made invisible to a cracker’s portscans; attacks can be mounted on such a host only if it’s existence is known by other means. Moreover, any vulnerability in a specific program is made much more difficult to exploit, as the the firewall simply drops packets from parties the doorman does not recognize.

The doorman watches all packets arriving at a specified interface on a specified UDP port. When a valid packet from knock is detected (see ’conditions’ below), doormand runs the first of two shell scripts, as configured in It is the responsiblity of these scripts to manipulate the firewall rules to allow a TCP connection from the originating IP address.

There is one script to add rules, and one to delete rules. The first call to the ’add’ script sets a broad firewall rule; open to one destination port, but from any source port at the originating IP address. The second call to that script sets a narrow rule; open to only one one source port at the originating IP address.

Between the knock and a connection on the requested port, the doorman will wait for a configurable number of seconds. If none is made within that time, the ’delete’ script is run to re-close the firewall. If a connection is made, the source port of that connection is noted; the ’add’ script is run to narrow the firewall hole, and then the ’delete’ script is run to delete the first, broader, rule.

The sequence of calls to the scripts, if all goes well, is this:

    a valid ’knock packet’ received...
 *--> add broad rule
    wait...  a TCP connection allowed by the broad rule is made...
 *--> add narrow rule (we now know the source port)
 *--> delete broad role (don’t need it anymore)
    the client & server converse; eventually, the client goes away...
 *--> delete narrow rule

No reply is made to a knock; success is apparent to the client only when it discovers that a connection to the requested service can be made.


-h 'help’; print a message explaining the options and quit.
-v 'version’; print the version number and quit.
-D Run in "Debug" mode. Doormand will not daemonize, and remain attached to the console; file ownership and permission checks are skipped, and logging is done to stdout.
-X Do a hex dump of all UDP packets received on the listening port, including the data-link header. Use of ’-X’ is not usually necessary; only used for debugging if the doorman ignores all knocks. See ’man 5’.
-f config-file
  Use the specified configuration file. The default configuration file is named "" in directory "/usr/local/etc/doormand", or the directory specified by the configure "--sysconfdir" option when building doormand and knock.


A knock packet contains 4 space-delimited ASCII strings: portnumber, groupname, a "random" decimal number called a "tag", and an MD5 hash formatted as a hexadecimal number of 32 characters. The knock client creates this hash from the the group’s shared secret, salted with the first 3 fields. The doorman performs the same MD5 operation, and checks that the two hashes are identical. If they are, the knock client must know the secret, and is let in.

Therefore, in order for a knock to succeed, the following conditions must be met:

1. the groupid must be in the doorman’s ’guestlist’ file

2. the secret must match that in the guestlist record for that group

3. the IP address of the client machine’s interface must match one of the addresses in the guestlist record.

4. the service requested must be in the guestlist record

5. the tag must not be "stale"; that is, it must not have already been used on a successful knock. (The doorman keeps a hashed table of information about successful knocks.)


Ready-made scripts are supplied for Linux, FreeBSD, netBSD, and OpenBSD:

ipchains_add & ipchains_delete ... Linux 2.2 ’ipchains’
iptables_add & iptables_delete ... Linux 2.4+ ’iptables’
ipf_add & ipf_delete ... netBSD ’ipf’
ipfw_add & ipfw_delete ... FreeBSD ’ipfw’
pfctl_add & pfctl_delete ... OpenBSD ’pf’

The ’firewall-add’ and ’firewall-del’ records in specify which set of these scripts will be executed.

For other firewall types, scripts must be supplied by the administrator. Both ’add’ and ’delete’ scripts are invoked with this parameter list :

        $1         $2      $3         $4       $5

interface-name   src-ip  src-port   dest-ip  dest-port

When adding or deleting "broad" rules, the value of $3, the src-port parameter, will be set to a single ’0’ character. Add & delete scripts may check for a zero value to determine the firewall command to be issued.

Both scripts must return a status by writing a string to stdout. A normal return is indicated by single ascii ’0’ (0x30) character.

Errors encountered while running the script should be indicated by returning a non-zero integer (perhaps ’errno’, but ’-1’ will do), followed by a numeric severity level:

  EMERG   0    ALERT  1    CRIT 2    ERROR 3


Severity values of 0..3 will cause the forked doormand process for that connection to log the event and exit. Levels 4..7 will cause the event to be logged, but processing will continue.

The message written to the logfile will also contain whatever text is written after the severity level; this may be extra information on the nature of the error, if so desired by the script writer.

An example error return:
-1 3 Permission denied


SIGHUP may be used force the parent doormand process to re-read it’s configuration and guest-list files. Any children preparing new, or monitoring established connections will continue to use old configuration data.

SIGTERM, SIGSTOP, SIGQUIT, and SIGINT may be used to shut the doornman down in an orderly fashion. Any children processing connections will exit, after removing any firewall rules for which they are responsible. There may be a delay of up to "connection_delay_2" (man ) before children exit.

FILES the configuration file for doormand. (man 5

guestlist: the list of guest (or group) names containing a secret for authentication, and information about which services they may connect to, and from what IP addresses. (man 5 guestlist) the process-ID file created by the parent doormand process. The full pathname is specified by the ’pidfile’ record of Doormand will refuse to run if this file already exists; it must be removed manually after a program crash.

A hash archive: a file containing information on previous successful knocks. In the current implementation, this file should not be shared with other doorman processes. If the ’hash-archive-size’ configuration parameter is changed to a smaller value, some stored knocks may be lost due to hash collisions upon insertion into the new table. The archive stores the 128-bit MD5 hash contained in the knock, and the time, as GMT, that the successful knock was received. The size of the archive should be made as large as possible without consuming an inconvenient amount of memory and disk space. This is to reduce the number of hash collisions; in the event of a collision where the two MD5 hashes match exactly, the doorman assumes a "replay" attack, logs a warning message, and refuses entry. However, in the event of a collision where the MD5 hashes do not match, the new knock simply over-writes the old.

A firewall-add script.

A firewall-delete script.


Three vulnerabilites of this approach spring immediately to mind. The first is that the guest "secrets" must exist as plaintext in the guestlist file, and may also exist (plaintext again!) in the client’s .knockcf or knock.cfg file. These secrets must therefore NEVER correspond to ANY passwords ANYWHERE ELSE.

Note also that coredumps from doormand crashes will also contain all guest-list secrets in plaintext.

Second, it is still possible for a cracker, connected to the same client machine as a legitimate user (L.U.), and able to sniff L.U.’s traffic, to ’slip in’ before L.U.
(This problem is mitigated somewhat by the fact that the attacker would still have to authenticate. Hoewever, he might briefly be able to launch attacks against vulnerabilities in the server at that port.)

Third, the doorman runs with root permissions. It is therefore possible that the doorman itself may be attacked, in hopes of exploiting a buffer overflow or similar bug.

The doorman does present a formidable barrier to a cracker, but not an impenetrable one.


knock(1), knockcf(5), guestlist(5),


doormand and knock are an implementation of an original idea by Martin Krzywinski. See his site at


Copyright (c) 2003-2005, J.B.Ward

Search for    or go to Top of page |  Section 8 |  Main Index

Doorman, V0.81 DOORMAND (8) Aug 14, 2005

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.