implements an authorization scheme known as Single Packet Authorization (SPA) for
Linux systems running iptables, and for Mac OS X and FreeBSD systems running ipfw.
This mechanism requires only a single encrypted and non-replayed
packet to communicate various pieces of information including desired access
through an iptables or ipfw policy. The main application of this program is to
use iptables or ipfw in a default-drop stance to protect services such as
with an additional layer of security in order to make the exploitation of
vulnerabilities (both 0-day and unpatched code) much more difficult. An
passively monitors authorization packets via
and hence there is no "server" to which to connect in the traditional sense.
Any service protected by fwknop is inaccessible (by using iptables or ipfw to intercept
packets within the kernel) before authenticating; anyone scanning for
the service will not be able to detect that it is even listening. Single Packet
Authorization offers many advantages over port knocking, including non-replayability
of SPA packets, ability to use asymmetric ciphers (such as Elgamal), and SPA cannot
be broken by simply spoofing packets to duplicate ports within the knock sequence
on the server to break port knocking authentication. SPA packets can easily be
spoofed as well (this is a good thing in this context), and this makes it possible
to make it appear as though, say, www.yahoo.com is trying to authenticate to a
target system but in reality the actual connection will come from a seemingly
unrelated IP. Although the default data collection method in Single Packet
Authorization mode is to use libpcap to sniff packets off the wire, fwknop can also
read packets out of a file that is written by the iptables
pcap writer (or a separate sniffer process that is writing packet data to a file).
Authorization packets are either encrypted with the Rijndael block cipher
or via GnuPG and associated asymmetric ciphers. If the symmetric encryption
method is chosen, then the encryption key is shared between the
client and server (see the
file). If the GnuPG
method is chosen, then the encryption keys are derived from GnuPG key
rings. SPA packets generated by fwknop running as a client adhere
to the following format (before they are encrypted):
random number (16 bytes)
mode (command mode (0) or access mode (1))
if command mode => command to execute
else access mode => IP,proto,port
message digest (SHA256 / SHA1 / MD5)
Each of the above fields are separated by a ":" character due to the
variable length of several of the fields, and those that might contain
":" characters are base64 encoded. The message digest (SHA256 by default
in all versions of
greater than 1.9.1) allows the server to check message integrity after decryption,
and the 16 bytes of random data ensures (with high probability) that no two messages
are identical. This ensures that replay attacks are not possible against fwknop.
For each packet coming from an
server caches the SHA256 digest calculated over the entire packet and compares against
previous packet digests in order to detect attempted replay attacks. The digest
cache file is located at
and is not rotated so that the detection of duplicate SPA messages is maximized.
Both syslog and email alerts are generated if a replay is detected (although
this can be tuned via the
variable in the
file). By default, the
client sends authorization packets over UDP
port 62201, but this can be altered with the
argument. The server must first be configured to acquire the SPA data on
the changed protocol-port. Also, fwknop can send the SPA packet over a random
port via the --rand-port argument. See
for further details. See the
section for example invocations of the
-D, --Destination <IP-address>
client to authenticate with the
daemon/service at the destination address <IP> . The connection mode is discovered by the
daemon/service when it decrypts and parses the authentication packet.
-A, --Access <port list>
Provide a list of ports and protocols to access on a remote computer running
The format of this list is '<proto>/<port>...<proto>/<port>,
The vast majority of usages for
require the -A argument, but sending full commands with the --Server-cmd
argument via an SPA packet to be executed by
does not require this argument.
One of these options (see below) is required to tell the remote
daemon what IP should be let through the local firewall. It is recommend to use
the -R or -a options instead of -s in order to harden SPA communications against
possible MITM attacks.
-a, --allow-IP <IP-address>
Specify IP address that should be permitted through the destination
server firewall (this IP is encrypted within the SPA packet itself). This is
useful to prevent a Man-In-The-Middle (MTIM) attack where an SPA packet can be
intercepted en-route and sent from a different IP than the original. Hence, if
server trusts the source address on the SPA packet IP header then the attacker
gains access. The
option puts the source address within the encrypted
SPA packet, and so thwarts this attack. The
option is also useful to specify the IP that will be granted access when SPA
packet itself is spoofed with the
option. Another related option is -R (see below) which instructs the
client to automatically resolve the externally routable IP address the local
system is connected to by querying the
This is an important option, and instructs the
client and the
daemon/service to query
to determine the IP address that should be allowed through the iptables policy
at the remote
server side. This is useful if the
client is being used on a system that is behind an obscure NAT address. Note
that you can use the
option to have fwknop resolve an externally routable address by using the
specific web service instead of http://www.whatismyip.org (see below).
server offers the ability to provide SPA access through an iptables firewall
to an internal service by interfacing with the iptables NAT capabilities. So,
if the fwknopd server is protecting an internal network on RFC 1918 address
space, an external fwknop client can request that the server port forward an
external port to an internal IP, i.e. "--NAT-access 192.168.10.2:55000". In
this case access will be granted to 192.168.10.2 via port 55000 to whatever
service is requested via the --Access argument (usually tcp/22). Hence, after
sending such an SPA packet, one would then do "ssh -p 55000 user@host" and
the connection would be forwarded on through to the internal 192.168.10.2
system automatically. Note that the port "55000" can be randomly generated
via the --NAT-rand-port argument (described later).
server, a NAT operation can apply to the local system instead of being
forwarded through the system. That is, for iptables firewalls, a connection
to, say, port 55,000 can be translated to port 22 on the local system. By
making use of the --NAT-local argument, the fwknop client can be made to
request such access. This means that any external attacker would only see
a connection over port 55,000 instead of the expected port 22 after the SPA
packet is sent.
--URL <web resolution URL>
This option is used in conjunction with the
option so that fwknop will resolve the externally routable IP address (useful
if fwknop is run on a system being a NAT) via a web service URL supplied on
the command line. A custom web resolution CGI script is available at the URL
below if http://www.whatismyip.org is not available:
to acquire GnuPG key password from a running
--gpg-agent-info <connection info>
Specify the value of the GPG_AGENT_INFO environment variable as returned
command. If the
command line argument is used instead of
then fwknop assumes that the GPG_AGENT_INFO environment variable has already
been set in the current shell.
Use the key that GnuPG defines as the default, i.e. the key that is specified
variable is not defined
, then GnuPG tries to use the first suitable key on
its key ring. If the user does not know the password for this key, then the
standard password error will be thrown by GnuPG and reported back to the
Specify the path to the GnuPG directory; normally this path is derived from the
home directory of the user that is running the
client. This is useful when a 'root' user wishes to log into a remote machine
daemon/service does not permit 'root' login.
--gpg-recipient <key ID>
Specify the GnuPG key ID, e.g. "1234ABCD" (see the output of "gpg --list-keys")
of the recipient of the Single Packet Authorization message. This key is imported
server and the associated private key is used to decrypt the SPA packet. The
recipient's key must first be imported into the client GnuPG key ring.
--gpg-signing-key <key ID>
Specify the GnuPG key ID, e.g. "ABCD1234" (see the output of "gpg --list-keys")
to use when signing the SPA message. The user is prompted for
the associated GnuPG password to create the signature. This
adds a cryptographically strong mechanism to allow the
daemon on the remote server to authenticate who created the SPA message.
to allow all output from the
process that is used by fwknop in GnuPG mode. This is primarily used for debugging
purposes if it appears that the GnuPG encrypt/decrypt is not performing correctly.
By default the
client instructs gpg to not reference any options file in gpg mode, but this
command line argument can be used to re-enable them.
Specify the path to the user home directory where files such as .fwknop.hosts
or .fwknop.run should be stored or retrieved.
client to run with the same command line arguments that were used in a previous execution.
This option is useful because the clients'
command line can be complex and difficult to recall.
to use the same command line arguments that were used to authenticate to
This option instructs the
to be as quiet as possible and only print absolutely necessary information to
client to form an SPA packet that contains the special-case IP
address "0.0.0.0" which will inform the destination
SPA server to use the source IP address from which the SPA packet originates as
the IP that will be allowed through upon modification of the firewall ruleset.
This option is useful if the fwknop client is deployed on a machine that is
behind a NAT device. The permit-address options
are mutually exclusive.
Specify the port number where
accepts packets via libpcap or ulogd pcap writer. By default fwknopd looks for
authorization packets over UDP port 62201.
Instruct the fwknop client to send an SPA packet over a random destination port
between 10,000 and 65535. The fwknopd server must use a PCAP_FILTER variable
that is configured to accept such packets. For example, the PCAP_FILTER variable
could be set to:
udp dst portrange 10000-65535
Usually fwknop is used to request access to a specific port such as tcp/22 on a
system running fwknopd. However, by using the --NAT-rand-port argument, it is
possible to request access to a particular service (again, such as tcp/22), but
have this access granted via a random translated port. That is, once the fwknop
client has been executed in this mode and the random port selected by fwknop is
displayed, the destination port used by the follow-on client must be changed to
match this random port. For SSH, this is accomplished via the -p argument.
See the --NAT-local and --NAT-access command line arguments to fwknop for
additional details on gaining access to services via a NAT operation.
client to write a newly created SPA packet out to a file so that it can be
examined off-line. The default path is
where <pid> is the process ID of the fwknop client process, but this can be
changed with the --Save-packet-file argument (see below).
Specify the file to write a new SPA packet to in
mode fwknop normally overwrite the file used to save a new SPA packet, but
this command line argument instructs fwknop to append a new SPA packet to
the file instead. This is useful for generating large sets of SPA packets
in order to test randomness or encryption properties.
By default, the
daemon on the server side enforces time synchronization between the clocks
running on client and server systems. The fwknop client places the local time
within each SPA packet as a time stamp to be validated by the fwknopd server
after decryption. However, in some circumstances, if the clocks are out of
sync and the user on the client system does not have the required access to
change the local clock setting, it can be difficult to construct and SPA
packet with a time stamp the server will accept. In this situation, the
--time-offset-plus option can allow the user to specify an offset (e.g.
"60sec", "60min", "2days", etc.) that is added to the local time.
This is similar to the --time-offset-plus option (see above), but subtracts
the specified time offset instead of adding it to the local time stamp.
Display the last command-line arguments used by
Display the last command-line arguments used to contact a SPA server running on
Send an SPA packet over a raw socket of the specified protocol. Accepted
values are tcp, udp, and icmp. This is useful if you want to send the SPA
packet over an orphaned TCP ACK or an ICMP packet.
Spoof the source address from which the
client sends SPA packets. This requires root on the client side access since a raw socket
is required to accomplish this. Note that the
argument can be given in this mode in order to pass any
keyword that might
be specified in
Specify the username that is included within SPA packet. This allows
client to satisfy any non-root
keyword on the
mode requires that the
client is executed as root).
When using the
argument to send an SPA packet over and ICMP packet, the ICMP type may be set
with this command line argument. The default is "8" for an ICMP echo-request
(see also the
When using the
argument to send an SPA packet over and ICMP packet, the ICMP code may be set
with this command line argument. The default is "0" for an ICMP echo-request
(see also the
to restrict message length to
bytes, and the client will not send an SPA packet that is larger than this
(i.e. perhaps a long command was included in --Server-cmd mode). This alters
the default value of 1500 bytes. See also the
MAX_SNIFF_BYTES variable in
on the SPA server.
client send an SPA packet as a web request over HTTP. This requires that the
is also running a webserver to receive the SPA web request. The web request
is built as a modified version of base64-encoded data where the "+" and "/"
chars are replace with "-" and "_" respectively (to avoid URL encoding issues).
--HTTP-proxy <proxy host>
option allows the
client to send SPA packets through an HTTP proxy when the
option is also used. The expected format for the argument is
and an optional port number is supported with the
--HTTP-user-agent <agent string>
Specify the HTTP user-agent whenver the
client is used to send an SPA packet over an HTTP request, or when the
option is used. The default user-agent is "Fwknop/VERSION", so "Fwknop/1.9.12"
for the 1.9.12 release.
client send an SPA packet over an established TCP connection (created by the fwknop
client to the specified listening port on the server with the
argument). This is not normally done, but is useful for compatibility with the Tor
for strong anonymity; see
In this case, the
server uses the
daemon to listen on a TCP port (62201 by default).
Display usage information and exit.
Display version information and exit.
client in verbose mode.
Provide a locale setting other than the default "C" locale.
Do not set the locale at all so that the default system locale will apply.
This is for command mode only (i.e. when you want to send a command across
to a system running
and have it execute the command). This option is not needed when trying to
gain access to a service via the SPA mechanism. To use this feature, please
ensure that ENABLE_CMD_EXEC; is set in the file
server you are sending the command to.
The --Server-cmd argument allows a complete command (e.g. "ping -c 1 www.yahoo.com",
or "iptables -t nat -A PREROUTING -p tcp -s 65.x.x.x --dport 443 -i eth0 -j DNAT --to 192.168.10.20:443")
to be send to an
server, which will execute the command as root. Command execution is enabled only
ENABLE_CMD_EXEC keyword is given in/etc/fwknop/access.conf
(note that commands can easily be restricted with the
keyword as well).
Legacy Port-knock mode only
All of the following options in this section are for the traditional port knocking
mode mode. This is a legacy mode and is
the preferred or recommended mode next to Single Packet Authorization ( see
for details on why).
Specify a port offset to use when running
in encrypted knock mode. The default is 61000.
Rotate the protocol across tcp and udp for
encrypted sequences. This just adds one more additional layer of obfuscation
to an encrypted sequence.
This command line switch provides an interface to
the old port knocking method if
the mode argument is "knock". If the
argument is not given then the
client defaults to using the SPA method which provides much better
security characteristics than port knocking (encrypted or not).
-t, --time-delay <seconds>
Specify a time delay to introduce between successive
connection attempts. This option is used by the
client. On the server side,
uses the variables MIN_TIME_DIFF
and MAX_TIME_DIFF to control whether the time delay actually means
something (i.e. if the MIN_TIME_DIFF is 2 seconds for a SOURCE block,
then the argument to the --time-delay option must be at least 2 at the
-u, --user-rc <rc-file>
The default connection rc file the
client uses to know what shared port knocking sequence to send to a destination machine
is defined in the file
The path to this file can be changed with the
command line option.
Contains the last command line arguments that the
client was invoked with.
Contains the last command line arguments for individual hosts that the
client has been used to gain access to. By using the
switch, these arguments can be recalled and used.
(only used in --gpg-agent mode).
The following examples illustrate the command line arguments that could
be supplied to the
client in a few situations:
Access mode examples
Packet contents printed to stdout at the
client when creating a 'access mode' SPA packet:
Use the Single Packet Authorization mode to gain access to tcp/22 (ssh)
and udp/53 running on the system 10.0.0.123 from the IP 192.168.10.4:
$ fwknop -A 'tcp/22,udp/53' -a 192.168.10.4 -D 10.0.0.123
Same as above example, but gain access from whatever source IP is seen
by the fwknop server (useful if the fwknop client is behind a NAT device):
$ fwknop -A 'tcp/22,udp/53' -s -D 10.0.0.123
Same as above example, but use the IP identification website http://www.whatismyip.com/
to derive the client IP address. This is a safer method of acquiring the client IP
address than using the
option because the source IP is put within the encrypted
packet instead of having the
daemon grant the requested access from whatever IP address the SPA packet originates:
$ fwknop -A 'tcp/22,udp/53' -R -D 10.0.0.123
Use the Single Packet Authorization mode to gain access to tcp/22 (ssh)
and udp/53 running on the system 10.0.0.123, and use GnuPG keys to encrypt
Instruct the fwknop server running at 10.0.0.123 to allow 172.16.5.4 to
connect to TCP/22, but spoof the authorization packet from an IP associated
# fwknop --Spoof-src 'www.yahoo.com' -A tcp/22 -a 172.16.5.4 -D 10.0.0.123
Command mode examples
Please ensure that ENABLE_CMD_EXEC; is set in the file
server you are attempting to connect to.
Packet contents printed to stdout at the
client when creating a 'command mode' SPA packet:
Random data: 4621962433020664
Type: 0 (command mode)
Cmd: echo "The commands sent - minus quote charaters around the command" & sleep 10; echo "The End"
SHA256 sum: eN8c8mNArZxF066iulbxlTK4Gt/EO0ALLYwzVzCkXww
Instruct the fwknop server running at 10.0.0.123 to send a single ICMP
echo request to www.yahoo.com:
This connection mode is a legacy mode and is
the preferred or recommended mode.
Packet contents printed to stdout at the
client when in 'port-knock mode':
Send an encrypted knock sequence to the IP "10.0.0.123" instructing the
fwknop daemon running there to open tcp port 22 to source address
$ fwknop --Server-mode 'knock' -A tcp/22 -a 192.168.10.4 -D 10.0.0.123
Same as above, but this time instruct the remote fwknop daemon to open
tcp port 22 to whatever source address the encrypted sequence originates
from (useful if the fwknop client is behind a NAT device):
$ fwknop --Server-mode 'knock' -A tcp/22 -s -D 10.0.0.123
Same as above, but rotate the knock sequence through the tcp and udp
protocols (remember that iptables must be configured to log both tcp and
udp packets to the default port range of 61000-61255):
$ fwknop --Server-mode 'knock' -A tcp/22 -s -r -D 10.0.0.123
Same as above, but change the base port for the encrypted sequence to
55000 (the default is 61000):
Send a shared knock sequence to the IP 10.11.11.123. The fwknop client
will read the sequence out of the file
and the server will read the sequence out of
$ fwknop --Server-mode 'knock' -D 10.11.11.123
requires perl. To take advantage of all of the authentication and access management features of the
daemon/service a functioning iptables firewall is required on the underlying
operating system. If fwknop is being run in the legacy port knocking mode,
then iptables must log packets via syslog, and ideally the
argument will be specified in the iptables logging rule so that the
be able to use a strategy similar to
to passively fingerprint operating systems.
can be run in debug mode with the
command line option. This will
disable daemon mode execution, and print verbose information to the screen
on STDERR as packets are received.