1. fwknop Quick Start
This section illustrates basic usage of
fwknop to harden an SSH daemon
with
Single Packet Authorization (SPA). For the remainder
of this document, two Linux systems will be used for illustration purposes:
spaclient (IP: 1.1.1.1) and
spaserver (IP: 2.2.2.2).
The SSH daemon along with iptables and fwknopd are deployed on the spaserver system,
and the SSH and fwknop clients are deployed on the spaclient system. This section assumes
that fwknop has been installed properly on both systems, and installation
details can be found in the
Installing fwknop section below. We'll use the
following network diagram to serve as a reference throughout:
Figure 1: Single Packet Authorization - general network diagram
Note that in the diagram above, the
spaclient is on a home/office network that is
behind a firewall. All packets sent out through this firewall are NAT'd to have source IP
1.1.1.1, and this is the IP that systems on the external Internet will see for
communications initiated by the
spaclient system.
In general, using fwknop to wrap sshd with a Single Packet Authorization layer involves
the following steps:
- Define an SPA encryption key in
/etc/fwknop/access.conf - this can involve GnuPG keys if you prefer.
- Configure the local firewall policy to block all incoming connections to sshd.
- Start
fwknopd
- Use the
fwknop client from a remote system to generate a valid encrypted SPA
packet as required by the access.conf file on the server.
- Access sshd with an ssh client as normal.
If you already have
fwknopd installed and configured, basic usage of
the
fwknop client to access sshd just looks like this:
[spaclient]$ fwknop -A tcp/22 -R -D spaserver
Enter encryption password:
[spaclient]$ ssh -l mbr spaserver
mbr@spaserver's password:
[spaserver]$ hostname
spaserver
Now, keeping the above outline in mind, the remainder of this Quick Start follows:
1.1 Configuring fwknopd to Protect sshd
First, on the spaserver system, configure fwknopd with a shared encryption
key. This key allows fwknopd to decrypt SPA packets that have been encrypted
with the Rijndael cipher from systems running fwknop clients. All encryption key
information and access control directives for the fwknopd server are placed within the
/etc/fwknop/access.conf file, so we add our key (along with some
additional variables that will be explained later) there:
[spaserver]# cat /etc/fwknop/access.conf
SOURCE: ANY;
OPEN_PORTS: tcp/22; ### for ssh (change for access to other services)
KEY: yourdecryptkey;
FW_ACCESS_TIMEOUT: 30;
With the
/etc/fwknop/access.conf setup, it's time to make sure that the
/etc/fwknop/fwknopd.conf file is also suitably configured. It is important
to configure the fwknopd daemon to sniff on a specific interface, although for Linux
systems the default is
eth0. If you are running fwknopd on different
platform such as FreeBSD or OpenBSD you will want to set the
PCAP_INTF to the appropriate
interface name. There are many variables in the
/etc/fwknop/fwknopd.conf
file, but most are set to sensible defaults. As an illustration, here is the
PCAP_INTF variable and it is set to
eth0:
[spaserver]# grep PCAP_INTF /etc/fwknop/fwknopd.conf
PCAP_INTF eth0;
Now, start the fwknopd daemon:
[spaserver]# service fwknop start
fwknop start/running, process 29134
At this point fwknopd is up and running and sniffing the eth0 Ethernet interface.
By default fwknopd does not sniff every packet though - it uses a bpf filter
to only sniff for UDP packets to port 62201. This can be changed though by
altering the
PCAP_FILTER variable in the
fwknopd.conf
file and restarting fwknopd. To confirm that fwknopd is sniffing the network,
after start up it writes a few messages to syslog as follows:
[spaserver]# grep fwknopd /var/log/syslog
Sep 22 10:40:59 spaserver fwknopd[4079]: Starting fwknopd
Sep 22 10:40:59 spaserver fwknopd[4079]: Added jump rule from chain: INPUT to chain: FWKNOP_INPUT
Sep 22 10:40:59 spaserver fwknopd[4079]: PCAP filter is: udp port 62201
Sep 22 10:40:59 spaserver fwknopd[4079]: Starting fwknopd main event loop.
1.2 Default-Drop firewall policy
Single Packet Authorization is designed to allow the local firewall to be configured in
a "default drop" stance for a protected service such as sshd. On the
spaserver
system we'll assume that
eth0 is the external interface and connections
to sshd should be blocked on this interface. The following iptables commands accomplish
this, and are compatible with
fwknopd.
[spaserver]# iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -j DROP
[spaserver]# iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
The
iptables setup script written
for the No Starch Press book
"
Linux Firewalls: Attack Detection and Response"
also configures iptables as described above - i.e. does not allow incoming connections to sshd on
eth0, but keeps any connection open that makes it into the established state.
(Disclaimer:
I wrote this book, but there are many other configuration setup scripts that one can use
besides the one developed for the book.) For any production firewall you will want to
simply not allow incoming connections to sshd and ensure that connection tracking for established
connections is enabled.
1.3 Gaining access to sshd with the fwknop client
Now let's move to the fwknop client system
spaclient and try to gain
access to SSH running on the
spaserver system. We verify first that
iptables is blocking our attempts to talk to SSH:
[spaclient]$ nmap -P0 -n -p 22 spaserver
Starting Nmap 5.00 ( http://nmap.org ) at 2012-09-22 10:50 EDT
Interesting ports on 2.2.2.2:
PORT STATE SERVICE
22/tcp filtered ssh
Nmap done: 1 IP address (1 host up) scanned in 2.10 seconds
So, to gain access to SSH, execute the fwknop client (note that most of the output below is
for informational purposes since we've included the
--verbose command line argument):
[spaclient]$ fwknop -A tcp/22 -R -D spaserver --verbose
Enter encryption password:
[+] Resolved external IP (via http://www.cipherdyne.org/cgi-bin/myip) as: 1.1.1.1
Enter encryption password:
FKO Field Values:
=================
Random Value: 1805793899630599
Username: mbr
Timestamp: 1348325239
FKO Version: 2.0.3
Message Type: 1
Message String: 1.1.1.1,tcp/22
Nat Access: <NULL>
Server Auth: <NULL>
Client Timeout: 0
Digest Type: 3
Encoded Data: 1805793899630599:bWJy:1348325239:2.0.3:1:MS4xLjEuMSx0Y3AvMjI
SPA Data Digest: 3MCsRnyNAmxT4NL7DhBDp5Cwl061KodGMJAEaPlvPIA
Final Packed/Encrypted/Encoded Data:
85yR1UXTnKQRKbIyLgjVJZPEdbhZJr//+ctXyL38a3VMvs2/NDH775WwVRe1EBnhqoEE9pFPrqHv5d8CVfh//FyOoqwveoBs+zbgb1LvoE4f6/9UJFybUWrApsB6z/0U9p1dPCdcbe1blK/H8hUgbOvWrKA7m8j30
Generating SPA packet:
protocol: udp
port: 62201
IP/host: 2.2.2.2
send_spa_packet: bytes sent: 161
After
fwknopd has received the incoming SPA packet and has validated that
1)
the SPA packet has not been replayed,
2) the SPA packet has been encrypted
with a key defined in the
access.conf file so that it is properly
decrypted by
fwknopd, and
3) the packet contains a request for
access that is authorized, then access is granted to sshd. This is done
by adding an
ACCEPT rule to the
FWKNOP_INPUT chain for
the
1.1.1.1 IP to tcp/22 for 30 seconds before deleting it. From the
spaserver system, you can see the
ACCEPT rule as well
as the messages
fwknopd writes to syslog as follows:
[spaserver]# fwknopd --fw-list
Listing rules in fwknopd iptables chains...
Chain FWKNOP_INPUT (1 references)
num target prot opt source destination
1 ACCEPT tcp -- 1.1.1.1 0.0.0.0/0 tcp dpt:22 /* _exp_1348326362 */
[spaserver]# grep fwknopd /var/log/syslog
Sep 22 10:50:32 spaserver fwknopd[4079]: (stanza #1) SPA Packet from IP: 1.1.1.1 received with access source match
Sep 22 10:50:32 spaserver fwknopd[4079]: Added Rule to FWKNOP_INPUT for 1.1.1.1, tcp/22 expires at 1348326362
While the
ACCEPT rule still exists, you can ssh from the
spaclient
system into
spaserver:
[spaclient]$ ssh -l mbr spaserver
mbr@spaserver's password:
[spaserver]$ hostname
spaserver
Once the 30 second expiration time arrives,
fwknopd removes the
ACCEPT
rule for 1.1.1.1 to tcp/22, but the ssh connection remains open through the use of the iptables
connection tracking capability. Here is the syslog message that
fwknopd writes when
the rule is removed:
Sep 22 10:50:02 spaserver fwknopd[4079]: Removed rule 1 from FWKNOP_INPUT with expire time of 1348326362.
After the
ACCEPT rule is removed, sshd is once again invisible to scans:
[spaclient]$ nmap -P0 -n -p 22 spaserver
Starting Nmap 5.00 ( http://nmap.org ) at 2012-09-22 10:50 EDT
Interesting ports on 2.2.2.2:
PORT STATE SERVICE
22/tcp filtered ssh
Nmap done: 1 IP address (1 host up) scanned in 2.10 seconds
As usual, if there are any problems with the Quick Start instructions or you have additional
questions, please email
<mbr[at]cipherdyne.org>.
2. Introduction
This tutorial is a comprehensive guide to the usage, deployment, and theory behind
the
fwknop project. After reading
this document, you will be armed with the requisite knowledge to use fwknop together
with a firewall configured in a "default drop" stance to wrap a cryptographically
strong passive authentication/authorization layer around arbitrary services. This
layer is called
Single Packet Authorization (SPA), and can apply to all sorts of
services from sshd and OpenVPN to mail protocols like POP and IMAP and even to HTTP.
The end goal is to make it infeasible for anyone armed with
nmap to even detect services protected in this
way - let alone exploit a vulnerability or attempt to brute force a password (as is
commonly done against accessible SSH daemons). By using the fwknop client to
generate a valid SPA message, access is granted temporarily to the protected service
from whatever IP address is encrypted within the SPA packet. An SPA packet is "valid"
when it is encrypted by a strong cipher (fwknop supports both Rijndael for symmetric
encryption and GnuPG for asymmetric encryption) with an expected key, and has not
been replayed as verified by a SHA-256 digest. No two SPA packets are identical
because they contain 16 bytes of random data before being encrypted in addition to leveraging
natural differences that Rijndael in CBC mode and GnuPG provide from one byte to the next. Once
the firewall has been temporarily reconfigured to allow access and a session is established, a
state tracking mechanism supported by the firewall can be used to keep a session established
even after the rule that allows access is removed.
Users of firewalls find value in the idea that traffic to a service can be blocked from
all but a few pre-defined networks according to the firewall policy. Few people question
whether this is valuable from a security perspective - firewalls generally enhance security
(the occasional firewall vulnerability not withstanding). The PK/SPA strategy extends the
notion of filtering traffic for a set of services by adding a lightweight crypto layer
to allow temporary access from networks that cannot be anticipated when the firewall policy
is written. This provides service
concealment by default, and the SPA strategy
asserts that there is value in this.
There are many people looking for vulnerabilities in server software, and when a clever
person finds a brand new vulnerability, this person has the opportunity to use it
for good - disclosing it responsibly to the vendor so that it can be fixed - or
ill - using it for malicious purposes. If the person chooses the later
and wants to exploit the vulnerability, then one of the first steps is to find a
list of targets. If an exploit applies to a piece of server software - say SSH - that typically
runs on a particular port (tcp/22 in this case), then a common technique for
identifying suitable targets is to use nmap to conduct a port sweep across many
networks looking for SSH servers listening on port 22. With SPA deployed,
anyone building such a list of targets will not be able to include your system
in their list.
Both PK and SPA are designed to protect server software
behind a default-drop packet filter and are not effective at protecting against
client-side exploits (such as an attack for a vulnerability in a web browser).
2.1 What is Port Knocking?
Port knocking is defined as the communication of authentication information over
closed (or at least logged) ports, together with the dynamic reconfiguration of a
default-drop firewall policy to allow access to authenticated connections. The
goal of port knocking is to provide a simplistic mechanism by which a remote user
can be authenticated before access is granted to a service such as an SSH daemon.
The basic architecture is that a port knocking client generates a series of packets
to a set of ports which are logged on a port knocking server, and if this series
of ports builds a proper sequence then access will be granted to the requested
service. Port knocking, in contrast to most Single Packet Authorization implementations,
uses packet headers instead of packet payloads to communicate authentication information.
A port knock sequence can be a simple shared sequence of ports, or it can be more
advanced and involve encryption and passive OS fingerprinting.
2.2 What is Single Packet Authorization?
Single Packet Authorization (SPA) is defined similarly to port knocking, except
that instead of just using packet headers, SPA communicates authentication
information within the payload portion of a packet. Because packet payloads
are used, SPA offers many enhancements over PK such as protection from replay
attacks, minimal network footprint (in terms of what IDS's may alert on - PK
sequences look like port scans after all), the ability to transmit full commands
and complex access requests, and better performance.
Although SPA is referred to in this document as Single Packet
Authorization, fwknop really performs both authentication and authorization,
which are not the same thing. "Authentication" is the process of proving who
you are, whereas "authorization" is the process of determining whether someone
is allowed to perform an operation.
2.3 What is fwknop?
fwknop is free and open source software that supports Single Packet Authorization.
The fwknop "server" supports
iptables
firewalls on Linux,
ipfw
firewalls on FreeBSD and Mac OS X, and
pf
on OpenBSD. The fwknop client runs on Linux, Mac OS X, *BSD, and Windows systems
(either under Cygwin or using the
fwknop UI).
Current versions of fwknop are written in C, but there are older versions that are
written in perl. These older versions support port knocking, but this has been
deprecated in favor of SPA in the C versions.
When fwknop was first released in 2004, it was the first software
implementation that combined port knocking with passive OS fingerprinting to add an
additional authentication parameter to port knock sequences. In May of 2005, the
first version of fwknop that supported full SPA mode communications (with encrypted
and non-replayable payloads) was released, and the development pace has remained
strong ever since. A new release is made on average every few months, and there
is a healthy list of
contributors who suggest features
and write patches to the fwknop code. As of November 2008, fwknop is available
as a Debian package for Debian and Ubuntu systems (thanks to Franck Joncourt),
and as an RPM for Red Hat and Fedora systems (thanks to Mirek Trmac).
All fwknop source code is versioned within git, and can be
viewed with the gitweb.cgi
interface.
2.4 fwknop License (GPL v2)
fwknop is released as open source software under the terms of the GNU Public
License (GPL) version 2. For reference, the full text of the GPL can be
downloaded from the Free Software Foundation. There are no plans at the present
time to change the licensing terms of fwknop to a different license (such as
GPL v3 or a BSD license), but this may change at any time without notice. However,
fwknop will always remain an open source project free for use by anyone.
In March 2005, a
patent for SPA
was filed with the US Patent and Trademark Office, and the patent appeared in their
database in March 2007 although it has not yet been issued. The patent was filed
mostly as a defensive measure so that it would be more difficult for a patent troll
to inflict damage upon the development of fwknop. Open source projects need to protect
themselves as aggressively as possible in an uncertain legal climate that makes
frivolous patent litigation an expensive proposition.
3. Installing fwknop
3.1 Downloading the latest fwknop release
Many Linux distributions such as Fedora, RHEL, Debian, Ubuntu, Slackware, OpenWRT,
and more also make fwknop available through their own standard package management systems
(yum, apt-get, etc.). It is frequently a good idea to install fwknop through the
package management system that is native to your distribution, but if you want to compile
and install from sources, the latest release of the fwknop source code is available at:
http://www.cipherdyne.org/fwknop/download/ .
3.2 Supported Platforms
The fwknop code is generally quite portable across various platforms, and the table below
tracks the current state of support across a broad set of operating systems. Following
this table are sections that make notes about fwknop operations on specific operating
systems. If you are able to get fwknop to function on a platform that is not listed
below, please contact the fwknop developers so that it can be included. On the development
side, if you see that a particular fwknop component is not currently supported on your OS
of choice (say, GnuPG support on Android), and you develop a patch to add support, please
submit the patch so it can be added to the next fwknop release. Your
patch will be attributed to you in the
CREDITS file.
| Component / Technology |
Fedora/RHEL/CentOS |
Debian/Ubuntu |
OpenWRT |
FreeBSD |
Mac OS X |
OpenBSD |
iPhone |
Android |
Windows |
| fwknop client |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
| fwknopd server |
Y |
Y |
Y |
Y |
Y |
Y |
N |
N |
N |
| GnuPG Support |
Y |
Y |
Y |
Y |
Y |
Y |
N |
N |
N |
| fwknopd server-side NAT |
Y |
Y |
Y |
N |
N |
N |
N |
N |
N |
| Native Windows binary (client) |
N/A |
Y |
| libfko library |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
| perl libfko bindings |
Y |
Y |
Y |
Y |
Y |
Y |
N |
N |
Unknown |
| python libfko bindings |
Y |
Y |
Y |
Y |
Y |
Y |
N |
N |
Unknown |
3.3 Notes on Specific Platforms
3.3.1 Linux Notes
Most new features in the fwknop world are prototyped on Linux first and then ported
to other operating systems. The fwknop client is usually the easiest part of fwknop
to get working on non-Linux systems because it doesn't depend on support for various
features within the local firewall and it doesn't have to worry about differences in
firewall command syntax (iptables vs. ipfw vs. pf). However, as noted in the
Supported Platforms section above, the fwknopd daemon supports many
non-Linux platforms. Now, for features that are specific to Linux, the fwknopd daemon
relies on the iptables "
comment" match in order to store the expiration time for
new
ACCEPT rules upon receiving a valid SPA packet. At init time, fwknopd
verifies whether the
comment match is available, and then uses it as follows
for new rules. Note that all new rules are added by fwknopd to the
FWKNOP_INPUT
chain to ensure separation with the rest of the iptables policy.
/sbin/iptables -t filter -A FWKNOP_INPUT -p 6 -s 1.1.1.1 --dport 22 -m comment --comment _exp_1348688232 -j ACCEPT
In terms of other dependencies, if you want the fwknopd daemon to compile and run then
you will need to install libpcap. This is usually best achieved by installing a
package such as "libpcap-dev" or "libpcap-devel" through your distribution package
manager (yum, apt-get, etc.).
3.3.2 FreeBSD Notes
The
fwknop client, server, and libfko library all function properly on FreeBSD systems.
Note that
fwknopd maintains rule expiration times via
ipfw
"
// _exp_<expire_time>" comments, and rules added by
fwknopd
go into
set 1 by default (see the
IPFW_ACTIVE_SET_NUM variable
in the
/etc/fwknop/fwknopd.conf file).
/sbin/ipfw add 10000 set 1 pass 6 from 1.1.1.1 to me dst-port 22 setup keep-state // _exp_1346784046
3.3.3 Mac OS X Notes
The fwknop client functions equivalently on Mac OS X systems as it does on other systems,
but things are slightly different for the fwknopd server due to differences between
ipfw
on Mac OS X vs.
ipfw on FreeBSD. These differences are handled
by
this patch,
which changes how fwknopd deals with
ipfw sets on Mac OS X vs. FreeBSD.
3.3.4 OpenBSD Notes
On OpenBSD, the fwknopd server makes use of a dedicated
pf anchor
to which fwknopd will add and delete rules. This anchor must be linked into the
pf policy (typically done by adding it into the
/etc/pf.conf file),
and fwknopd runs a check at init time to ensure that the anchor exists. The
PF_ANCHOR_NAME variable in the
/etc/fwknop/fwknopd.conf
config file controls the name of the anchor, with the default being set as follows:
For rule expiration, fwknopd leverages the
pf "
label"
capability to mark new rules with an expiration time.
3.3.5 iPhone Notes
There is an fwknop
iPhone client, but is has not yet been uploaded to the Apple iStore. In addition,
it does not yet support the encryption of SPA packets with GnuPG, but Rijndael mode works just fine.
3.3.6 Android Notes
There is an fwknop
Android client, and similarly to the iPhone the Android client supports
Rijndael for SPA packet encryption but not yet GnuPG.
3.3.7 Windows Notes
Support on Windows is in the form of a native Windows fwknop client binary along with the
libfko code being portable to Windows. The client is also known to work under
Cygwin, and there is a
UI as well. However, GnuPG support is not yet functional.
In addition, there are no current plans to support a Windows firewall in fwknopd, but theoretically
it could be developed.
3.4 Installing from Sources
As of this writing, the latest release of fwknop is 2.0.3, and compiling and
installing fwknop is easily done via the following steps. Note that this will result
in fwknopd configuration files being installed in
/etc/fwknop/ along with normal
binaries in
/usr/bin/ and
/usr/sbin/ (most command output removed
for brevity). Also, the GnuPG signature for the fwknop-2.0.3.tar.gz tarball is verified
(always do this!) using the key available
here - you'll need to
import this key with "
$ gpg --import <key file>" if it is not already
on your GnuPG keyring.
[spaserver]$ wget http://www.cipherdyne.org/fwknop/download/fwknop-2.0.3.tar.gz
[spaserver]$ wget http://www.cipherdyne.org/fwknop/download/fwknop-2.0.3.tar.gz.asc
[spaserver]$ gpg --verify fwknop-2.0.3.tar.gz.asc
gpg: Signature made Tue 04 Sep 2012 10:49:32 PM EDT using DSA key ID 0D3E7410
gpg: Good signature from "Michael Rash (Signing key for cipherdyne.org projects) <mbr@cipherdyne.org>"
[spaserver]$ tar xfz fwknop-2.0.3.tar.gz
[spaserver]$ cd fwknop-2.0.3
[spaserver]$ ./configure --prefix=/usr --sysconfdir=/etc && make
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
/bin/bash ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -Wall -fstack-protector-all -fstack-protector -fPIE -pie -D_FORTIFY_SOURCE=2 -MT base64.lo -MD -MP -MF .deps/base64.Tpo -c -o base64.lo base64.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -Wall -fstack-protector-all -fstack-protector -D_FORTIFY_SOURCE=2 -MT base64.lo -MD -MP -MF .deps/base64.Tpo -c base64.c -fPIC -DPIC -o .libs/base64.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -Wall -fstack-protector-all -fstack-protector -D_FORTIFY_SOURCE=2 -MT base64.lo -MD -MP -MF .deps/base64.Tpo -c base64.c -fPIE -pie -o base64.o >/dev/null 2>&1
...
[spaserver]$ su
Password:
[spaserver]# make install
Making install in lib
make[1]: Entering directory `/home/mbr/git/fwknop.git/lib'
make[2]: Entering directory `/home/mbr/git/fwknop.git/lib'
test -z "/usr/lib" || /bin/mkdir -p "/usr/lib"
/bin/bash ../libtool --mode=install /usr/bin/install -c libfko.la '/usr/lib'
libtool: install: /usr/bin/install -c .libs/libfko.so.0.0.3 /usr/lib/libfko.so.0.0.3
libtool: install: (cd /usr/lib && { ln -s -f libfko.so.0.0.3 libfko.so.0 || { rm -f libfko.so.0 && ln -s libfko.so.0.0.3 libfko.so.0; }; })
...
[spaserver]# which fwknop
/usr/bin/fwknop
[spaserver]# fwknop -V
fwknop client 2.0.3, FKO protocol version 2.0.3
[spaserver]# which fwknopd
/usr/sbin/fwknopd
[spaserver]# fwknopd -V
fwknopd server 2.0.3
Also, before running that last
make install, it is recommended to run
the
fwknop test suite to make sure that fwknop seems to operate
normally on your system.
If fwknop is supported by your OS package management system, you may want to install
using it instead. For example, on Ubuntu systems, you can install via:
[spaclient]# apt-get install fwknop-client
[spaserver]# apt-get install fwknop-server
3.5 The fwknop Test Suite
Given that fwknop supports several different modes of operation - including the
usage of various encryption algorithms, cryptographic hashes, and firewall
binaries - it is important to automate the testing and verification of proper
fwknop execution. This is the job of the fwknop test suite which is bundled
within the fwknop sources (see the
test/ directory). Nearly every
aspect of fwknop operations is examined and verified by the test suite. In
this section we'll examine test suite operations and show how it can be used
in the development of new fwknop features and functionality. In general, when
a new feature is developed, a corresponding test or set of tests is added to the
test suite to ensure proper implementation. This same process also applies to
bug fixes.
3.5.1 Running the Test Suite
When installing fwknop on any system it is recommended to run the test suite to
verify that run time aspects of fwknop work properly. The test suite can be
executed before the final "
make install" step in the installation process.
This way, if the test suite indicates there are critical problems after fwknop
has been compiled (unlikely assuming that fwknop is being installed on a supported
platform), then the installation can be aborted and bugs filed before binaries
have been installed in important filesystem locations. After compilation with
"
./configure --prefix=/usr ... && make" the test suite can be run as
follows from the
test/ directory. Note that this must be done as root,
and in this particular case we also instruct the test suite to recompile fwknop
so that it can verify that there are no compilation warnings:
[spaserver]# cd fwknop-2.0.3/test/
[spaserver]# ./test-fwknop.pl --enable-recompile
[+] Starting the fwknop test suite...
args: --enable-recompile
Saved results from previous run to: output.last/
[recompilation] recompile and look for compilation warnings.........pass (1)
[build] [client] binary exists......................................pass (2)
[build security] [client] Position Independent Executable (PIE).....pass (3)
[build security] [client] stack protected binary....................pass (4)
[build security] [client] fortify source functions..................pass (5)
[build security] [client] read-only relocations.....................pass (6)
[build security] [client] immediate binding.........................pass (7)
[build] [server] binary exists......................................pass (8)
[build security] [server] Position Independent Executable (PIE).....pass (9)
[build security] [server] stack protected binary....................pass (10)
[build security] [server] fortify source functions..................pass (11)
[build security] [server] read-only relocations.....................pass (12)
[build security] [server] immediate binding.........................pass (13)
[build] [libfko] binary exists......................................pass (14)
[build security] [libfko] stack protected binary....................pass (15)
[build security] [libfko] fortify source functions..................pass (16)
[build security] [libfko] read-only relocations.....................pass (17)
[build security] [libfko] immediate binding.........................pass (18)
...
[Rijndael SPA] [client+server] complete cycle (tcp/22 ssh)..........pass (44)
[Rijndael SPA] [client+server] permissions check cycle (tcp/22).....pass (45)
[Rijndael SPA] [client+server] dual usage access key (tcp/80 http)..pass (46)
[Rijndael SPA] [client+server] packet aging (past) (tcp/22 ssh).....pass (47)
[Rijndael SPA] [client+server] packet aging (future) (tcp/22 ssh)...pass (48)
[Rijndael SPA] [client+server] expired stanza (tcp/22 ssh)..........pass (49)
[Rijndael SPA] [client+server] invalid expire date (tcp/22 ssh).....pass (50)
...
[Rijndael SPA] [client+server] replay attack detection..............pass (81)
[Rijndael SPA] [client+server] replay detection (Rijndael prefix)...pass (82)
[Rijndael SPA] [FUZZING] null port value............................pass (87)
[Rijndael SPA] [FUZZING] long FKO protocol value (enc mode trigger).pass (88)
[Rijndael SPA] [FUZZING] long FKO protocol value (Rijndael trigger).pass (89)
[Rijndael SPA] [FUZZING] null proto value...........................pass (90)
...
[GnuPG (GPG) SPA] [client+server] complete cycle (tcp/22 ssh).......pass (113)
[GnuPG (GPG) SPA] [client+server] multi gpg-IDs (tcp/22 ssh)........pass (114)
[GnuPG (GPG) SPA] [client+server] replay detection (GnuPG prefix)...pass (120)
[GnuPG (GPG) SPA] [client+server] non-base64 altered SPA data.......pass (121)
[GnuPG (GPG) SPA] [client+server] base64 altered SPA data...........pass (122)
[GnuPG (GPG) SPA] [client+server] appended data to SPA pkt..........pass (123)
[GnuPG (GPG) SPA] [client+server] prepended data to SPA pkt.........pass (124)
[GnuPG (GPG) SPA] [server] digest cache structure...................pass (126)
[+] passed/failed/executed: 126/0/126 tests
There are many more tests than are displayed above, and a complete example of
test suite output can be found
here.
If there are any failures indicated in the test suite output, the most
important files to examine are the
test.log and the various
NNN.test results files (where NNN corresponds to each test number) in
the
output/ directory. These files help to diagnose any problems with
fwknop on the local system.
3.5.2 --diff Mode
One of the more useful things the test suite offers is the ability to compare results from
one test run to another.
[spaserver]# ./test-fwknop.pl --diff
This is mostly useful when hacking on the fwknop code in order to
use the test suite to verify a change (or lack thereof) in functionality. At startup, the
test suite copies any existing
output/ directory to
output.last
and then diff's each file between the two runs in
--diff mode. In the process,
it tries to match output files to each other to account for differences in how the test
suite is invoked across the runs (such as if different
--include or
--exclude criteria is provided). Using this mode, the typical workflow
becomes 1) run the test suite, 2) hack on the fwknop code and recompile, 3) run the test
suite in
--diff mode, 4) commit the changes if everything is in order. This
allows the test suit to help validate changes before they make it into the code base. A
similar work flow exists for
--enable-valgrind mode below.
3.5.3 valgrind Support
The test suite is able to run all tests underneath the excellent
valgrind dynamic analysis tool with the
--enable-valgrind command line argument.
[spaserver]# ./test-fwknop.pl --enable-valgrind
By examining test suite
output with valgrind enabled, memory leaks and other bugs become a lot easier to
find. Here is some example valgrind output produced by the test suite, and the
corresponding fix:
44 bytes in 1 blocks are definitely lost in loss record 2 of 2
at 0x482BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
by 0x490EA50: strdup (strdup.c:43)
by 0x10CD69: incoming_spa (incoming_spa.c:162)
by 0x10E000: process_packet (process_packet.c:200)
by 0x4862E63: ??? (in /usr/lib/i386-linux-gnu/libpcap.so.1.1.1)
by 0x4865667: pcap_dispatch (in /usr/lib/i386-linux-gnu/libpcap.so.1.1.1)
by 0x10DABF: pcap_capture (pcap_capture.c:226)
by 0x10A798: main (fwknopd.c:299)
When working on fwknop code, one of the most powerful ways of executing the test suite
is successive runs as follows to ensure no compilation warnings under
-Wall
and with valgrind enabled. Then by applying
--diff mode across these runs it
becomes easier to verify whether new code is properly developed. Here is an example where
a code change got rid of a valgrind warning - you can see the warning removed from the
output/42.test file:
[spaserver]# ./test-fwknop.pl --enable-recompile --enable-valgrind
[spaserver]# ./test-fwknop.pl --enable-recompile --enable-valgrind
[spaserver]# ./test-fwknop.pl --diff
[+] Checking: [Rijndael SPA] [client+server] complete cycle (tcp/22 ssh)
--- output.last/42.test 2012-10-04 21:36:17.660155003 -0400
+++ output/42.test 2012-10-04 21:36:17.692155003 -0400
@@ -5,30 +5,14 @@
Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
Command: ../client/.libs/fwknop -A tcp/22 -a 127.0.0.2 -D 127.0.0.1 --get-key local_spa.key --verbose --verbose
-Invalid read of size 4
- at 0x4E37DF4: fko_encrypt_spa_data (fko_encryption.c:65)
- by 0x10B036: main (fwknop.c:292)
- Address 0x583c3fc is 108 bytes inside a block of size 110 alloc'd
- at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
- by 0x4E37DA8: fko_encrypt_spa_data (fko_encryption.c:56)
- by 0x10B036: main (fwknop.c:292)
-
-Invalid read of size 4
- at 0x4E37E47: fko_encrypt_spa_data (fko_encryption.c:69)
- by 0x10B036: main (fwknop.c:292)
- Address 0x583c3fc is 108 bytes inside a block of size 110 alloc'd
- at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
- by 0x4E37DA8: fko_encrypt_spa_data (fko_encryption.c:56)
- by 0x10B036: main (fwknop.c:292)
-
send_spa_packet: bytes sent: 161
3.5.4 Anonymizing Test Suite Output
If the test suite has uncovered a problem, the results files can be anonymized
(all IP address, hostnames, and other identifying information removed) so that
they can be sent around to fwknop developers for comment. This process has
been automated with the
--Anonymize-results command line argument:
[spaserver]# ./test-fwknop.pl --Anonymize-results
[+] Anonymizing all IP addresses and hostnames from output files...
Creating tar file: test_fwknop.tar.gz
test.log
output/
output/1.test
output/test.log
output/1_fwknopd.test
...
output/init
[+] Anonymized test results file: test_fwknop.tar.gz
Now the
test_fwknop.tar.gz can be safely shared with others, though it is recommended to
review the information it contains just to be sure that nothing sensitive made it through. The
anonymization step sets all IPv4 addresses to "N.N.N.N" and removes hostnames from
uname
output. Typically the
test_fwknop.tar.gz file is sent to an fwknop developer
for review whenever a test fails.
4. fwknop Operations
This section covers general operations of fwknop. It is assumed that fwknop has been
installed on both the
spaclient (IP: 1.1.1.1) and
spaserver (IP: 2.2.2.2) systems so that proper operations can be illustrated.
Also, in this section we generally show fwknopd execution on Ubuntu Linux, but analogous
operations apply to other supported platforms.
4.1 Starting and Stopping the fwknopd daemon
Depending on which platform fwknop is deployed, starting and stopping the fwknop
daemon may be accomplished via different mechanisms. On a Linux system such as
Ubuntu that is running
upstart, controlling
fwknopd is quite easy:
[spaserver]# service fwknop status
fwknop start/running, process 8002
[spaserver]# service fwknop stop
fwknop stop/waiting
[spaserver]# service fwknop start
fwknop start/running, process 8540
One nice reason to use
upstart is built-in process monitoring and the
ability to restart a daemon if it ever dies. This eliminates fwknopd as a single
point of failure for services that it is guarding. So, if one were to kill the
fwknopd daemon on
spaserver, we'd see that
upstart
has restarted it:
[spaserver]# kill `pgrep fwknopd`
[spaserver]# service fwknop status
fwknop start/running, process 32743
[spaserver]# grep fwknop /var/log/syslog | tail -n 1
Sep 27 20:17:17 spaserver kernel: [123463.123937] init: fwknop main process ended, respawning
The fwknopd daemon also has a built-in status checking ability to see if an fwknopd process
is currently running:
[spaserver]# fwknopd --status
Detected fwknopd is running (pid=8540).
4.2 SPA with Symmetric Keys (via Rijndael)
This section illustrates gaining access to two different services, sshd and IMAP over SSL
with SPA using symmetric encryption keys via the Rijndael cipher. We configure fwknopd
to sniff
eth0 via the
/etc/fwknop/fwknopd.conf file on the
spaserver system just as in the
Quick Start section. We also configure the
/etc/fwknop/access.conf
file with a stanza to define the symmetric encryption key along with a few other parameters.
In this case, allow SPA clients to request access to tcp/22 (ssh) or tcp/993 (IMAPS) via the
OPEN_PORTS variable, and we also force SPA clients to explicitly include the
IP that should be granted access with the
REQUIRE_SOURCE_ADDRESS. On the fwknop
command line, the allow IP can be set via
the
-a <IP> argument, or the client can resolve its own IP via
http://www.cipherdyne.org/cgi-bin/myip
with the
-R command line argument.
[spaserver]# grep PCAP_INTF /etc/fwknop/fwknopd.conf
PCAP_INTF eth0;
[spaserver]# cat /etc/fwknop/access.conf
SOURCE: ANY;
OPEN_PORTS: tcp/22, tcp/993; ### SSH and IMAP over SSL
KEY: yourdecryptkey;
REQUIRE_SOURCE_ADDRESS: Y;
FW_ACCESS_TIMEOUT: 30;
We assume that iptables is configured in a default-drop stance for both sshd and IMAPS,
and that a connection tracking rule exists to allow packets that are part of established
TCP connections to make it through. The following commands accomplish this for these two services,
but you will probably want to integrate this with any firewall policy interface that
you normally use. Some additional information is mentioned in the
Default-Drop Firewall Policy
section.
[spaserver]# iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -j DROP
[spaserver]# iptables -I INPUT 1 -i eth0 -p tcp --dport 993 -j DROP
[spaserver]# iptables -I INPUT 1 -i eth0 -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Now, from the
spaclient system we run the fwknop client in order to gain
access to both sshd and IMAPS (note the usage of
-R to automatically
resolve the externally facing client IP):
[spaclient]$ fwknop -A tcp/22,tcp/993 -R -D spaserver
Enter encryption password:
[spaclient]$ ssh mbr@spaserver
mbr@spaserver's password:
4.3 SPA with Asymmetric Keys (via GnuPG)
Some people prefer using the security properties provided by GnuPG as the encryption/decryption
method of choice for Single Packet Authorization. This section shows how to leverage GnuPG keys
for SPA. First, you will need to first create the necessary GnuPG keys on both the client and
server. If you already have a sensitive GnuPG key that you use for email (or other) encryption,
you can safely use this key on the client side since it will only be used for message signing by
fwknop. On the fwknopd server you will need to create a special GnuPG key that is exclusively
used for fwknop communications. The reason stems from the fact that the password used
to unlock this key must be stored within the
/etc/fwknop/access.conf file since
fwknopd must be able to decrypt messages that have been encrypted by an fwknop
client with the server's public key. Hence, it is not a good idea to use a
highly valuable personal GnuPG key on the server. It is also possible to create GnuPG keys on
the server with no password and then set "
GPG_ALLOW_NO_PW: Y;" in the
access.conf file. While this may sound like a bad idea, in automated environments
it makes sense because "there is usually no way to store a password more securely than on the
secret keyring itself" according to:
http://www.gnupg.org/faq/GnuPG-FAQ.html#how-can-i-use-gnupg-in-an-automated-environment.
Using this feature and removing the passphrase from a GnuPG key pair is also useful in some
environments where libgpgme is forced to use gpg-agent and/or pinentry to collect a passphrase.
In order for fwknop to support SPA via GnuPG you will need the
libgpgme library
installed. When compiling fwknop, the autoconf
configure script automatically
detects whether
libgpgme is installed, and if so, it compiles in GnuPG support by
default.
Once you have created the requisite keys as shown below, you will need to import and sign each key
into its "opposite" system. That is, import and sign the server key into the client's GnuPG key ring,
and vice-versa. Because SPA messages must fit within a single IP packet, it is recommended to
choose a key size of 2048 bits or less for the fwknopd server GnuPG key. The process of
generating the necessary GnuPG keys from the perspectives of both the client and server is
outlined below. First we generate GnuPG keys and then export them to ascii files:
[spaserver]# gpg --gen-key
[spaserver]# gpg --list-keys
pub 1024D/ABCD1234 2012-05-01
uid fwknop server key <fwknopd@spaserver>
sub 2048g/EFGH1234 2012-05-01
[spaserver]# gpg -a --export ABCD1234 > server.asc
[spaclient]$ gpg --gen-key
[spaclient]$ gpg --list-keys
pub 1024D/1234ABCD 2012-05-01
uid fwknop client key <fwknop@spaclient>
sub 2048g/1234EFGH 2012-05-01
[spaclient]$ gpg -a --export 1234ABCD > client.asc
Next, we transfer the ascii files between the two systems. In this example we
use scp (which will presumably be firewalled off after fwknop is deployed!), but
any other transfer mechanism (ftp, http, etc.) will work:
[spaclient]$ scp client.asc root@spaserver:
[spaclient]$ scp root@spaserver:server.asc .
Now we import and sign each key:
[spaserver]# gpg --import client.asc
[spaserver]# gpg --edit-key 1234ABCD
Command> sign
[spaclient]$ gpg --import server.asc
[spaclient]$ gpg --edit-key ABCD1234
Command> sign
On the server side, we need to add several configuration directives to the
/etc/fwknop/access.conf file so that fwknopd uses GnuPG to verify and decrypt SPA
packets and are signed and encrypted with GnuPG. Note that the server key ID is
ABCD1234
and the client key ID is
1234ABCD:
SOURCE: ANY;
OPEN_PORTS: tcp/22, tcp/993;
GPG_REMOTE_ID: 1234ABCD;
GPG_DECRYPT_ID: ABCD1234;
GPG_DECRYPT_PW: <your decryption password>; ### or set GPG_ALLOW_NO_PW and remove the passhprase
GPG_HOME_DIR: /root/.gnupg;
FW_ACCESS_TIMEOUT: 30;
Now, to gain access to sshd, we execute fwknop:
[spaclient]$ fwknop -A tcp/22 --gpg-recip ABCD1234 --gpg-sign 1234ABCD -R -D spaserver
Enter passphrase for signing:
[spaclient]$ ssh -l mbr spaserver
mbr@spaserver's password:
4.4 Handling Multiple Services
By default, an SPA user can request access to any service within a properly constructed SPA
packet (i.e. one that matches the decryption key specified in a corresponding stanza in the
/etc/fwknop/access.conf file). That is, a user can request access to sshd over
tcp/22 and fwknopd would allow this by default. However, it is easy to restrict a user to
only be able to request access to specific services via the
OPEN_PORTS variable.
For example, if you only want a user to be able to request access to, say, tcp/22 and tcp/993,
you could set up an access.conf stanza like this:
[spaserver]# cat /etc/fwknop/access.conf
SOURCE: ANY;
OPEN_PORTS: tcp/22, tcp/993;
KEY: somedecryptkey;
REQUIRE_SOURCE_ADDRESS: Y;
REQUIRE_USERNAME: bob;
FW_ACCESS_TIMEOUT: 30;
Now, the user can gain access to both services simultaneously with the following:
[spaclient]$ fwknop -A tcp/22,tcp/993 -R -D spaserver
Enter encryption password:
On the server side, two new
ACCEPT rules are added - one for tcp/22 and the other
for tcp/993. Both rules are deleted after 30 seconds:
Oct 2 23:11:39 spaserver fwknopd[8540]: (stanza #1) SPA Packet from IP: 1.1.1.1 received with access source match
Oct 2 23:11:39 spaserver fwknopd[8540]: Added Rule to FWKNOP_INPUT for 1.1.1.1, tcp/22,tcp/993 expires at 1349406729
Oct 2 23:11:39 spaserver fwknopd[8540]: Added Rule to FWKNOP_INPUT for 1.1.1.1, tcp/22,tcp/993 expires at 1349406729
Oct 2 23:12:09 spaserver fwknopd[8540]: Removed rule 1 from FWKNOP_INPUT with expire time of 1349406729.
Oct 2 23:12:09 spaserver fwknopd[8540]: Removed rule 1 from FWKNOP_INPUT with expire time of 1349406729.
If the
OPEN_PORTS variable is used and the user requests access to a service
that is not listed with this variable then fwknopd refuses to grant access. This scenario is
illustrated in the next section.
4.5 Handling Multiple Users
fwknop supports the ability to have dedicated SPA keys for multiple users - each user can have
their own set of SPA keys (asymmetric and/or symmetric). In addition, each user can be
restricted to only being able to access a particular service and/or being granted access
from a particular set of networks (if these are known up front). All of these access qualifiers
along with the encryption keys themselves are placed within the
/etc/fwknop/access.conf
file. Below is an example
access.conf file that configures a combination of Rijndael
and GnuPG usage for a set of three remote users: Bob (username: bob), Alice (username: alice),
and John (username: john):
[spaserver]# cat /etc/fwknop/access.conf
SOURCE: ANY; # for bob
OPEN_PORTS: tcp/22;
KEY: bobdecryptkey;
REQUIRE_SOURCE_ADDRESS: Y;
REQUIRE_USERNAME: bob;
FW_ACCESS_TIMEOUT: 30;
SOURCE: ANY; # for alice
GPG_REMOTE_ID: 7234ABCD;
GPG_DECRYPT_ID: EBCD1234;
GPG_ALLOW_NO_PW: Y;
REQUIRE_SOURCE_ADDRESS: Y;
REQUIRE_USERNAME: alice;
FW_ACCESS_TIMEOUT: 30;
SOURCE: 3.3.3.0/24, 4.4.0.0/16; # for john
OPEN_PORTS: tcp/80;
KEY: johndecryptkey;
REQUIRE_USERNAME: john;
REQUIRE_SOURCE_ADDRESS: Y;
FW_ACCESS_TIMEOUT: 300;
This results in a number of things:
- All three users (Bob, Alice, and John) must use
-a or -R
on the fwknop command line so that the source IP is encrypted within the SPA packet.
- Bob can access sshd from any source network via an SPA packet that has been encrypted
with the proper Rijndael key.
- Alice is required to encrypt SPA packets with GnuPG - the server key ID is:
EBCD1234
and the client-side signing key ID is: 7234ABCD.
- Alice has the most access available since there is no usage of the
OPEN_PORTS variable.
This means that access to any service can be requested. A proper SPA packet can be built by Alice
with the following command:
[spaclient]$ fwknop -A tcp/22 --gpg-recip EBCD1234 --gpg-sign 7234ABCD -R -D spaserver
Enter passphrase for signing:
- John can only request access to
tcp/80, and can only do this with SPA packets from the
3.3.3.0/24 and 4.4.0.0/16 networks. That is, the source IP of the SPA packet
must originate from an IP within one of these networks. Note that is in addition to the
REQUIRE_SOURCE_ADDRESS criteria. If John builds an SPA packet that requests access to a
service other than tcp/80, fwknopd will reject it with the following message written via
syslog:
Oct 2 20:06:05 spaserver fwknopd[8540]: (stanza #3) One or more requested protocol/ports was denied per access.conf.
4.6 Client Automation with the --get-key Option
There are some environments where typing in a passphrase to generate an encryption key is not
convenient. This is where the
--get-key <file> option comes in to specify a
path to a file where the passphrase is stored in the filesystem. The fwknop client then just
reads this file and does not prompt the user to type in any passphrase. This strategy is used
by the test suite to execute the client without requiring manual user input.
Here is an example command line to illustrate
--get-key usage:
[spaclient]$ fwknop -A tcp/22 --get-key /some/path/to/fwknop.key -R -D spaserver
The format of the
--get-key file is "
IP|host: key" like this:
[spaclient]$ cat /some/path/to/fwknop.key
spaserver: somedecryptkey
4.7 SPA Across NAT Gateways
From the
spaclient system we have already sent SPA packets out through the gateway with
external IP
1.1.1.1 as depicted in
Figure 1. However, this only applies
to client-side Network Address Translation (NAT) for the outgoing SPA packet and associated ssh (or other)
connection. How about making use of NAT on the
spaserver system to transparently access
services running on the subnet
behind it?
One of the more important features offered by the fwknopd daemon is the ability to interact with
the NAT facilities offered by the local firewall. This is only supported
on Linux for iptables firewalls as of fwknop-2.0.3, but NAT support on ipfw and PF is coming soon as well.
What this enables is the ability to transparently translate incoming connections from the Internet
to services that are running on internal hosts behind the firewall that is running fwknopd. The use case
where this makes the most sense is when the user does not want to access sshd on the firewall itself but
on a system behind the firewall. Access could be granted to sshd on the firewall and then the user could
ssh from there to the internal host, but this is adds unnecessary overhead when fwknopd can just build
a NAT rule to have the incoming ssh connection go directly to the internal host.
Let's illustrate this scenario by accessing sshd on
10.2.1.10 behind the
spaserver.
First, we'll need to reconfigure the
/etc/fwknop/fwknopd.conf file to allow SPA clients
to request NAT rules with the
ENABLE_IPT_FORWARDING variable:
[spaserver]# grep ENABLE_IPT_FORWARDING /etc/fwknop/fwknopd.conf
ENABLE_IPT_FORWARDING Y;
[spaserver]# service fwknop restart
fwknop stop/waiting
fwknop start/running, process 12624
Now from
spaclient we request access to sshd running on
10.2.1.10:
[spaclient]$ fwknop -A tcp/22 -N 10.2.1.10:22 -R -D spaserver
Enter encryption password:
[spaclient]$ ssh -l mbr spaserver
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
12:34:0d:37:23:1e:f5:2b:12:12:12:c5:b9:63:23:23.
Please contact your system administrator.
Add correct host key in /home/mbr/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/mbr/.ssh/known_hosts:16
remove with: ssh-keygen -f "/home/mbr/.ssh/known_hosts" -R 2.2.2.2
RSA host key for 2.2.2.2 has changed and you have requested strict checking.
Host key verification failed.
We see the warning above because fwknopd has built iptables
DNAT and
FORWARD
rules to automatically NAT the incoming ssh connection to the 10.2.1.10 system. First we show the
syslog message that fwknopd generates for this, and then illustrate the rules themselves with the
--fw-list switch:
Oct 7 14:26:55 spaserver fwknopd[12624]: (stanza #1) SPA Packet from IP: 1.1.1.1 received with access source match
Oct 7 14:26:55 spaserver fwknopd[12624]: Added FORWARD Rule to FWKNOP_FORWARD for 1.1.1.1, tcp/22 expires at 1349634445
Oct 7 14:26:55 spaserver fwknopd[12624]: Added DNAT Rule to FWKNOP_PREROUTING for 1.1.1.1, tcp/22 expires at 1349634445
[spaserver]# fwknopd --fw-list
Listing rules in fwknopd iptables chains...
Chain FWKNOP_INPUT (1 references)
num target prot opt source destination
Chain FWKNOP_FORWARD (1 references)
num target prot opt source destination
1 ACCEPT tcp -- 1.1.1.1 10.1.2.10 tcp dpt:22 /* _exp_1349634445 */
Chain FWKNOP_PREROUTING (1 references)
num target prot opt source destination
1 DNAT tcp -- 1.1.1.1 0.0.0.0/0 tcp dpt:22 /* _exp_1349634445 */ to:10.1.2.10:22
After correcting the ssh key warning, an ssh connection will be allowed transparently through
the
2.2.2.2 border firewall into the
10.2.1.10 system.
4.7.1 SPA Ghost Services
A further refinement of the server-side NAT concept is to NAT connections from an SPA-authenticated
client
simultaneously while a service is already bound to a port. That is, in
Figure 1
a webserver is deployed at IP
10.1.2.3. Let us assume that the
2.2.2.2 firewall has
a policy deployed that automatically translates incoming connections on port 80 to this internal system - i.e. making
the Apache instance a public webserver. Fine. Now, instead of having fwknopd on
2.2.2.2 NAT an
incoming port 22 connection also to port 22 on
10.1.2.10, let's alter the fwknop client command
line to have fwknopd NAT incoming connections to
port 80 over to port 22 on
10.1.2.10.
This will only be done for the source IP
1.1.1.1, so everyone else on the Internet only ever
sees the same Apache webserver while the
spaclient system has access to sshd on
10.1.2.10:
[spaclient]$ fwknop -A tcp/80 -N 10.2.1.10:22 -R -D spaserver
Enter encryption password:
[spaclient]$ ssh -p 80 -l mbr spaserver
mbr@spaserver's password:
Note that we changed "
tcp/22" to "
tcp/80" on the fwknop command line, and we also
instructed ssh to make the connection over port 80 with "
-p 80". Finally, as before, here are the
syslog messages and iptables rules that fwknopd adds:
Oct 7 15:26:22 spaserver fwknopd[12624]: (stanza #1) SPA Packet from IP: 1.1.1.1 received with access source match
Oct 7 15:26:22 spaserver fwknopd[12624]: Added FORWARD Rule to FWKNOP_FORWARD for 1.1.1.1, tcp/80 expires at 1349638012
Oct 7 15:26:22 spaserver fwknopd[12624]: Added DNAT Rule to FWKNOP_PREROUTING for 1.1.1.1, tcp/80 expires at 1349638012
[spaserver]# fwknopd --fw-list
Listing rules in fwknopd iptables chains...
Chain FWKNOP_INPUT (1 references)
num target prot opt source destination
Chain FWKNOP_FORWARD (1 references)
num target prot opt source destination
1 ACCEPT tcp -- 1.1.1.1 10.1.2.10 tcp dpt:22 /* _exp_1349638012 */
Chain FWKNOP_PREROUTING (1 references)
num target prot opt source destination
1 DNAT tcp -- 1.1.1.1 0.0.0.0/0 tcp dpt:80 /* _exp_1349638012 */ to:10.1.2.10:22
The concept of having SPA result in connections for a service being translated through to a different system
even though another service is already bound to the destination port on which the connection is made is
called SPA "ghost services", and was announced in the blog post
"
Creating Ghost Services with Single Packet Authorization".
4.8 User Interfaces
4.8.1 iPhone Client
Below is a screenshot of the fwknop client running on an iPhone. The code itself is available
in the top level
iphone/ directory in the
fwknop sources.
Max Kastanas contributed both the iPhone and Android code.
4.8.2 Android Client
Below are screenshots of the fwknop client running on an Android phone. The code itself is available
in the top level
android/ directory in the
fwknop sources.
4.8.3 Windows Morpheus UI
4.8.4 Web Proxy
4.9 SPA Packet Spoofing
By default, the fwknop client sends SPA packets over UDP port 62201. This allows the client
to easily send SPA packets over the network without requiring any
special privileges
since it doesn't manipulate raw
packet headers by default. However, if the user that
is running the client
does happen to have admin level access, fwknop can send SPA packets
over the network from spoofed source IP addresses. Two command line arguments are required
in order to spoof the source IP: "
-Q <IP> -P udpraw" as follows:
[spaclient]$ fwknop -A tcp/22 -P udpraw -Q 4.4.4.4 -R -D spaserver
Enter encryption password:
Assuming that the local firewall policy is not setup to stop spoofed packets from being sent
over the wire, then the remote fwknopd daemon will see the source IP on the SPA packet as
4.4.4.4. However, with
REQUIRE_SOURCE_ADDRESS enabled in the
/etc/fwknop/access.conf file, fwknopd will only allow access to the IP address
that is encrypted within the SPA packet - not the spoofed source address. In this case, since
the
-R argument was used, the IP that will be allowed is
1.1.1.1 for
the
spaclient system:
Oct 2 22:14:56 spaserver fwknopd[12624]: (stanza #1) SPA Packet from IP: 4.4.4.4 received with access source match
Oct 2 22:14:56 spaserver fwknopd[12624]: Added Rule to FWKNOP_INPUT for 1.1.1.1, tcp/22 expires at 1349403326
4.10 Stopping Replay Attacks
One of the main reasons to implement Single Packet Authorization as an improvement over
port knocking is to make replay attacks a thing of the past. This section illustrates how
an attacker might attempt a replay attack and shows that fwknop is not vulnerable - the attack
is detected and a warning message is written to syslog. First, from the Quick Start
"
Gaining access to sshd with the fwknop client" section above, the fwknop
client is executed in
--verbose mode, and this prints out the raw encrypted SPA
payload data that fwknop transmits on the wire. From this output, here is the raw payload data:
85yR1UXTnKQRKbIyLgjVJZPEdbhZJr//+ctXyL38a3VMvs2/NDH775WwVRe1EBnhqoEE9pFPrqHv5d8CVfh//FyOoqwveoBs+zbgb1LvoE4f6/9UJFybUWrApsB6z/0U9p1dPCdcbe1blK/H8hUgbOvWrKA7m8j30
One can also use an Ethernet sniffer such as
tcpdump to verify that this data is
what the client sends over the wire. Now, from the Quick Start section, this SPA packet was
already sent from the
spaclient system to the
spaserver system in order
to gain access to sshd. So, this particular SPA packet has been used once, and therefore should
never be seen again on the wire. Let's assume that an attacker was able to monitor and capture
the SPA packet above, and that the same attacker thinks that this data might be part of SPA
communications. The attacker is certainly free to replay the same packet on the wire and send
it to the
spaserver system, and this is easily done as follows:
[attacker]$ echo -n "85yR1UXTnKQRKbIyLgjVJZPEdbhZJr//+ctXyL38a3VMvs2/NDH775WwVRe1EBnhqoEE9pFPrqHv5d8CVfh//FyOoqwveoBs+zbgb1LvoE4f6/9UJFybUWrApsB6z/0U9p1dPCdcbe1blK/H8hUgbOvWrKA7m8j30" | nc -u spaserver 62201
On the
spaserver system, fwknopd will sniff the replayed SPA packet, and will
compare the SHA-256 digest of this packet vs. the SHA-256 digest of all previously seen and
properly decrypted SPA packets. If there is a match, then fwknopd knows that a replay attack
was attempted (subject to there not being a collision in the SHA-256 calculation, which is
exceedingly unlikely). In this case, fwknopd generates the following warning via
syslog, and no access is granted to the attacker:
Oct 3 22:07:22 spaserver fwknopd[12624]: Replay detected from source IP: 3.3.3.3, Destination proto/port: 17/62201, Original source IP: 1.1.1.1, Original dst proto/port: 17/62201, Entry created: 10/03/12 20:52:39
Note in the above output that the source IP of the replayed SPA packet is
3.3.3.3.
This is the attacker's IP address that we've chosen for the purposes of illustration. It makes
no difference what the source IP is of the replayed packet because the SHA-256 digest is
computed over the SPA payload data.
4.11 SPA Over Tor
Adding strong anonymity to SPA communications via
Tor
is possible if one agrees to send SPA packet data over established TCP connections. This is a
requirement because building a virtual circuit through the Tor network is only done for TCP,
and then only for connections that are in the established state. The fwknop "
-P tcp"
argument instructs the fwknop client to establish a TCP connection with the SPA packet destination,
so if this destination happens to be a proxy that can communicate over Tor then we're in business.
This is where the
socat project comes in. We'll
use it to create a socks proxy that interfaces with Tor, and then connect to it with the fwknop
client. This requires that the fwknop daemon listen on a TCP port for SPA data, and for this we
set "
ENABLE_TCP_SERVER Y;" in the
/etc/fwknop/fwknopd.conf file on
spaserver and restart. By default, in this mode fwknopd listens on TCP port 62201,
but this can be changed with the
TCPSERV_PORT variable. With fwknopd restarted, we
now fire up the
socat proxy on
spaclient and run fwknop:
[spaclient]$ socat TCP-LISTEN:62201 SOCKS4A:127.0.0.1:2.2.2.2:62201,socksport=9050 &
[1] 20551
[spaclient]$ fwknop -A tcp/22 -a 1.1.1.1 -D 127.0.0.1 -P tcp
Enter encryption password:
Behind the scenes, the SPA is sent over Tor to the destination IP 2.2.2.2 (
spaserver). The
fwknop daemon monitors the SPA packet, and grants access to sshd from 1.1.1.1:
Oct 2 23:11:56 spaserver fwknopd[12624]: (stanza #1) SPA Packet from IP: 96.47.N.N received with access source match
Oct 2 23:11:56 spaserver fwknopd[12624]: Added Rule to FWKNOP_INPUT for 1.1.1.1, tcp/22 expires at 1349403326
The 96.47.N.N IP (partially blanked out) is a live Tor exit router. So, the SPA packet was
given strong anonymity by Tor, but the ssh connection itself must be made from 1.1.1.1 directly.
This is because the next virtual circuit built through the Tor network by an ssh connection might
go through a different exit router, and therefore isn't predictable at the time the SPA packet
is sent. However, if you want both the SPA packet and the ssh conneciton to use the same exit
router, then you can set the exit router manually in
/etc/tor/torrc via the
"
ExitNodes" directive. In this case, you would want to instruct fwknopd to allow
the ssh connection from the same exit router by specifying its IP on the fwknop command line
e.g. "
-a 96.47.N.N":
[spaclient]$ fwknop -A tcp/22 -a 96.47.N.N -D 127.0.0.1 -P tcp
Enter encryption password:
5. fwknop Design Goals
Below are the design choices that guide fwknop development. Other PK/SPA software make different
design choices, and whether you prefer fwknop vs. another implementation depends at least partially
on whether you agree with the following:
- No Heavyweight Interpreted Languages
Many people don't want to install perl,
python, or ruby on a firewall or network gateway device. Such languages are large and
complex, and are implemented by similarly complex binaries that are usually themselves
written in a language like C. Firewalls are frequently stripped down systems that are
designed to just filter network traffic, provide administrative interfaces and sometimes
VPN services, and not do much else. Both the fwknop client and server are entirely
written in C - there is no requirement for perl, python, or any other interpreted language.
- Support Embedded Devices
A consequence of fwknop being developed in C is that it only uses minimal system resources
and can therefore support embedded devices that don't have a lot of computing power or
main memory. For example, where the older perl version of fwknop could not run on Linksys
routers supported by OpenWRT, these same routers can run the newer C version of fwknop.
- Don't Require Admin Access to Run the SPA Client
There are many computing environments where users don't have privileged accounts. This
should not present a barrier to using the SPA client. In fwknop, SPA packets are (by
default) sent over a regular UDP socket and therefore require no special
privileges.
- Don't Require the Manipulation of Raw Packet Headers
There are some SPA implementations that communicate information within specially modified
fields within IP or TCP headers. Such manipulation requires that the user have the
ability to acquire a raw socket from the OS, and this requires admin level privileges.
In addition, depending on how the SPA client manipulates packet headers when building an
SPA packet, other monitoring systems such as an IDS or a passive OS fingerprinter may
produce event data that unnecessarily calls attention to the SPA communications. This
is not to say that that is impossible to detect SPA packets generated by fwknop - it is
just that a monitoring system is more likely to flag communications that involve
manipulated packet headers than to generate an event for packets produced by
fwknop. For example, intrusion detection systems track TCP connections, and spoofed TCP
ACK's that are not part of a proper connection (assuming non-asymmetric routing) may
potentially be flagged. Also, manipulated TCP options fields that don't conform to OS
defaults will cause an OS to appear to change under the observation of things like
p0f. While sometimes this is an expected
behavior such as if a VM is being run or a system is actually a NAT device with other
systems behind it, there are plenty of deployment scenarios where this is not expected.
- Don't trust the IP header
Any SPA implementation that trusts the source IP address in the IP header of the SPA packet
is vulnerable to a MITM attack. An inline device that can intercept an SPA packet
can hold the original packet and retransmit it but with the source IP changed to
whatever the attacker wants. If the SPA server relies on the source IP in the
IP header, then it has no way to know that it isn't legitimate. If an SPA
implementation is going to go to the trouble of leveraging cryptography - certainly
important since replay attacks among other problems can't be prevented without it - then
the IP should be made part of an encrypted payload. This is exactly what fwknop does with
the
-a or -R arguments on the fwknop command line. An attacker
can intercept an SPA packet produced by fwknop, change the source IP and retransmit, but
SPA server will only allow access to the IP that was originally encrypted within the SPA
payload.
- Support Server-Side NAT
There are plenty of networks with a border firewall where a remote user actually wants
access to a service that is running on an internal system and not on the firewall itself.
Typical ways of accessing such a service involve running VPN software, but with an SPA
implementation that can manipulate NAT rules on the border firewall it is possible to
transparently grant SPA users access to internal services through the firewall.
With fwknop, the capability to leverage
server-side NAT
has been built in for a long time.
- Support Cloud Computing Environments
Supporting Cloud Computing environments such as Amazon's AWS Virtual Private Cloud
(VPC) networks is an extension of supporting server-side NAT. Since fwknopd
can build NAT rules for incoming connections to other internal systems transparently,
this easily brings SPA to cloud computing networks. For instance, an important
use case for SPA within Amazon's cloud is the ability to protect internal Windows
instances from the Windows RDP vulnerability from 2012
(CVE-2012-0002).
One challenge for this is the fact that fwknopd does not directly support a Windows
firewall. The solution is to deploy a virtual Linux instance on the VPC network and
then use either the normal SNAT/DNAT capabilities in fwknopd, or use FORCE_NAT
mode. Either way, RDP connections can be made to internal Windows systems through the
Linux "jump host" after a proper SPA packet is sent. This scenario is illustrated
by the following graphic:
- Support Multiple Firewalls
Because fwknop does not rely on specialized logging infrastructure or link against
libraries that are tied to one firewall architecture or another, it can easily support
multiple firewalls just by executing the local firewall admin command line interface.
It currently supports iptables on Linux,
ipfw
on FreeBSD and Mac OS X, and pf on OpenBSD.
- Minimize Library Dependencies
Given the design decisions made by fwknop above, it is important to minimize library
dependencies and to audit the source code. Here are all library dependencies in the
fwknopd daemon including GnuPG support (this is optional):
$ ldd /usr/sbin/fwknopd
linux-vdso.so.1 => (0x00007ffeebf820e0)
libfko.so.0 => /usr/lib/libfko.so.0 (0x00007f1a6ae930e0)
libpcap.so.0.8 => /usr/lib/x86_64-linux-gnu/libpcap.so.0.8 (0x00007e1a6a85c0e0)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007e1a6a49e0a0)
libgpgme.so.11 => /usr/lib/libgpgme.so.11 (0x00007f1aeaee800e)
/lib64/ld-linux-x86-64.so.2 (0x00007e1a6aede0e0)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x0000ef1a6a06e0e0)
The libfko library is developed by the fwknop project for SPA encryption, decryption,
and validation. libpcap is a standard C library that is leveraged by a lot of
security projects including intrusion detection systems and more. The gpgme libraries
are only used if you want GnuPG support, and the remaining libraries are standard
system libraries that typical Linux binaries need. That's it. One may certainly
question the use of libpcap, and in defense of this choice note that: 1)
fwknopd by default does not put the sniffing interface into promiscuous mode, 2)
fwknopd by default only pays attention to UDP packets to port 62201, 3) if you
examine Metasploit you'll see that there only a few exploits for pcap-based software
and they target what rides on top of libpcap vs. libpcap itself, and 4) even
if there is a vulnerability in libpcap, the exploit model is different than it is
for normal server software that you can easily scan for, and being different in this
game is good.
- Support Both Symmetric and Asymmetric Ciphers
Some users prefer the security properties that asymmetric crypto systems have over those
provided by symmetric algorithms like Rijndael, or vice versa. fwknop supports both
Rijndael and GnuPG for SPA encryption/decryption. On another note,
HMAC-SHA256 support
is coming soon to fwknop.
- Leverage Compiler and OS Security Features
By default, fwknop is:
- Compiled with
-Wall to flag all compile warnings (zero warnings currently on Ubuntu 12.04 with gcc-4.6.3).
- Built with
-fstack-protector for gcc protection against stack overflows.
- Built with support for Address Space Layout Randomization (ASLR) / built as Position Independent Executable (PIE).
- Built with Fortify Source (
-D_FORTIFY_SOURCE=2).
- Built with RELRO.
- Built with BIND_NOW.
Many of the security hardening features above are described in the
Ubuntu Security Wiki.
6. fwknop Communications
6.1 SPA Packet Format
The fwknop client (and anything that uses the
libfko library to generate SPA
packets) creates SPA data according to a particular format before it is encrypted. This
allows the fwknopd daemon to validate incoming SPA packets and apply appropriate access controls.
Every SPA packet has a series of mandatory fields, and depending on the desired access may
also contain a series of optional fields. The fwknop client accepts input from the user,
populates the SPA packet with data built from this input, encrypts and base64 encodes the packet,
and then sends in out on the wire towards the SPA server.
Mandatory SPA Packet Fields:
- 16 bytes of random data
- Local username
- Local time stamp
- fwknop version
- SPA message type
- Access request or command to execute
- SPA message digest (SHA-256 by default)
Optional SPA Packet Fields:
- NAT access request
- Third-party authentication information
- Firewall rule timeout
6.2 Raw SPA Packets
The default encryption algorithm used by the fwknop client is Rijndael, and
by using the
--verbose command line argument the raw encrypted data
can be seen on stdout before it is base64 encoded. For example, when fwknop
is used to build an SPA packet for gaining access to tcp/22 on the fwknopd
server system, here is an example of the raw encrypted data (in a hex dump
output format) followed by the same data in its base64 encoded form (command output
has been removed for brevity):
[spaclient]$ fwknop -A tcp/22 -R -D spaserver --verbose
Enter encryption password:
15:58:12.593286 IP 1.1.1.1.33299 > 2.2.2.2.62201: UDP, length 161
0x0000: 4500 00bd bad1 4000 4011 815c 7f00 0001 E.....@.@..\....
0x0010: 7f00 0001 8213 f2f9 00a9 febc 612f 755a ............a/uZ
0x0020: 7054 3543 5a67 5043 684b 625a 6634 4f6d pT5CZgPChKbZf4Om
0x0030: 4b57 3150 5371 7939 4543 3777 4c70 4831 KW1PSqy9EC7wLpH1
0x0040: 5432 3432 5234 6b70 4d30 4772 4877 7862 T242R4kpM0GrHwxb
0x0050: 6a37 314b 2b66 7656 3162 6432 776f 6c39 j71K+fvV1bd2wol9
0x0060: 4679 756c 3849 326b 4d68 654e 4859 614d Fyul8I2kMheNHYaM
0x0070: 4266 3244 6e35 436f 6f64 7a53 2b55 3173 Bf2Dn5CoodzS+U1s
0x0080: 3959 3733 4f65 7545 756d 3761 6335 4873 9Y73OeuEum7ac5Hs
0x0090: 7766 4854 7078 6a36 344b 3556 5973 544c wfHTpxj64K5VYsTL
0x00a0: 7575 2f6e 486b 566d 7947 4448 7678 2b6c uu/nHkVmyGDHvx+l
0x00b0: 7333 7664 3445 6261 517a 4569 62 s3vd4EbaQzEib
a/uZpT5CZgPChKbZf4OmKW1PSqy9EC7wLpH1T242R4kpM0GrHwxbj71K+fvV1bd2wol9Fyul8I2kMheNHYaM \
Bf2Dn5CoodzS+U1s9Y73OeuEum7ac5HswfHTpxj64K5VYsTLuu/nHkVmyGDHvx+ls3vd4EbaQzEib
SPA packets encrypted with Rijndael are typically on the order of about 200
bytes long or less.
Also supported by fwknop is GnuPG for asymmetric encryption, and SPA packets
encrypted with GnuPG are typically much larger - on the order of about 1000
bytes. Similarly to the above output, here is an example of using fwknop to
build an SPA packet with GnuPG (command output has again been removed):
[spaclient]$ fwknop --gpg-recip 361BBAD4 --gpg-sign 6A3FAD56 -A tcp/22 -R -D spaserver --verbose
Enter passphrase for signing:
16:10:58.674052 IP 1.1.1.1.44954 > 2.2.2.2.62201: UDP, length 1044
0x0000: 4500 0430 a6f2 4000 4011 91c8 7f00 0001 E..0..@.@.......
0x0010: 7f00 0001 af9a f2f9 041c 0230 494f 4133 ...........0IOA3
0x0020: 796f 4831 4c35 4f4e 4543 4541 662f 554e yoH1L5ONECEAf/UN
0x0030: 506b 5a61 6374 4259 4e53 5955 5964 6c30 PkZactBYNSYUYdl0
0x0040: 5944 5a46 662f 3234 5764 4468 6344 6d63 YDZFf/24WdDhcDmc
0x0050: 4a4e 4270 6f77 712f 7451 4978 5963 3253 JNBpowq/tQIxYc2S
0x0060: 7863 4758 4662 4362 304c 6c77 7476 654d xcGXFbCb0LlwtveM
0x0070: 6630 6472 6166 6476 4144 7361 4838 6b5a f0drafdvADsaH8kZ
0x0080: 7854 674f 4932 4877 4555 3756 7478 3766 xTgOI2HwEU7Vtx7f
0x0090: 6d55 3371 4f44 7938 4c6f 6978 786a 4d44 mU3qODy8LoixxjMD
0x00a0: 4251 3656 3145 5a4c 5331 6757 6550 5a70 BQ6V1EZLS1gWePZp
0x00b0: 4b6d 6b37 5358 5a61 6b74 7469 3958 594c Kmk7SXZaktti9XYL
0x00c0: 4246 4173 5470 4e4b 7175 2b53 4667 6774 BFAsTpNKqu+SFggt
0x00d0: 6846 4a33 724b 3064 657a 634d 6358 5739 hFJ3rK0dezcMcXW9
0x00e0: 6e48 5572 5057 6959 6745 6969 5773 6763 nHUrPWiYgEiiWsgc
0x00f0: 4841 4943 4f34 4178 5058 7767 5374 6162 HAICO4AxPXwgStab
...
0x0370: 632f 3658 694e 5836 4f57 5a31 4b7a 5263 c/6XiNX6OWZ1KzRc
0x0380: 6e4a 4852 5064 6f4d 6e42 2f6c 7367 4267 nJHRPdoMnB/lsgBg
0x0390: 4456 3952 5532 3463 6f53 7473 6732 7950 DV9RU24coStsg2yP
0x03a0: 346f 4a69 5830 664f 4e63 3430 304b 3175 4oJiX0fONc400K1u
0x03b0: 6c69 7641 6830 2f33 4b5a 7074 754d 5045 livAh0/3KZptuMPE
0x03c0: 6870 2b4a 7636 4745 6f43 796f 7978 372b hp+Jv6GEoCyoyx7+
0x03d0: 4e58 7264 4771 4b4c 7757 704b 6369 4167 NXrdGqKLwWpKciAg
0x03e0: 4974 7975 3854 3244 6255 616c 544c 782b Ityu8T2DbUalTLx+
0x03f0: 4d73 7168 4d69 4646 7575 3959 744a 2f2f MsqhMiFFuu9YtJ//
0x0400: 6661 7974 6d77 6d59 5533 6f48 6166 3547 faytmwmYU3oHaf5G
0x0410: 4330 434c 3044 5861 384a 4c52 572f 746e C0CL0DXa8JLRW/tn
0x0420: 2f71 6169 7977 4739 7374 664a 6976 4551 /qaiywG9stfJivEQ
IOA3yoH1L5ONECEAf/UNPkZactBYNSYUYdl0YDZFf/24WdDhcDmcJNBpowq/tQIxYc2SxcGXFbCb0LlwtveMf0drafdvADsaH8kZxTgOI2 \
HwEU7Vtx7fmU3qODy8LoixxjMDBQ6V1EZLS1gWePZpKmk7SXZaktti9XYLBFAsTpNKqu+SFggthFJ3rK0dezcMcXW9nHUrPWiYgEiiWsgcHAICO4AxPXwgS \
tabnqVrxT6QtVjX9uet2uG8JLkaTNzpmclFA6vyuK2XZAL7975YiOC6wMKaIqtrSjrKIUcfkUru9jDfHODP3GPf8h6t/4qDOFUzSfTVZ5EzegQEyV3MI3Qf \
EUAhdkBKySTamr/Af+M+CyJhJPbbqwy/LYjJM8ypkf75rV1gjGpLH1lgM+X/O6ARloRYYoTNuJyBhKHlJTB25QaXYfOvfBiRjLU7rqEDPC+coUdcrqZbl+i \
/HQMtVVqcrVJrzr6xVuI4ednShmwP3221pt2TgQ6HkP/8j2yMlNyEEYgjXKt+Zdlw3k0ODkFEH7cMIliUSgsOPzGtwO/WvDaVrkZQrZaZjS+lqGwvTn9dkL \
mcEV5iYuDTplmNOUSOX+afWaEH5S3t2P6ttsXhCD4Rzpx1uMDybwvss7ZIvYp91OPi957Pe1rCH3uCAeTzI5qbcR1PIu9X+dRDXpssaehmJLeq+DudZGQq3 \
e2NLAPAFpDH7MAc6AnXWfH2H2/sbXCSVqHPdsRH5yOlCxkW9ZGVnIdYPb9y3005Iz1trAJffLFVNCvLDQAcNA3qmUQHwHn6y2Vt30PiylPeOa6xrLlTmNs+ \
Q0jWOQdGR9q9NwN9I0U1GjIsWKNQJmi7c/6XiNX6OWZ1KzRcnJHRPdoMnB/lsgBgDV9RU24coStsg2yP4oJiX0fONc400K1ulivAh0/3KZptuMPEhp+Jv6G \
EoCyoyx7+NXrdGqKLwWpKciAgItyu8T2DbUalTLx+MsqhMiFFuu9YtJ//faytmwmYU3oHaf5GC0CL0DXa8JLRW/tn/qaiywG9stfJivEQ
7. fwknop Development
7.1 Programming Languages and Style
All recent versions of fwknop are developed in C. There are older versions written
in perl, but these are no longer maintained. The development process for fwknop
uses
valgrind to assist in the validation of
proper memory handling, security oriented compiler options are enabled, and the
C code for libfko is portable to Windows. The fwknop test suite is written in
perl for rapid prototyping of testing functionality, there are various supporting
shell scripts, the Android client is written in Java, and the iPhone client is
written in Objective C. With regard to programming style, all fwknop source code
uses spaces for indentation instead of having to worry about tabs. A width of
four spaces is used for each level of indentation.
7.2 Source Control (git)
All fwknop sources are tracked via
git, and you can
clone the repository either from
github
or from cipherdyne.org:
$ git clone https://www.github.com/mrash/fwknop fwknop.git
Cloning into 'fwknop.git'...
remote: Counting objects: 5275, done.
remote: Compressing objects: 100% (1603/1603), done.
remote: Total 5275 (delta 3672), reused 5155 (delta 3552)
Receiving objects: 100% (5275/5275), 2.07 MiB | 3.96 MiB/s, done.
Resolving deltas: 100% (3672/3672), done.
$ git clone http://www.cipherdyne.org/git/fwknop.git fwknop.git
Cloning into 'fwknop.git'...
7.3 Older Perl Releases
The perl version is no longer maintained, and it doesn't conform to one of the main
design goals of
not using heavyweight interpreted languages. However,
if you really want to run the perl version, all of the older fwknop releases are still
available at the
download page. Also, the perl sources
are checked in under the
perl/legacy/fwknop/ directory in git.
7.4 Submitting Patches
Being an open source project, patches against fwknop are heartily accepted.
Over the years, several people have
contributed
suggestions, bug fixes, and patches to the fwknop sources. Before submitting a patch,
you may want to review the latest public code in the latest release, or view the as yet
unreleased sources via the fwknop
gitweb.cgi
interface (or through git itself). Patches can be submitted to the fwknop mailing list
or emailed to
<mbr[at]cipherdyne.org>. If you are on Github, a patch can
be submitted via a pull request.
7.5 Primary Developers
The fwknop project was created by
Michael Rash in 2004
originally as a port knocking implementation for iptables firewalls, and SPA mode was
offered in 2005. Damien Stuart did the original port of the fwknop perl code to C
and implemented the libfko shared library architecture in the process. Today both
Michael and Damien are the primary developers of fwknop, and are assisted by many
worthy individuals who enjoy contributing to open source software. Damien can be
reached at
<dstuart[at]dstuart.org> and Michael at
<mbr[at]cipherdyne.org>.
7.6 Mailing List
The
fwknop-discuss
mailing list serves as a forum for asking questions, submitting patches, and providing
feedback on all things related to fwknop. Theoretical discussions of both port knocking
and Single Packet Authorization are also welcomed on this list. The list is generally
fairly low traffic, although from time to time there are spikes in the number of emails
if there is a software release or if new features are discussed for inclusion in fwknop.
New releases are always announced on the mailing list, and this includes pre-releases
for upcoming bug fixes and new features in the next major version.
8. References and Further Reading
8.1 Reference List
-
"An Analysis of Port Knocking and Single Packet Authorization"
- this is a Master's Thesis completed in September, 2006 by Sebastien Jeanquier at the
Royal Holloway College, University of London about the concepts of port knocking and
Single Packet Authorization. This is a standard reference for issues surrounding
PK/SPA, and makes an excellent argument for why neither PK nor SPA suffer from the
"security through obscurity" problem.
-
Online fwknop man pages
- the complete man pages for fwknop. This is the most comprehensive documentation for
the command line arguments supported by the fwknopd daemon and the fwknop client.
-
Wikipedia on Port Knocking and SPA
- this is the latest information that Wikipedia has on PK/SPA, and provides a fairly
good introduction to the technology and tradeoffs.
-
"Single Packet Authorization with fwknop"
- this paper was published in the February, 2006 issue of USENIX ;login: Magazine, and
is the first article on the fwknop implementation of SPA.
-
"
Enhancing Firewalls: Conveying User and Application Identification to Network Firewalls"
- this is a Master's Thesis completed in May, 2007 by Rennie deGraaf at the
the University of Calgary.
-
"
Linux Firewalls: Attack Detection and Response with iptables, psad, and fwsnort"
- Chapters 12 and 13 of this book published by No Starch Press in October 2007 discuss
port knocking and Single Packet Authorization.
-
"
Recent Advances in Single Packet Authorization"
- this is the set of slides for a talk given at the HOPE Number Nine conference
in New York City in July 2012.
-
"
Port Knocking and Single Packet Authorization: Practical Deployments"
- this is the set of slides for a talk given at The Last HOPE conference
in New York City in July 2008.
-
"
Zero-day Attack Prevention via Single Packet Authorization"
- slides from the Techno Security conference in Myrtle Beach in June 2007.
-
"
Attack Detection and Response with Linux Firewalls"
- slides from the ShmooCon conference in Washington D.C. in March 2007.
-
"
Service Cloaking and Anonymous Access; Combining Tor with Single Packet Authorization (SPA)"
- slides from the Defcon conference in Las Vegas in August 2006.
8.2 fwknop and fwknopd --help Output
Quite a lot of information can be found in the
fwknop man pages,
but you can also get a sense for some of the major fwknop functionality by looking at the
command line --help output. Here is the fwknop client --help information:
[spaclient]$ fwknop --help
fwknop client version 2.0.3
Single Packet Authorization client
Usage: fwknop -A <port list> [-s|-R|-a] -D <spa_server> [options]
-h, --help Print this usage message and exit.
-A, --access Provide a list of ports/protocols to open
on the server.
-B, --save-packet Save the generated packet data to the
specified file.
-a, --allow-ip Specify IP address to allow within the SPA
packet.
-C, --server-cmd Specify a command that the fwknop server will
execute on behalf of the fwknop client..
-D, --destination Specify the IP address of the fwknop server.
-n, --named-config Specify an named configuration stanza in the
'$HOME/.fwknoprc' file to provide some of all
of the configuration parameters.
-N, --nat-access Gain NAT access to an internal service
protected by the fwknop server.
-p, --server-port Set the destination port for outgoing SPA
packet.
-P, --server-proto Set the protocol (udp, tcp, http, tcpraw,
icmp) for the outgoing SPA packet.
Note: The 'tcpraw' and 'icmp' modes use raw
sockets and thus require root access to use.
-s, --source-ip Tell the fwknopd server to accept whatever
source IP the SPA packet has as the IP that
needs access (not recommended, and the
fwknopd server can ignore such requests).
-S, --source-port Set the source port for outgoing SPA packet.
-Q, --spoof-source Set the source IP for outgoing SPA packet.
-R, --resolve-ip-http Resolve the external network IP by
connecting to a URL such as the default of:
http://www.cipherdyne.org/cgi-bin/myip
This can be overridden with the --resolve-url
option.
--resolve-url Override the default URL used for resolving
the source IP address.
-u, --user-agent Set the HTTP User-Agent for resolving the
external IP via -R, or for sending SPA
packets over HTTP.
-H, --http-proxy Specify an HTTP proxy host through which the
SPA packet will be sent. The port can also be
specified here by following the host/ip with
":".
-U, --spoof-user Set the username within outgoing SPA packet.
-l, --last-cmd Run the fwknop client with the same command
line args as the last time it was executed
(args are read from the ~/.fwknop.run file).
-G, --get-key Load an encryption key/password from a file.
-r, --rand-port Send the SPA packet over a randomly assigned
port (requires a broader pcap filter on the
server side than the default of udp 62201).
-T, --test Build the SPA packet but do not send it over
the network.
-v, --verbose Set verbose mode.
-V, --version Print version number.
-m, --digest-type Specify the message digest algorithm to use.
(md5, sha1, or sha256 (default)).
-f, --fw-timeout Specify SPA server firewall timeout from the
client side.
--gpg-encryption Use GPG encryption (default is Rijndael).
--gpg-recipient-key Specify the recipient GPG key name or ID.
--gpg-signer-key Specify the signer's GPG key name or ID.
--gpg-home-dir Specify the GPG home directory.
--gpg-agent Use GPG agent if available.
--no-save-args Do not save fwknop command line args to the
$HOME/fwknop.run file
--nat-local Access a local service via a forwarded port
on the fwknopd server system.
--nat-port Specify the port to forward to access a
service via NAT.
--nat-rand-port Have the fwknop client assign a random port
for NAT access.
--show-last Show the last fwknop command line arguments.
--time-offset-plus Add time to outgoing SPA packet timestamp.
--time-offset-minus Subtract time from outgoing SPA packet
timestamp.
And finally, here is the fwknopd daemon --help output:
[spaserver]# fwknopd --help
fwknopd server version 2.0.3
Single Packet Authorization server
Usage: fwknopd [options]
-h, --help - Print this usage message and exit.
-a, --access-file - Specify an alternate access.conf file.
-c, --config-file - Specify an alternate configuration file.
-C, --packet-limit - Limit the number of candidate SPA packets to
process and exit when this limit is reached.
-d, --digest-file - Specify an alternate digest.cache file.
-D, --dump-config - Dump the current fwknop configuration values.
-f, --foreground - Run fwknopd in the foreground (do not become
a background daemon).
-i, --interface - Specify interface to listen for incoming SPA
packets.
-K, --kill - Kill the currently running fwknopd.
--gpg-home-dir - Specify the GPG home directory.
-l, --locale - Provide a locale setting other than the system
default.
-O, --override-config - Specify a file with configuration entries that will
overide those in fwknopd.conf
-p, --pid-file - Specify an alternate fwknopd.pid file.
-P, --pcap-filter - Specify a Berkeley packet filter statement to
override the PCAP_FILTER variable in fwknopd.conf.
-R, --restart - Force the currently running fwknopd to restart.
--rotate-digest-cache
- Rotate the digest cache file by renaming it to
'-old', and starting a new one.
-S, --status - Display the status of any running fwknopd process.
-v, --verbose - Set verbose mode.
-V, --version - Print version number.
--fw-list - List all firewall rules that fwknop has created
and then exit.
--fw-list-all - List all firewall rules in the complete policy,
including those that have nothing to do with
fwknop.
--fw-flush - Flush all firewall rules created by fwknop.
Please contact Michael Rash at
<mbr[at]cipherdyne.org> with any questions.
### EOF ###