© 2004 by Thomas Wana <thomas@wana.at>
Index: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 supportExample:
./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
makebuilds the whole module, and
make installinstalls 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)
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.debor
rpm -i sigknock_1.0-i386.rpm.
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
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.
In order to see who is theoretically allowed to do a signature knock, do:
gpg --homedir /etc/sigknock --list-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
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.
The basic idea behind SigKnock is the authentication of users using a challenge response protocol, combined with digital signatures. A session looks as follows:
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.
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
More interesting than the keyport-target is the match-function. Let's look at its parameters in more detail:
I think the best way to demonstrate the features of SigKnock is by showing some examples.
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
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
What can you do when something "doesn't work"?
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.
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'.