The SigKnock Administrator's HowTo

© 2004 by Thomas Wana <thomas@wana.at>

Index:

Installing the SigKnock-module and -libraries

Installation from Source

You will need the configured sources of the currently running kernel as well as the sources of the iptables-tool you currently use.

SigKnock comes with a configure-script which you must use to configure the source tree. There are several variables that are important as you can see with ./configure --help:

   ...
  --prefix=PREFIX                  install architecture-independent files in PREFIX [/usr/local]
   ...
  --with-debug                     When supplied, compiles the kernel module with debug messages
  --with-kernel-sources=DIR        Location of the kernel sources to build against (default is /lib/modules/`uname -r`/build)
  --with-iptables-sources=DIR      Location of the iptables sources to build against (default is /usr/src/iptables-1.2.6a)
  --with-iptables-version=VERSION  Version of the iptables sources (default is 1.2.6a)
  --with-sigknock-homedir=DIR      Location of the module's homedir (needed for temporary files and gpg keyrings; default is /etc/sigknock)
  --with-modversions               Compile the module with modversions support
	
Example:
   ./configure --prefix=/usr --with-debug --with-kernel-sources=/usr/src/linux-2.4.27 --with-iptables-sources=/usr/src/iptables-1.2.9 --with-iptables-version=1.2.9
   

After that, a simple

   make
   
builds the whole module, and
   make install
   
installs the parts into the right locations. The iptables-shared-libraries go to /lib/iptables and the client goes to $PREFIX/bin.

Note: The kernel module will not be installed by 'make install'. You have to copy the file (ipt_sigknock.o for 2.4 kernels and ipt_sigknock.ko for 2.6 kernels) yourself to the location you need it (most probably somewhere in /lib/modules etc, but the configure script can't guess this for you)

Installation of a binary package

If you got SigKnock as binary package, you have to take care that it fits exactly your kernel version and iptables version. Depending on the distribution you are using, a installation can be as easy as:

   dpkg -i sigknock_1.0-i386.deb
   
or
   rpm -i sigknock_1.0-i386.rpm
   
.

Testing the module and libraries

Now try the following command, you should see an output like this:

   # iptables -m sigknock --help
   iptables v1.2.9
   ...
   Signature knocking v1.2.9 options:
   --uid User-ID
                           User-ID of the signature to check against. You can use this several times in a single rule.
   --timeout Timeout[smhd]
                           Timeout (in seconds, minutes, hours or days) after the port closes again
   --close-after-syn
                           Close the match after the first TCP-SYN came through
   timeout and close-after-syn are exclusive.
   Note: you *must* have a SIGKNOCK-KEYPORT target in your fw-rules; see
   the sigknock docs for details.
   
This confirms that the iptables-shared-libraries have been installed correctly. Now try to load the module, if this works without any error then you are ready for signature knocking!
   insmod ipt_sigknock.o
   


Managing SigKnock's GnuPG-keys

As I hope you already know, SigKnock operates with GnuPG-keys :) In order for the server to verify a signature, the public key of the signer has to be stored somewhere.

Per default, the sigknock module searches for the keys under /etc/sigknock, but you can change that via ./configure. Let's assume you chose the default. The directory has already been created for you during the installation.

Listing keys

In order to see who is theoretically allowed to do a signature knock, do:

   gpg --homedir /etc/sigknock --list-keys
   

Adding keys

If you want e.g. John Doe to be authenticated via SigKnock, you have to get his public key and store it in /etc/sigknock. Look at the following example:

   # wget http://www.doe.com/john.doe.pubkey.asc

   # gpg --homedir /etc/sigknock --import john.doe.pubkey.asc
   gpg: key 103F85BC: public key "John Doe <john@doe.com>" imported
   gpg: Total number processed: 1
   gpg:               imported: 1

   # gpg --homedir /etc/sigknock --list-keys
   /etc/sigknock/pubring.gpg
   -------------------------
   pub  1024D/103F85BC 2004-08-24 John Doe <john@doe.com>
   sub  1024g/0BD3A059 2004-08-24
   

Modifying keys, deleting keys, etc

You can operate on the keyrings in the sigknock-key-directory just like on your own keyring. Just use gpg with the --homedir flag. Look at the GnuPG-manual to find out more.


SigKnock mechanisms

The basic idea behind SigKnock is the authentication of users using a challenge response protocol, combined with digital signatures. A session looks as follows:

  1. The client sends a challenge request to the server. This is done over UDP. The server "listens" on a certain port, the so-called "keyport", for challenge requests. (the "listen" is in quotes because it doesn't really listen in terms of listen(2). It only sees packets entering the IP-stack and analyzes those who go to the keyport).
  2. The server generates a challenge and sends it back to the client.
  3. The client signs the challenge using its private key and sends the detached signature back to the server.
  4. Now the server knows, what challenge it sent to the client, and can check with the signature it received if the signature is valid and, more importantly, who signed the challenge. With this information, we can be cryptographically secure that the client is who he claims to be.
  5. All iptables-rules, that contain the key-User-ID, now "match". This is netfilter-terminology for a rule that now becomes active. With this, you can do whatever you can imagine. After all, it's just a flag that is set and reset.
Note: There are really two more steps prior to step 1 that have been omitted here for clarity. SigKnock uses the ideas of syncookies to protect itself from spoofed source addresses, and their negotiation is handled there.

The iptables interface

One of the strengths of SigKnock is its integration into the Linux firewall administration utility, iptables. With that, you can easily create powerful rules that now can make use of SigKnock's authentication facilities. You can use all the modules you used before (think of connection tracking, think of NAT, think of traffic shaping, ...), but now on a secure per-user-level.

The keyport

SigKnock really consists of two "modules": the SIGKNOCK-KEYPORT-target and the sigknock-match (if you don't know what's the difference between "target" and "match" in iptables-terminology, go and look that up first).

The keyport is there to handle the challenge response protocol between the client and the server. In early implementations SigKnock used a fixed port number for that, but that proved to be impractical; with this dynamic target you have full power over your SigKnock keyport, e.g. only allow signature knocks from certain IP-addresses etc etc.

To define the keyport for UDP, port 4000, you would use:

   iptables -A INPUT -p udp --dport 4000 -j SIGKNOCK-KEYPORT
   

The sigknock-match

More interesting than the keyport-target is the match-function. Let's look at its parameters in more detail:

--uid User-ID

The full User-ID of the public key to match against. The SigKnock-module reads the gpg-output and allows the match when the signature from this User-ID was valid. You can supply more than one of these in a single rule (up to 10).

--close-after-syn

This flag closes the match after the first TCP syn-packet went through. This is very useful if you want to "shut the door" right behind you after you entered the service.

--timeout

This is an alternative to --close-after-syn, they can't be used together. This flag determines how long the match will be valid after a successful signature knock. You can supply here any number, followed by a time determinator like 's' for seconds, 'h' for hours, 'm' for minutes or 'd' for days. e.g. --timeout 2h = the match closes two hours after a successful sigknock.


Examples

I think the best way to demonstrate the features of SigKnock is by showing some examples.

Denying all traffic, only allow traffic from a certain User-ID

This is not a very useful example, but it gives you a basic idea. The match stays open for 1 hour:

   // default-policy DROP all traffic
   iptables -P INPUT DROP
   iptables -P OUTPUT DROP
  
   // John Doe may communicate with the server
   iptables -A INPUT -m sigknock --uid "John Doe <john@doe.com>" --timeout 1h -j ACCEPT
   iptables -A OUTPUT -m sigknock --uid "John Doe <john@doe.com>" --timeout 1h -j ACCEPT
   

Protecting the SSH port, also using connection state match

Suppose you want to protect your SSH-port, so only "John Doe" can connect to port 22. The port shall be closed again after John Doe connects to it. The rest of the server's firewall rules shall stay unaffected (so no playing with the rule policies etc).

The idea is to only allow established connections per default, so noone can get in in the first place. Then we add a rule where new connections are only allowed after a successful signature knock. This is the only way to establish a connection.

   // we accept already established connections to the ssh-port
   iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED -j ACCEPT
   iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

   // now, accept NEW connections only after a successful signature knock for John Doe
   iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m sigknock --uid "John Doe <john@doe.com>" --close-after-syn -j ACCEPT

   // and drop the rest (e.g. unauthorized connection attempts etc)
   iptables -A INPUT -p tcp --dport 22 -j DROP
   

Debugging common problems

What can you do when something "doesn't work"?

Use 'dmesg'

The kernel module prints out messages to the kernel log when something noticeable happened, e.g. successful or unsuccessful SigKnock attempts. When a SigKnock is unsuccessful, it additionally prints out the GnuPG output from that operation, so you can see what was the reason for the SigKnock to fail.

Common things that can happen here are e.g. insufficiently restrictive permissions on /etc/sigknock (GnuPG will refuse to use the keyrings there if they aren't properly secured), forgot a space character in the --uid switch, etc. 'dmesg' is the administrator's tool to debug SigKnock problems.

Compile the module with --with-debug enabled

If you enable --with-debug at the ./configure command line, the client and the kernel module spit out a lot of information about what's going on. You can again access this information easily using 'dmesg'.


The SigKnock Administrator's HowTo - © 2004 Thomas Wana <thomas@wana.at>