FWKNOP(8)

NAME
fwknop - Firewall Knock Operator

SYNOPSIS
fwknop -A <ports> -R|-a|-s -D <host> [options]

DESCRIPTION
fwknop 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 SSH with an additional layer of security in order to make the exploitation of vulnerabilities (both 0-day and unpatched code) much more difficult. An authorization server fwknopd passively monitors authorization packets via libpcap 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 ulogd 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 /etc/fwknop/access.conf 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)
    username
    timestamp
    software version
    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 fwknop 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 fwknop client, the fwknopd 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 /var/log/fwknop/digest.cache 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 ALERTING_METHODS variable in the /etc/fwknop/fwknop.conf file). By default, the fwknop client sends authorization packets over UDP port 62201, but this can be altered with the --Server-port 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 fwknopd(8) for further details. See the EXAMPLES section for example invocations of the fwknop client.

REQUIRED ARGUMENTS

-D, --Destination <IP-address>
    Direct the fwknop client to authenticate with the fwknopd daemon/service at the destination address <IP> . The connection mode is discovered by the fwknopd 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 fwknopd. The format of this list is '<proto>/<port>...<proto>/<port>, e.g. "tcp/22,udp/53". NOTE: The vast majority of usages for fwknop require the -A argument, but sending full commands with the --Server-cmd argument via an SPA packet to be executed by fwknopd does not require this argument.

-R|-a|-s
    One of these options (see below) is required to tell the remote fwknopd 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.

OPTIONS

-a, --allow-IP <IP-address>
    Specify IP address that should be permitted through the destination fwknopd 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 the fwknopd server trusts the source address on the SPA packet IP header then the attacker gains access. The -a option puts the source address within the encrypted SPA packet, and so thwarts this attack. The -a option is also useful to specify the IP that will be granted access when SPA packet itself is spoofed with the --Spoof-src option. Another related option is -R (see below) which instructs the fwknop client to automatically resolve the externally routable IP address the local system is connected to by querying the http://www.whatismyip.com website.

-R, --Resolve-external-IP
    This is an important option, and instructs the fwknop client and the fwknopd daemon/service to query http://www.whatismyip.com to determine the IP address that should be allowed through the iptables policy at the remote fwknopd server side. This is useful if the fwknop client is being used on a system that is behind an obscure NAT address. Note that you can use the --URL option to have fwknop resolve an externally routable address by using the specific web service instead of http://www.whatismyip.org (see below).

--NAT-access <internalIP:forwardPort>
    The fwknopd 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).

--NAT-local
    On the fwknopd 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 -R 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: http://www.cipherdyne.org/cgi/clientip.cgi

--gpg-agent
    Instruct fwknop to acquire GnuPG key password from a running gpg-agent instance.

--gpg-agent-info <connection info>
    Specify the value of the GPG_AGENT_INFO environment variable as returned by the gpg-agent --daemon command. If the fwknop --gpg-agent command line argument is used instead of --gpg-agent-info, then fwknop assumes that the GPG_AGENT_INFO environment variable has already been set in the current shell.

--gpg-default-key
    Use the key that GnuPG defines as the default, i.e. the key that is specified by the default-key variable in ~/.gnupg/options. If the default-key variable is not defined within ~/.gnupg/options , 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 user.

--gpg-home-dir <dir>
    Specify the path to the GnuPG directory; normally this path is derived from the home directory of the user that is running the fwknop client. This is useful when a 'root' user wishes to log into a remote machine whose sshd 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 by the fwknopd 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 fwknopd daemon on the remote server to authenticate who created the SPA message.

--gpg-verbose
    Instruct fwknop to allow all output from the gpg 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.

--gpg-use-options
    By default the fwknop client instructs gpg to not reference any options file in gpg mode, but this command line argument can be used to re-enable them.

--Home-dir <dir>
    Specify the path to the user home directory where files such as .fwknop.hosts or .fwknop.run should be stored or retrieved.

-l, --last-cmd
    Instruct fwknop client to run with the same command line arguments that were used in a previous execution. This option is useful because the clients' fwknop command line can be complex and difficult to recall.

--Last-host <host>
    Instruct fwknop to use the same command line arguments that were used to authenticate to host.

-q, --quiet
    This option instructs the fwknop to be as quiet as possible and only print absolutely necessary information to the terminal.

-s, --source-ip
    Instruct the fwknop client to form an SPA packet that contains the special-case IP address "0.0.0.0" which will inform the destination fwknopd 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 -s (default), -R and -a are mutually exclusive.

--Server-port <port>
    Specify the port number where fwknopd accepts packets via libpcap or ulogd pcap writer. By default fwknopd looks for authorization packets over UDP port 62201.

--rand-port
    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

--NAT-rand-port
    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.

--Save-packet
    Instruct the fwknop client to write a newly created SPA packet out to a file so that it can be examined off-line. The default path is ~/fwknop_save_packet.<pid> where <pid> is the process ID of the fwknop client process, but this can be changed with the --Save-packet-file argument (see below).

--Save-packet-file <file>
    Specify the file to write a new SPA packet to in --Save-packet mode.

--Save-packet-append
    In --Save-packet 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.

--time-offset-plus <time>
    By default, the fwknopd 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.

--time-offset-minus <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.

--Show-last-cmd
    Display the last command-line arguments used by fwknop.

--Show-host-cmd <host>
    Display the last command-line arguments used to contact a SPA server running on a specific host.

--Spoof-proto <protocol>
    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-src <IP>
    Spoof the source address from which the fwknop client sends SPA packets. This requires root on the client side access since a raw socket is required to accomplish this. Note that the --Spoof-user argument can be given in this mode in order to pass any REQUIRE_USERNAME keyword that might be specified in /etc/fwknop/access.conf.

--Spoof-user <user>
    Specify the username that is included within SPA packet. This allows the fwknop client to satisfy any non-root REQUIRE_USERNAME keyword on the fwknopd server ( --Spoof-src mode requires that the fwknop client is executed as root).

--icmp-type <type>
    When using the --Spoof-proto 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 --icmp-code argument below).

--icmp-code <code>
    When using the --Spoof-proto 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 --icmp-type argument above).

--Max-packet-size <size>
    Instruct fwknop to restrict message length to size 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 fwknop.conf on the SPA server.

--HTTP
    Have the fwknop client send an SPA packet as a web request over HTTP. This requires that the system running fwknopd 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>
    The HTTP-proxy option allows the fwknop client to send SPA packets through an HTTP proxy when the --HTTP option is also used. The expected format for the argument is http://some.host.com and an optional port number is supported with the http://some.host.com:PORT format.

--HTTP-user-agent <agent string>
    Specify the HTTP user-agent whenver the fwknop client is used to send an SPA packet over an HTTP request, or when the --Resolve-external-IP option is used. The default user-agent is "Fwknop/VERSION", so "Fwknop/1.9.12" for the 1.9.12 release.

-T, --TCP-sock
    Have the fwknop 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 --Server-port argument). This is not normally done, but is useful for compatibility with the Tor for strong anonymity; see http://tor.eff.org/. In this case, the fwknopd server uses the fwknop_serv daemon to listen on a TCP port (62201 by default).

-h, --help
    Display usage information and exit.

-V, --Version
    Display version information and exit.

-v, --verbose
    Run the fwknop client in verbose mode.

--locale <locale>
    Provide a locale setting other than the default "C" locale.

--no-locale
    Do not set the locale at all so that the default system locale will apply.

--Server-cmd <cmd>
    NOTE: This is for command mode only (i.e. when you want to send a command across to a system running fwknopd 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 /etc/fwknop/access.conf on the fwknopd 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 fwknop server, which will execute the command as root. Command execution is enabled only if the ENABLE_CMD_EXEC keyword is given in /etc/fwknop/access.conf (note that commands can easily be restricted with the CMD_REGEX 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 not the preferred or recommended mode next to Single Packet Authorization ( see http://www.cipherdyne.org/fwknop/docs/SPA.html for details on why).

    --offset <port>
        Specify a port offset to use when running fwknop in encrypted knock mode. The default is 61000.

    -r, --rotate-proto
        Rotate the protocol across tcp and udp for encrypted sequences. This just adds one more additional layer of obfuscation to an encrypted sequence.

    --Server-mode <mode>
        This command line switch provides an interface to the old port knocking method if the mode argument is "knock". If the --Server-mode argument is not given then the fwknop 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 fwknop client. On the server side, fwknopd 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 client side).

    -u, --user-rc <rc-file>
        The default connection rc file the fwknop client uses to know what shared port knocking sequence to send to a destination machine is defined in the file ~/.fwknoprc. The path to this file can be changed with the --user-rc command line option.

FILES

~/.fwknop.run
    Contains the last command line arguments that the fwknop client was invoked with.

~/.fwknop.hosts
    Contains the last command line arguments for individual hosts that the fwknop client has been used to gain access to. By using the --Last-host switch, these arguments can be recalled and used.

ENVIRONMENT:
GPG_AGENT_INFO (only used in --gpg-agent mode).

EXAMPLES:
The following examples illustrate the command line arguments that could be supplied to the fwknop client in a few situations: Access mode examples
    Packet contents printed to stdout at the fwknop client when creating a 'access mode' SPA packet:

            Random data: 6565240948266426
            Username: mbr
            Timestamp: 1203863233
            Version: 1.9.2
            Type: 1 (access mode)
            Access: 127.0.0.2,tcp/22
            SHA256 sum: gngquSL8AuM7r27XsR4qPmJhuBo9pG2PYwII06AaJHw

    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 -s option because the source IP is put within the encrypted packet instead of having the fwknopd 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 and decrypt:

    $ fwknop -A 'tcp/22,udp/53' --gpg-sign ABCD1234 --gpg--recipient 1234ABCD -R -D 10.0.0.123

    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 with www.yahoo.com:

    # fwknop --Spoof-src 'www.yahoo.com' -A tcp/22 -a 172.16.5.4 -D 10.0.0.123

Command mode examples
    NOTE: Please ensure that ENABLE_CMD_EXEC; is set in the file /etc/fwknop/access.conf on the fwknopd server you are attempting to connect to. Packet contents printed to stdout at the fwknop client when creating a 'command mode' SPA packet:

            Random data: 4621962433020664
            Username: mbr
            Timestamp: 1203864394
            Version: 1.9.2
            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:

    $ fwknop --Server-cmd 'ping -c 1 www.yahoo.com' -D 10.0.0.123

Port-knock mode (legacy) examples
    This connection mode is a legacy mode and is not the preferred or recommended mode. Packet contents printed to stdout at the fwknop client when in 'port-knock mode': <TODO> 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 192.168.10.4:

    $ 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):

    $ fwknop --Server-mode 'knock' -A tcp/22 -s -r --offset 55000 -D 10.0.0.123

    Send a shared knock sequence to the IP 10.11.11.123. The fwknop client will read the sequence out of the file ~/.fwknoprc and the server will read the sequence out of /etc/fwknop/access.conf:

    $ fwknop --Server-mode 'knock' -D 10.11.11.123

DEPENDENCIES
fwknop requires perl. To take advantage of all of the authentication and access management features of the fwknopd 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 --log-tcp-options argument will be specified in the iptables logging rule so that the fwknopd daemon/service will be able to use a strategy similar to p0f to passively fingerprint operating systems.

DIAGNOSTICS
fwknop can be run in debug mode with the --debug command line option. This will disable daemon mode execution, and print verbose information to the screen on STDERR as packets are received.

SEE ALSO
fwknopd(8), iptables(8), gpg(1), gpg-agent(1), knopmd(8), knopwatchd(8) p0f(1), More information on the differences between port knocking and Single Packet Authorization can be found in the paper "Single Packet Authorization with fwknop" available here: http://www.cipherdyne.org/fwknop/docs/SPA.html

AUTHOR
Michael Rash <mbr@cipherdyne.org>

CONTRIBUTORS
Many people who are active in the open source community have contributed to fwknop. See the CREDITS file in the fwknop sources, or visit http://www.cipherdyne.org/fwknop/docs/contributors.html to view the online list of contributors. The phrase "Single Packet Authorization" was coined by MadHat and Simple Nomad at the BlackHat Briefings of 2005 (see: http://www.nmrc.org/). The term "port knocking" was coined by Martin Krzywinski (see: http://www.portknocking.org/). The original p0f passive OS fingerprinter was written by Michal Zalewski, and is available here: http://lcamtuf.coredump.cx/p0f.shtml

BUGS
Send bug reports to mbr@cipherdyne.org. Suggestions and/or comments are always welcome as well.

DISTRIBUTION
fwknop is distributed under the GNU General Public License (GPL), and the latest version may be downloaded from http://www.cipherdyne.org/