# fwknop - Single Packet Authorization

## Introduction
fwknop implements an authorization scheme known as Single Packet Authorization
(SPA) for strong service concealment. SPA requires only a single packet which
is encrypted, non-replayable, and authenticated via an HMAC in order to
communicate desired access to a service that is hidden behind a firewall in a
default-drop filtering stance. The main application of SPA is to use a firewall
to drop all attempts to connect to services such as SSH in order to make the
exploitation of vulnerabilities (both 0-day and unpatched code) more difficult.
Because there are no open ports, any service that is concealed by SPA naturally
cannot be scanned for with Nmap. The fwknop project supports four different
firewalls: iptables, firewalld, PF, and ipfw across Linux, OpenBSD, FreeBSD,
and Mac OS X. There is also support for custom scripts so that fwknop can be
made to support other infrastructure such as ipset or nftables.

SPA is essentially next generation Port Knocking (PK), but solves many of the
limitations exhibited by PK while retaining its core benefits. PK limitations
include a general difficulty in protecting against replay attacks, asymmetric
ciphers and HMAC schemes are not usually possible to reliably support, and it
is trivially easy to mount a DoS attack against a PK server just by spoofing an
additional packet into a PK sequence as it traverses the network (thereby
convincing the PK server that the client doesn't know the proper sequence). All
of these shortcomings are solved by SPA. At the same time, SPA hides services
behind a default-drop firewall policy, acquires SPA data passively (usually via
libpcap or other means), and implements standard cryptographic operations for
SPA packet authentication and encryption/decryption.

SPA packets generated by fwknop leverage HMAC for authenticated encryption in
the encrypt-then-authenticate model. Although the usage of an HMAC is currently
optional (enabled via the `--use-hmac` command line switch), it is highly
recommended for three reasons:

   1. Without an HMAC, cryptographically strong authentication is not possible
with fwknop unless GnuPG is used, but even then an HMAC should still be
applied.
   2. An HMAC applied after encryption protects against cryptanalytic CBC-mode
padding oracle attacks such as the Vaudenay attack and related trickery (like
the more recent "Lucky 13" attack against SSL).
   3. The code required by the fwknopd daemon to verify an HMAC is much more
simplistic than the code required to decrypt an SPA packet, so an SPA packet
without a proper HMAC isn't even sent through the decryption routines.

The final reason above is why an HMAC should still be used even when SPA
packets are encrypted with GnuPG due to the fact that SPA data is not sent
through libgpgme functions unless the HMAC checks out first. GnuPG and libgpgme
are relatively complex bodies of code, and therefore limiting the ability of a
potential attacker to interact with this code through an HMAC operation helps
to maintain a stronger security stance. Generating an HMAC for SPA
communications requires a dedicated key in addition to the normal encryption
key, and both can be generated with the `--key-gen` option.

fwknop encrypts SPA packets either with the Rijndael block cipher or via GnuPG
and associated asymmetric cipher. If the symmetric encryption method is chosen,
then as usual the encryption key is shared between the client and server (see
the `/etc/fwknop/access.conf` file for details). The actual encryption key used
for Rijndael encryption is generated via the standard PBKDF1 key derivation
algorithm, and CBC mode is set. If the GnuPG method is chosen, then the
encryption keys are derived from GnuPG key rings.

## Use Cases
People who use Single Packet Authorization (SPA) or its security-challenged cousin
Port Knocking (PK) usually access SSHD running on the same system where the SPA/PK
software is deployed. That is, a firewall running on a host has a default-drop
policy against all incoming SSH connections so that SSHD cannot be scanned, but a
SPA daemon reconfigures the firewall to temporarily grant access to a passively
authenticated SPA client:

![SPA-basic-access-SSHD](doc/images/SPA_basic.png) "Basic SPA usage to access SSHD"

fwknop supports the above, but also goes much further and makes robust usage of NAT
(for iptables/firewalld firewalls). After all, *important* firewalls are usually gateways
between networks as opposed to just being deployed on standalone hosts.  NAT is commonly
used on such firewalls (at least for IPv4 communications) to provide Internet access to
internal networks that are on RFC 1918 address space, and also to allow external
hosts access to services hosted on internal systems.

Because fwknop integrates with NAT, SPA can be leveraged to access internal services
*through* the firewall by users on the external Internet. Although this has plenty of
applications on modern traditional networks, it also allows fwknop to support cloud
computing environments such as Amazon's AWS:

![SPA-Amazon-AWS-cloud](doc/images/SPA_AWS_network_setup.png) "SPA usage on Amazon AWS cloud environments"

## User Interface
The official cross-platform fwknop client user interface *fwknop-gui*
([download](https://incomsystems.biz/fwknop-gui/), [github](https://github.com/jp-bennett/fwknop-gui))
is developed by Jonathan Bennett. Most major client-side SPA modes are supported
including NAT requests, HMAC and Rijndael keys (GnuPG is not yet supported), fwknoprc
stanza saving, and more.  Currently fwknop-gui runs on Linux, Mac OS X, and
Windows - here is a screenshot from OS X:
![fwknop-gui-OS-X-screenshot](doc/images/fwknop-gui-OSX.png) "fwknop-gui on Mac OS X"
Similarly, an updated
[Android client](https://github.com/jp-bennett/Fwknop2) is
[available](https://incomsystems.biz/fwknop-gui/android.php) as well.

## Tutorial
A comprehensive tutorial on fwknop can be found here:

[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html)


## Features
The following is a complete list of features supported by the fwknop project:

 * Implements Single Packet Authorization around iptables and firewalld firewalls
   on Linux, ipfw firewalls on *BSD and Mac OS X, and PF on OpenBSD.
 * The fwknop client runs on Linux, Mac OS X, *BSD, and Windows under Cygwin.
   In addition, there is an [Android app](https://github.com/jp-bennett/Fwknop2/releases)
   to generate SPA packets.
 * Supports both Rijndael and GnuPG methods for the encryption/decryption of
   SPA packets.
 * Supports HMAC authenticated encryption for both Rijndael and GnuPG. The order
   of operation is encrypt-then-authenticate to avoid various cryptanalytic problems.
 * Replay attacks are detected and thwarted by SHA-256 digest comparison of valid
   incoming SPA packets. Other digest algorithms are also supported, but SHA-256 is
   the default.
 * SPA packets are passively sniffed from the wire via libpcap. The fwknopd server
   can also acquire packet data from a file that is written to by a separate Ethernet
   sniffer (such as with `tcpdump -w <file>`), from the iptables ULOG pcap writer, or
   directly via a UDP socket in `--udp-server` mode.
 * For iptables firewalls, ACCEPT rules added by fwknop are added and deleted (after
   a configurable timeout) from custom iptables chains so that fwknop does not
   interfere with any existing iptables policy that may already be loaded on the
   system.
 * Supports inbound NAT connections for authenticated SPA communications (iptables
   firewalls only for now). This means fwknop can be configured to create DNAT
   rules so that you can reach a service (such as SSH) running on an internal system
   on an RFC 1918 IP address from the open Internet. SNAT rules are also supported
   which essentially turns fwknopd into a [SPA-authenticating gateway](https://www.cipherdyne.org/blog/2015/04/nat-and-single-packet-authorization.html)
   to access the Internet from an internal network.
 * Multiple users are supported by the fwknop server, and each user can be assigned
   their own symmetric or asymmetric encryption key via the /etc/fwknop/access.conf
   file.
 * Automatic resolution of external IP address via
   [https://www.cipherdyne.org/cgi-bin/myip](https://www.cipherdyne.org/cgi-bin/myip)
   (this is useful when the fwknop client is run from behind a NAT device). Because
   the external IP address is encrypted within each SPA packet in this mode,
   Man-in-the-Middle (MITM) attacks where an inline device intercepts an SPA packet
   and only forwards it from a different IP in an effort to gain access are thwarted.
 * [Port randomization](https://www.cipherdyne.org/blog/2008/06/single-packet-authorization-with-port-randomization.html)
   is supported for the destination port of SPA packets as well
   as the port over which the follow-on connection is made via the iptables NAT
   capabilities. The later applies to forwarded connections to internal services and
   to access granted to local sockets on the system running fwknopd.
 * Integration with Tor (as described in this
   [DefCon 14](http://www.cipherdyne.org/fwknop/docs/talks/dc14_fwknop_slides.pdf) presentation).
   Note that because Tor uses TCP for transport, sending SPA packets through the Tor
   network requires that each SPA packet is sent over an established TCP connection,
   so technically this breaks the "single" aspect of "Single Packet Authorization".
   However, Tor provides anonymity benefits that can outweigh this consideration in
   some deployments.
 * Implements a versioned protocol for SPA communications, so it is easy to extend
   the protocol to offer new SPA message types and maintain backwards compatibility
   with older fwknop clients at the same time.
 * Supports the execution of shell commands on behalf of valid SPA packets.
 * The fwknop server can be configured to place multiple restrictions on inbound SPA
   packets beyond those enforced by encryption keys and replay attack detection.
   Namely, packet age, source IP address, remote user, access to requested ports,
   and more.
 * Bundled with fwknop is a comprehensive test suite that issues a series of tests
   designed to verify that both the client and server pieces of fwknop work properly.
   These tests involve sniffing SPA packets over the local loopback interface,
   building temporary firewall rules that are checked for the appropriate access based
   on the testing config, and parsing output from both the fwknop client and fwknopd
   server for expected markers for each test. Test suite output can easily be
   anonymized for communication to third parties for analysis.
 * fwknop was the first program to integrate port knocking with passive OS
   fingerprinting. However, Single Packet Authorization offers many security benefits
   beyond port knocking, so the port knocking mode of operation is generally
   deprecated.


## License
The fwknop project is released as open source software under the terms of
the **GNU General Public License (GPL v2)** or (at your option) any later
version. The latest release can be found at
[http://www.cipherdyne.org/fwknop/](http://www.cipherdyne.org/fwknop/)


## Current State
This README file describes the present state of the fwknop project as of the
2.5 release made in July, 2013. At present, we have an implementation of the
Firewall Knock Operator library; `libfko`, as well as the fwknop client and
server applications. The library provides the API and back-end functionality
for managing the Single Packet Authorization (SPA) data that the other fwknop
components employ. It also can be used by other programs that need SPA
functionality (see the `perl` directory for the FKO perl module as an example,
and there are python bindings as well in the `python` directory).


## Upgrading
If you are upgrading from an older version of fwknop (and this includes the
original perl implementation as well), then you will want to read the
following link to ensure a smooth transition to fwknop-2.5 or later:

[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility)

## Misc
 * Questions or comments about fwknop will be fielded on the
[fwknop mailing list](http://lists.sourceforge.net/lists/listinfo/fwknop-discuss]).
 * For static analysis, fwknop uses the CLANG static analyzer and also the powerful
Coverity Scan tool: [![](https://scan.coverity.com/projects/403/badge.svg)](https://scan.coverity.com/projects/fwknop)

## Building fwknop
This distribution uses GNU autoconf for setting up the build. Please see
the `INSTALL` file for the general basics on using autoconf.

There are some "configure" options that are specific to fwknop. They are
(extracted from *./configure --help*):

      --disable-client        Do not build the fwknop client component. The
                              default is to build the client.
      --disable-server        Do not build the fwknop server component. The
                              default is to build the server.
      --with-gpgme            support for gpg encryption using libgpgme
                              [default=check]
      --with-gpgme-prefix=PFX prefix where GPGME is installed (optional)
      --with-gpg=/path/to/gpg Specify path to the gpg executable that gpgme will
                              use [default=check path]
      --with-firewalld=/path/to/firewalld
                              Specify path to the firewalld executable
                              [default=check path]
      --with-iptables=/path/to/iptables
                              Specify path to the iptables executable
                              [default=check path]
      --with-ipfw=/path/to/ipfw
                              Specify path to the ipfw executable [default=check
                              path]
      --with-pf=/path/to/pfctl
                              Specify path to the pf executable [default=check
                              path]
      --with-ipf=/path/to/ipf Specify path to the ipf executable [default=check
                              path]

    Examples:

    ./configure --disable-client --with-firewalld=/bin/firewall-cmd
    ./configure --disable-client --with-iptables=/sbin/iptables --with-firewalld=no

## Notes
### Migrating from the Perl version of fwknop
For those of you who are currently using the Perl version and plan to
migrate to this version, there are some things to be aware of:

 * Not all of the features and functionality of the Perl-based
 fwknop were ported to this implementation. We felt it important
 to keep the C version as lean and lightweight as possible. Most
 of the omitted feature/functions (like email alerts) can be
 accomplished through other means (i.e. use an external script
 to monitor log files and alert based on appropriate log messages).

 * There are some differences in the fwknop configuration and access
 file directives and values. Some of these are fairly subtle. You
 should pay careful attention to the documentation and comments in
 those files.


### For fwknop developers
If you are pulling this distribution from git, you should run the
`autogen.sh` script to generate the autoconf files. If you get errors about
missing directories or files, try running `autogen.sh` again. After that
you can run the `autoreconf -i` when you want to regenerate the configuration.
If, for some reason, autoreconf does not work for you, the `autogen.sh`
script should suffice.

The fwknop and fwknopd man page nroff sources are included in their
respective directories (client and server). These nroff files are derived
from the asciidoc sources in the 'docs' directory. See the README in docs
for details.
