seppl 0.4

Copyright 2003,2004 Lennart Poettering <mzfrccy (at) 0pointer (dot) de>


This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


Thu Jan 22 2004:

Version 0.4 released; changes include: port to Linux 2.6, no other changes. Version 0.4 is no longer compatible with kernel 2.4. Use version 0.3 for kernel 2.4, it is functionally equivalent.

Sat Dec 6 2003:

Version 0.3 released; changes include: IV are no longer simply increased from packet to packet, a C implementation of seppl-gen-key was added, the iptables release is automatically detected now, support for kernels with versioned symbols.

Wed Nov 5 2003:

Version 0.2 released; changes include: ported to kernel 2.4.22, autoconf/automake based build system, init script


seppl is both a protocol definition and a software implementation of a new encryption layer for IPv4. It makes use of symmetric cryptography for encrypting the whole traffic on a network. Its implementation is designed around Linux netfilter/iptables.

seppl introduces two new netfilter targets: CRYPT and DECRYPT. A firewall rule may thus be used for encrypting/decrypting the incoming and outgoing network traffic. This makes seppl extraordinarily easy to use, since no daemons need to run for secure communication.

seppl uses the encryption engine of the Linux Cryptographic API which is available in kernel 2.4.22 and newer.

seppl is primarily intended for encrypting wireless LANs (as secure replacement of the broken WEP encryption) and local ethernet networks but may be used for large scale VPN solutions as well.

The protocol seppl relies on is not compatible with any other software. The protocol is open and well defined but there is no implementation other than this reference software.

Why SEPPL, there are already IPSEC, CIPE,...?

CIPE may be used for point-to-point connections only. It has tunnel structure and thus introduces new IP addresses. This is not always desirable. It requires a user space daemon.

IPSEC/FreeSwan is extremely complicated to use. Due to its strange routing scheme it is nearly impossible to use together with routing daemons. IPSEC is heavyweight.

seppl is truely peer-to-peer. It encrypts seamlessly all outgoing traffic and it thus compatible with routing daemons. It is extremely easy to use as well, as it makes no change to the normal routing behaviour. seppl is extremely lightweight.


seppl 0.4 is quite stable and feature complete


The Implementation

The implementation consists of three Linux kernel modules: seppl.o, ipt_CRYPT.o and ipt_DECRYPT.o. The former is the in-kernel key manager, the latter are the two new netfilter targets. Both depend on seppl.o.

seppl.o must be inserted into kernel in first place. The key manager may be accessed with the file /proc/net/seppl_keyring. It contains binary key data, and is initially empty. You may add a new key by writing it to that file.

The two Python scripts seppl-ls and seppl-gen-key me be used for key management. seppl-ls may be used for converting seppl keys between the binary format used by /proc/net/seppl_keyring and a human readable XML based format. Simply call seppl-ls for a list of all currently active keys. seppl-gen-key generates a new key from /dev/urandom. By default it will use the XML format. The parameter -x forces binary mode. You may generate and activate two keys "linus" and "alan" by issuing the following command lines:

seppl-gen-key -n linus -x > /proc/net/seppl_keyring
seppl-gen-key -n alan -x > /proc/net/seppl_keyring

seppl-ls without argument lists the new keys saved in the kernel keyring. You may remove all (currently unused) keys by issuing:

echo clear > /proc/net/seppl_keyring

Since seppl is based on symmetric cryptography using shared keys you have to copy newly generated keys to every host you want to connect to your seppl infrastructure. (preferably via SSH or any other secure file transfer) You get a binary copy of your current keyring by issuing:

cat /proc/net/seppl_keyring >

Now copy that file to all other hosts and issue the following command there:

cat > /proc/net/seppl_keyring

That is simple, isn't it?

After doing so you may configure your firewall settings on each host:

iptables -t mangle -A POSTROUTING -o eth0 -j CRYPT --key linus
iptables -t mangle -A PREROUTING -i eth0 -j DECRYPT

This will encrypt all outgoing traffic on eth0 with the key "linus". All incoming traffic is decrypted with either "linus" or "alan", depending on the key name specified in the specific network packet. Unencrypted incoming packets are silently dropped. Use

iptables -t mangle -A PREROUTING -p 177 -i eth0 -j DECRYPT

for allowing both crypted and unencrypted incoming traffic.

That's it. You're done. All your traffic on the local subnet is now crypted with seppl.

The default cipher is AES-128. If you don't specify the name of the used key it defaults to "def".

An SysV init script /etc/init.d/seppl is provided. It will load seppl's kernel modules and write all keys from the directory /etc/seppl to the kernel keyring. It will not add any firewall rules, however.

Performance issues

The network packets are increased in size when they are crypted, since two new headers and the IV are added. (36 bytes in average) This conflicts on some way with the MTU management of the Linux kernel and results in having all large packets (that is: package size near MTU) fragmented in one large and another very small package. This will hurt network performance. A work-around of this limitation is using the TCPMSS target of netfilter to adjust the MSS value in the TCP header to smaller values. This will increase TCP perfomance, since TCP packets of the size of the MTU are no longer generated. Thus no fragmentation is needed. However, TCPMSS is TCP specific, it won't help on UDP or other IP protocols.

Add the following line before encryption to your firewall setup:

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o eth0 -j TCPMSS --set-mss $((1500-40-8-16-6-15))

The Protocol

For encryption every single unencrypted packet is taken and converted to a crypted one. Not a single further packet is ever sent.

   Original                     SEPPL counterpart
+------------+              +-----------------------+  \
| IP-Header  |              | Modified IP-Header    |   |
+------------+      <==>    +-----------------------+   |
| Payload    |              | SEPPL-Header          |   > Unencrypted
+------------+              +-----------------------+   |
                            | Initialization Vector |   |
                            +-----------------------+  /
                            | SEPPL-Header          |  \
                            +-----------------------+   | Crypted
                            | Payload               |   | 
                            +-----------------------+  /

The original IP header is kept as far as possible. Only three fields are replaced with new values. The protocol number is set to 177, the fragment offset is set to 0 and the total length is corrected to the new length. All other fields are kept as is, including IP options.

The unencrypted seppl header consists of a one-byte cipher number and a key name. Currently only 0 and 1 are defined as cipher numbers for AES with 128bit key, resp. AES with 192bit key. The key name (7 bytes) may be used to select a specific key in a larger keyring.

The IV is used for CBC coding of the cipher used. It differs from packet to packet, but is not randomly generated. Due to perfomance reasons, only the initial IV on system startup is randomized, all following IVs are generated by incrementing the previous ones.

The crypted seppl header consists of three saved fields of the original IP header (protocol number, fragment offset, total length) and a byte which is always 0 for detecting unmatching keys.

The payload is the original IP-playload, from the TCP/UDP/other header to the end.


seppl interferes with netfilter's connection tracking in some way. Thus you will not be able to use NAT in conjunction with seppl. If you use connection tracking in some other way together with seppl your mileage may vary.

seppl is tested with Linux 2.6.1. Use version 0.3 for Linux 2.4.


This is my first Linux kernel project, I am new to kernel hacking, so please be gracious!

IANAC ("I Am Not A Cryptoanalist"), I cannot guarantee that I used the cryptographic routines correctly. I think I did, but maybe I am plain stupid.


seppl was developed and tested on Debian GNU/Linux "testing" from Nov 2003, it should work on most other Linux distributions and Unix versions since it uses GNU Autoconf and GNU libtool for source code configuration and shared library management.

seppl requires Linux 2.6.{0,1} (configured sources installed) and iptables 1.2.8 or newer.

The complete userspace tool set requires Python 2.1 or newer. A stripped down set in C is available as well.


As this package is made with the GNU autotools you should run ./configure inside the distribution directory for configuring the source tree. After that you should run make for compilation and make install (as root) for installation of seppl.


Donald J Bindner for many patches


The newest release is always available from

The current release is 0.4

Get seppl's development sources from the Subversion repository.

Lennart Poettering <mzfrccy (at) 0pointer (dot) de>, January 2004
$Id: index.html,v 1.1 2004/03/09 01:53:58 lennart Exp $