[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

1. Introduction

1.1 Network layers and encryption  Where encryption takes place.
1.2 IP routing and Virtual Private Networks  About IP routing and VPNs.
1.3 How CIPE works  The encapsulation method employed here.
1.4 CIPEs software components  Which pieces of software CIPE consists of.
1.5 Notes on internals  A look under the hood of CIPE.

1.1 Network layers and encryption

There are several different places where encryption can be built into an existing network infrastructure, corresponding to the different protocol layers:

  1. On the network level: Packets travelling between hosts on the network are encrypted. The encryption engine is placed near the driver which sends and receives packets. An implementation is found in CIPE.
  2. On the socket level: A logical connection between programs running on different hosts (TCP connection; transport or session layer in OSI) is encrypted. The encryption engine intercepts or proxies connections. SSH and SSL work this way.
  3. On the application level: Applications contain their own encryption engine and encrypt data themselves. The best known example is PGP for encrypting mail.

Low-level encryption as implemented with CIPE has the advantage that it can be made to work transparently, without any change to application software. In the case of encrypting IP packets, it can be built into IP routers which usually act as "black boxes" that only route traffic between hosts, the hosts themselves don't see at all how the routing works. So an encrypting router looks exactly like a non-encrypting one, without any difference seen by other hosts and applications. It can thus be used in places where software changes at higher levels are not feasible.

Low-level encryption has the disadvantage that it does not guard against intruders on a higher level, e.g. Trojaned applications, bug exploits in system software or rogue administrators "sniffing" on terminal devices.

1.2 IP routing and Virtual Private Networks

A virtual private network (VPN for short) is a network (1) belonging to one organization, using its own address range, but overlayed on existing network infrastructure. IP-in-IP tunneling makes it possible to build IP-based VPNs on top of other IP-based carrier networks, such as the Internet. Encrypted tunneling guards against passive (sniffing) and active (faked message injection) attacks on the carrier network. The carrier network sees only encrypted data.

Depending on the choice of protocol, all information the original packets carry can be encrypted. This includes not only the actual (payload) data but also the TCP/IP headers, leaving no trace as to which addresses and services are actually used. Traffic analysis attacks, which attempt to gain useful information out of sniffing by "who contacts whom", are thus made unfeasible. An even more sophisticated technique to thwart traffic analysis employs the injection of dummy packets into the network which carry no useful information at all but are (at the carrier level) indistinguishable from real data packets.

IP routing in a VPN situation consists of the routing of the carrier network, which in most situations is just a standard Internet setup, and routing of the overlayed VPN. This is easiest when the address ranges of carrier and VPN do not overlap in any way. It is common for VPNs to use the and address ranges, which are not part of the Internet and thus do never conflict with actual Internet routing: any address in this range must be local to the organization using it. See section 5.2 Example 1, for a typical example.

The IPSEC standards define a set of protocols which can be used (among other things) to build encrypted VPNs. However, IPSEC is a rather heavyweight and complicated protocol set with a lot of options, implementations of the full protocol set are still rarely used and some issues (such as key management) are still not fully resolved. CIPE uses a simpler approach, in which many things which can be parameterized (such as the choice of the actual encryption algorithm used) are an install-time fixed choice. This limits flexibility but allows for a simple (and therefore efficient, easy to debug...) implementation.

1.3 How CIPE works

CIPE encapsulates encrypted IP datagrams in UDP datagrams and sends them via the normal UDP mechanism. This is different from standard IPIP encapsulation. UDP was chosen because this way many different endpoints can easily be distinguished by port numbers; because an IP protocol number would warrant a formal registration; and because handling of UDP datagrams is easier than using a separate IP protocol number, especially in firewalled setups. Specifically, UDP can be handled by user-level applications such as a SOCKS5 relayer. See section 3.4 Working with SOCKS.

A CIPE link always connects exactly two endpoints. In many ways, the link works like a PPP dial-up link. At present, each link has its own secret 128-bit key which has to be known by both ends (and nobody else). This link key (called static key in the protocol description) is used to negotiate a frequently changed dynamic key, which encrypts the actual data.

Since CIPE 1.5 it is also possible to negotiate the keys via a public key mechanism, similar to the SSH package. This removes the need for shared secret keys. See section 4. The PKCIPE tool.

1.4 CIPEs software components

The CIPE package consists of a kernel module and a driver program. The kernel module does the IP packet handling: sending and receiving packets, encapsulation including encryption. It implements a network device which is mostly handled like any other network device. Configuration and the whole key exchange process is done by the user level program ciped. See section 2.6.1 Program Names.

ciped looks and behaves rather similar to pppd. In particular, opening and closing a CIPE device is tied to starting and ending a ciped process (one per device), the specification of options to the daemon mimics pppd's setup and ciped invokes scripts on opening and closing a device.

The pkcipe program is a separate add-on to the ciped driver which manages keys and other parameters.

1.5 Notes on internals

(This section is only relevant to readers who want to understand the source, not to the regular user.)

The module consists of an output driver, an input driver, the encapsulation routines and some stuff to keep it all together. The output driver is largely an adapted version of new_tunnel from the Linux distribution. (2) In Linux 2.0 its actual packet sending is done via the kernel IP forwarding engine. This implies that (a) forwarding must be enabled in the kernel and (b) the encrypted packets, being UDP packets with the source/dest addresses given as "me" and "peer", are checked against the forwarding (as well as the output) firewall. (If it doesn't work for you, first make sure that your firewall rules let the packets pass!)

The input driver is an adaptation from the kernel UDP receiver. To activate it, ciped has to set a socket into a special mode with an ioctl call. This has to be a connected UDP socket. The ioctl_attach(2cipe) call replaces the socket's sendto(2) and recvfrom(2) operations with special versions that do decryption of traffic internally and only pass key exchange blocks to the user layer. The whole work of decrypting and rerouting incoming traffic is done inside a blocking recvfrom(2). This means that unlike normal IP forwarding, it is called from user mode and the needed CPU time is charged to the ciped process, although the data never passes into user mode. sendto(2) encodes the block as a key exchange block and sends it to the peer. The socket should not use read(2), write(2), select(2) or nonblocking mode (yet).

Before attaching the socket, the operational parameters of the device have to be set using a ioctl_setpar(2cipe) call. The key exchange process supplies keys to the kernel via ioctl_setkey(2cipe).

The netdevice can only be opened (configured "UP") if it has a controlling socket. When the controlling socket is closed, the netdevice gets closed. Conversely, closing the netdevice (with ifconfig(8)) closes the socket too. Closing deletes all information that is set by ciped on the device.

Devices can be dynamically allocated and deallocated using a ioctl_alloc(2cipe) call. The first device always remains allocated as a hook for the ioctl calls.

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Olaf Titz on August, 4 2004 using texi2html