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/