This section is in preparation. See the Release Notes for a planned roadmap. I included the CIPE documentation as a subsection, but the section layout is not complete, so this may change (Why doesn't linuxdoc provide a part commamd like LaTeX? :-(
Anyway, this section includes descriptions of Linux kernel add-ons that allow you to encrypt the flow of network traffic (at least IP traffic, don't know about IPX and such).
All network encryption packages described in this document work on the same basis: A private network, which should be inaccessible to the outside world, is spread over many (physical) locations (read: company centres and/or roaming users) that are connected via the "evil" internet. This setup is commonly called VPN (virtual private network), because the private network shares its physical structure with the "real" internet.
The task is to route IP packets originating in the private network and destined for other hosts in the private network through the internet while preserving privacy.
This section describes problems and concepts common to all of the VPN packages to be described later on.
The basic networking protocol nowadays is TCP/IP, mostly because it is the protocol the internet uses. But there were other network protocols and ever will be. When the internet began to grow, everyone was tempted to switch to the TCP/IP protocol, regardless of what he was using before. But many applications were not TCP/IP aware and it proved difficult to convert certain subnets to TCP/IP. However, one still wanted to benefit from the TCP/IP protocol and use it for communicating with the internet.
This was one major reason to invent tunnels. Just like TCP/IP packets are packed in Ethernet frames to send them over Ethernet or in PPP frames to send them over PPP links, one now wrappes TCP/IP packets with e.g. IPX frames to tunnel TCP/IP through IPX, or vice versa.
Thus, one was able to use TCP/IP in IPX or ATM---you name it---environments without fundamental changes to routers and so on.
The next picture shows an IP packet contained in an IPX frame:
+------------++-----------+------------------+ | IPX header || IP header | payload | +------------++-----------+------------------+ <----- IP packet --------------> <----- IPX packet containing IP packet ------>
Of cource, no-one prevents you from tunneling IP packets in IP packets. While this does not seem very useful at first sight, there are indeed situations where this concept makes your network admin's life much easier.
One typical example of ordinary IP-in-IP tunneling is the connection of a roaming user to a LAN. The roaming user can plug his laptop into whatever network is available (provided it has a connection to the internet), establish a tunnel to a gateway in the home LAN and route everything through the tunnel. This means that the roaming user will always find the same configuration of networking services available once he gets the tunnel to the home LAN up and running. Another typical example is LAN-LAN coupling.
You can find out more about ordinary tunneling (as opposed to encrypted tunnels) in the NET-3-HOWTO. We will instead concentrate on tunnels that encrypt everything that is put into them.
The main thing to keep in mind when discussing VPN setups is the existence of two logical networks sharing the same physical network hardware. It is important not to confuse those two.
On the one hand, one has the private network, consisting of possibly many sites and hosts, which have no (inherently) secure connection between each other. One has to provide for a secured, transparent connection between them in order to make the pieces a whole.
On the other hand, one has the carrier network (often the internet) that is used to connect the different sites the private network is physically located at.
Typically, the private network uses IP subnets that are reserved for use in closed networks with no connection to the internet. Those subnets include the class A 10.0.0.0/8, the class B 172.[16-31].0.0/16 and the class C 192.168.[0-255].0/8 subnets. Those IP addresses will not be routed by internet routers and thus can only be used for their intended use: private networks. (There are, however, examples where the carrier network uses these addresses and the "private" network uses ordinary, routable addresses, see Section Encrypt the Local Ethernet.)
All VPN packages establish an encrypted point-to-point connection on top of an existing network between two hosts. This connection belongs to the private network, while the existing network serves as the carrier of the encrypted datagrams.
The toughest part in setting up a VPN seems to be the correct routing. But this is only so if one confuses the two distinct networks described above. Indeed, one has to maintain two disjoint routing tables:
One for routing the private traffic within the private network
(usually through the tunnel interfaces) and one for routing the
encrypted datagrams over the carrier network (usually through the
physical interfaces like eth0
, ppp0
).
Be careful, though: Not all physical network interfaces belong to the carrier network! The internal Ethernet of a company may well belong to the private network.
The problem is now that Linux knows nothing of our ambition to create a VPN setup. Also, it does not know about private and carrier networks and their distinction. All Linux can do is, based on its routing table, send an IP packet destined to a particular IP address through an appropriate network interface.
Therefore, the logical distinction of the two networks has to be expressed in terms of routing rules. The best practice proves ever so often to be to consider the carrier network alone first. Once you have the routing table for the carrier network, you start creating the tunnels and add routing rules for the private network, independent of the carrier networks' rules.
The simplest class of a VPN is where the private and the carrier network coincide. As an example, I picked the case where a company wants to encrypt all traffic in the local Ethernet. This can be useful, if the LAN carries sensible data and one wants to make the EM radiation of the ethernet cables unusable to possible spies.
In this setup one hits the limit of most current VPN packages: They only know of point-to-point connections. Only FreeS/WAN has/will eventually have the ability to connect two arbitrary hosts transparently.
So, the only way out is to either select a host as internal gateway, and route all packets through it or to set up point-to-point connections for every single combination of hosts on the network.
While the first method minimizes configuration overhead, it also minimizes performance, because each packet has to be sent from the originating host to the gateway and back to the destination host. So network performance is roughly halved, not even counting the additional de/encryption process on the gateway host.
The second method maximizes both network performance and configuration overhead, because each change in the network topology needs to be reflected in the local (w.r.t. each host) configuration files.
Assume that the company's LAN is a single Ethernet segment and an IP subnet with net address 200.0.0.0 and subnet mask 255.255.255.0, i.e. the class C network 200.0.0.0/24. It has a gateway to the internet (to exchange mail, etc) with IP address 200.0.0.1. Security is enforced by a firewall in front of the gateway, so our task is only to encrypt all traffic in the local part of the ethernet.
ethernet - - - -----+----------+----------+ eth0 | | | ... host C host B host A (gateway) 200.0.0.3 200.0.0.2 200.0.0.1 | eth1 +-----------| firewall |------> INTERNET
As the hosts behind the firewall have transparent access to the internet (within the rules of the firewall), it is necessary that the private network has IP addresses that are routable. The carrier network does not need to have routable IP addresses, so we choose to assign IP address 200.0.0.0/24 to the private network and IP address 10.0.0.0/24 to the carrier network.
In the configuration-friendly model where all traffic is routed via the gateway (200.0.0.1 in our setup), host A's routing table would look like this:
Routes for the carrier network and the connection to the firewall:
Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 firewall 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo [200.0.0.0 0.0.0.0 255.255.255.0 U! 0 0 0 eth0] 0.0.0.0 firewall 0.0.0.0 UG 0 0 0 eth1The routing table entry in parenthesis is a reject route preventing that local traffic is sent unencryptedly via the default route if the point-to-point route for a particular host is not set or there is no host corresponding to a given IP address.
Routes for the private network:
Destination Gateway Genmask Flags Metric Ref Use Iface 200.0.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tunl0 200.0.0.3 0.0.0.0 255.255.255.255 UH 0 0 0 tunl1 200.0.0.4 0.0.0.0 255.255.255.255 UH 0 0 0 tunl2 ... ... ... ... ... ... ... ...Here
tunl
x stands as a placeholder for the interface
name of the particular software used (e.g. cipcb
x
for CIPE or ipsec
x for FreeS/WAN).
The routing table on the other hosts (B, C, etc) would look simply thus:
Destination Gateway Genmask Flags Metric Ref Use Iface 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 10.0.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 200.0.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 tunl0 0.0.0.0 200.0.0.1 0.0.0.0 UG 0 0 0 tunl0Here, 10.0.0.1 is the IP address of host A in the carrier network (this is all any given host needs to know for its routing job, but the first route can safely be changed to be a net route).
In the performance-friendly model, host A's routing table would look the same, but the other hosts would have a routing table like the following:
Destination Gateway Genmask Flags Metric Ref Use Iface 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 200.0.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 tunl0 200.0.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tunl1 200.0.0.3 0.0.0.0 255.255.255.255 UH 0 0 0 tunl2 ... ... ... ... ... ... ... ... 0.0.0.0 200.0.0.1 0.0.0.0 UG 0 0 0 tunl0Note that the point-to-point routes are usually set up automatically by the controlling daemon, so in the last routing table, you only need to set the default and net routes by yourself.
The classical class of VPNs is the situation where two or more physically separated offices are to be connected in a transparent and secure way via the internet.
We first look at the routing required to connect two offices:
OFFICE A if0 +-------> INTERNET <--------+ if0 OFFICE B 1.1.1.1 / \ 2.2.2.2 carrier - - - - - / - - - - - - - - - - \ - - - - - network - / \ private 10.0.1.1 / 10.0.1.1 10.0.2.1 \ 10.0.2.1 +------ gw.a ------------------------------- gw.b ------+ | eth0 tunl0 tunl0 eth0 | v v LAN A LAN B 10.0.1.0/24 10.0.2.0/24
We have two LANs A and B with private IP address spaces 10.0.1.0/24
and 10.0.2.0/24, respectively and we assume that one host in
LAN A (called gw.a) is connected to the internet via the network
interface if0
(this is a generic name, think of it as
ppp0
for a PPP link or eth1
for a DSL or leased
line, etc.) with IP 1.1.1.1. The same is true for a host gw.b in
LAN B, connected to the internet via if0
with IP address
2.2.2.2. The eth0
IP address of the gateways is, as usual,
10.0.1.1 and 10.0.2.1, respectively.
We want to connect these two LANs with a tunnel, so that traffic can flow between them, although they use IP addresses that are not allowed to travel the internet.
The advantage of using private IP addresses is that these need not be reserved (and possibly paid for) and that they make it hard for external intruders to attack hosts, simply due to the fact that IP packets destined for these IP addresses are immediately dropped by every internet router.
We identify the internet, together with the if0
interfaces of
each gateway, to be the carrier network, while the two LANs
and the tunnel between the two gateways constitute the private
network.
If we first consider the routing needed for the carrier network, we simply get the following tables:
gw.a's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 2.2.2.2 0.0.0.0 255.255.255.255 UH 0 0 0 if0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo gw.b's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 1.1.1.1 0.0.0.0 255.255.255.255 UH 0 0 0 if0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
On top of this, we construct the routing tables for the private network:
gw.a's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.2.1 0.0.0.0 255.255.255.255 UH 0 0 0 tunl0 10.0.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.0.2.0 10.0.2.1 255.255.255.0 UG 0 0 0 tunl0 gw.b's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.1.1 0.0.0.0 255.255.255.255 UH 0 0 0 tunl0 10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.0.1.0 10.0.1.1 255.255.255.0 UG 0 0 0 tunl0
This class of VPNs is a special case of Example Connect Two Private Ethernets, and the routing involved is in fact easier when considering the tables only.
What makes this example special and interesting from a configuration point of view, is the fact that the tunnels are dynamically created and destroyed possibly quite often (as opposed to created at boot time and destroyed at system shutdown) and that the IP address of the mobile host may change frequently, depending on what LAN or ISP the laptop is currently plugged into.
Often one part of the carrier network consists of a dynamically established PPP link, which adds even more configuration overhead and variables to consider.
This setup depends heavily on the VPN software used, so further discussion of this is postponed to the sections on specific VPN software below.
CIPE by Olaf Titz (
Olaf.Titz@inka.de) ships with the International Kernel Patch
(see Section
Obtaining and Installing the International Kernel Patch). The userspace tools needed are in the
net/cipe
subdirectoy of the patched kernel source. The
package is also available from
http: //sites.inka.de/~bigred/devel/cipe.html. I only document version
1.3.0 (Apr 1999) here, although there is a newer version out
(1.4.2). It will not inter-operate with earlier versions due to a bug
in the key handling or so in those earlier versions, but it finally
supports Windows! See
http://CIPE-Win32.sourceforge.net/. There is also a mailing
list dedicated to CIPE. You can subscribe to it by sending a message
with the single line subscribe cipe-l in its body to
majordomo@inka.de.
CIPE is a very simple package in that it requires you to make some decisions at compile-time, which leads to specialized and simpler code, which in turn is supposedly less bug-loaden than a complicated protocol like IPSec. CIPE is only compatible to itself, but often enough that is no limitation.
These disadvantages turn out to be big wins when it comes to maintaining the package, as configuration is much easier done than e.g. the disk encryption in Section Disk Encryption.
CIPE intercepts the network stack just above the network layer by
adding a new network interface (e.g. cipcb0
). (IP-)Packets
routed through it will be encrypted and put through a tunnel to a peer
gateway, where they will be decrypted and delivered.
It employs symmetric ciphers (Blowfish and IDEA) and a shared secret (key) with dynamic re-keying, i.e. the shared secret is only used for authentication and exchanging the first dynamically generated, actual encryption key. Data is encrypted using these dynamic keys.
The package consists of a kernel module (cipcb
for Blowfish
and cipci
for IDEA) and a user space deamon
(ciped-cb
resp. ciped-ci
).
The only thing you need to do in your kernel is to enable loadable
module support (CONFIG_MODULES
). Of course you need to have
some kind of (carrier) network running, but I assume that this is in a
working state. See the appropriate HOWTOs for how to configure that.
CIPE currently only works as modules and I do not see anything
indicating a change to that. Also, the building of the CIPE modules is
currently not included in the kernel build process, not even with the
international kernel, although the entries in make config
suggest otherwise. At least on my 2.2.17.6 CIPE modules were not build
resp. installed by make modules modules_install
.
So you have to do that yourself: Change into the CIPE directory. It is
the net/cipe
subfolder of the kernel source tree if you use
CIPE from the international kernel patch or cipe-1.3.0
if you
extracted it from the tar archive on
inka.de.
If you have the source of the kernel under /usr/src/linux
,
then you can just enter ./configure
to let CIPE figure out
the details of your kernel. Otherwise you have to tell the
configuration script where to find the kernel source with the
--with-linux
option, e.g.
root# ./configure --with-linux=/usr/src/linux-2.2.17if your kernel source resides in
/usr/src/linux-2.2.17
. If
you want to use the IDEA cipher instead of the default Blowfish, then
call ./configure
with the option
--enable-idea
. These are the compile-time options mentioned
in the
Concepts and Features
Section. You can compile different versions of the CIPE modules and
userspace tools one after the other to allow the use of both ciphers.
After the configure script has successfully finished, you will find a
new folder named something like 2.2.17-i386-cb
in the CIPE
directory. This helps you with the compilation of multiple versions of
the CIPE package (e.g. for using both ciphers). The first part of the
folder name consists of the kernel version (like uname -r
)
for which the modules will be compiled, followed by the machine type
(like uname -m
) and by the CIPE features: The first character
stands for the protocol version (only c=3 allowed) and the cipher used
(b=Blowfish and i=IDEA).
To compile and install the modules and userspace tools, enter the newly created directory and type
root# make && make installThat was it! Have a look at the file
cipe.info
which
accompanies the CIPE sources if you want to compile CIPE for special
cases (e.g. if you do not have the kernel source, but only the
includes installed).
First, you have to do a minimal configuration: Copy the
samples
directory to /etc/cipe
and edit the file
/etc/cipe/options
to include only the parameter
key
. For a first test you can safely go with the value
provided by the options
file of the samples
directory. Later, you have to change this key, of course.
It is important that the key is the same on both machines you want to connect with a CIPE tunnel. For first tests, I would recommend that you set up a CIPE connection between hosts on the local Ethernet segment, if possible. Things like CIPE over PPP are covered in more depth later on.
To be specific, assume that we are living on an ethernet that consists of two boxes and uses IP addresses from the private range 10.0.0.0/24. We want to use Blowfish encryption. The two boxes, called A and B, have IP addresses 10.0.0.1 and 10.0.0.2 respectively.
The first step after compiling and installing CIPE on both machines is to load the modules on both hosts:
root@A# modprobe cipcb root@B# modprobe cipcbNext, you start the CIPE-daemon on each machine:
root@A# ciped-cb me=10.0.0.1:6789 peer=10.0.0.2:6543 ipaddr=10.0.1.1 ptpaddr=10.0.1.2 root@B# ciped-cb peer=10.0.0.1:6789 me=10.0.0.2:6543 ptpaddr=10.0.1.1 ipaddr=10.0.1.2As you can see, the configuration parameters have to be swapped, so to speak, as me's peer is peer's me. Also, we need to use additional IP addresses for the CIPE interface (called
cibcb
here), see
next section.
If everything worked well, you can try to ping the peer to see if the tunnel has been successfully established:
user@A$ ping 10.0.1.2 user@B$ ping 10.0.1.1A common mistake is to have a firewalling policy of DENY or REJECT and no ACCEPT rule corresponding to the UDP port numbers used.
ping
will report "sendto: write: operation not
permitted" if this is the case. See the ipchains-HOWTO for how to add
such rules. If you are using masquerading together with CIPE, you may
want to look at the CIPE+Masquerading-miniHOWTO, too.
If you were able to ping the other host, you can now try to telnet or ssh the other host. If all works well, you have successfully completed the first tests.
In this subsection you will learn of the various parameters that influence CIPE's behaviour. You have seen the most important ones in the last section, here we discuss their meaning in detail:
For security reasons, the key
parameter
must be set via an options file, owned by root and unreadable for
anyone else. It is followed by the 128-bit shared secret, i.e. the key
that is used for authentication and generation of session keys. To
generate a truly random key and add it directly to your options file,
so no-one can sneak it, issue the following command:
root# echo key $(head -c 16 /dev/random | md5sum) >> /etc/cipe/optionsIt is your responsibility that you transfer the key from one machine to the other in a secure fashion. Do not use ftp or other unencrypted protocols to send the key! The recommended way is to learn the key by heart and type it into the other box by hand or to send it via PGP/GnuPG-encrypted E-Mail. But also transferring it via removable media or through a ssh session is acceptable. Make sure you are absolutely certain that the other end of the ssh connection is indeed the box you think it is.
nokey
leads to
simple (and unauthenticated) IP-in-IP tunnelling, useful only for
testing. key
and nokey
are mutually exclusive
options.
The IP address of my host, followed by the
colon-separated port number the CIPE daemon should listen to
(me
) and the IP address of the other end of the CIPE tunnel,
followed by the colon-separated port number to which we wish to
connect to (peer
). These are the IP addresses that hosts of
the carrier network "see". Make sure that all firewalls
between the two hosts let pass UDP packets destined for those
ports. peer
can be 0.0.0.0:0, in which case the IP address is
taken as the one of the host connecting to us, provided it
successfully authenticates itself. me
needs not be
specified. In this case CIPE will pick appropriate values and report
them to the ip-up
script.
The IP address of the cipcb
(resp. cipci
) interface on my host (ipaddr
) and the
IP address of the cipcb
(resp. cipci
) interface of
the peer (ptpaddr
). The CIPE daemon uses this information to
automatically set a point-to-point route between the two interfaces
after a connection has been established (just like the PPP daemon does
after successful dial-in). These are the IP addresses that hosts in
the private network "see". ptpaddr
can be 0.0.0.0,
in which case the peer's IP address is determined when the other end
tries to connect and successfully authenticates itself.
These optional parameters specify the
cipcb/i
device MTU (maximum transfer unit), the UDP packets'
TTL (time to live) value and the cipcb/i
device metric. See
the appropriate (networking) HOWTOs if you don't know what I am
talking about.
These optional
parameters specify the key exchange timeout (10), the dynamic key
lifetime (600), the key exchange timestamp window (0), the time
between two successive keep-alive pings (0), the timeout for those
pings (0) and the maximum number of network errors between two key
exchanges (8). All these parameters take their values to be specified
in seconds and a value of 0 (zero) means "disable this feature/no
timeout". Default values are listed in parenthesis. maxerr
is
different, though: The value is just a number (no seconds) and a value
of 0 (zero) means "accept no errors", while "accept any number of
errors" corresponds to a value of -1 (minus one). You normally want to
go with the default values, but sometimes adjusting the
maxerr
parameter is needed if your connection is not so
reliable (e.g. PPP).
These optional parameters specify the
name of the ip-ip
and ip-down
scripts to run
resp. (default: /etc/cipe/ip-up
resp. /etc/cipe/ip-down
) and an optional argument to pass to
the ip-up
script. Useful if you intend to run more than one
ciped
.
There is also the socks
parameter, which allows you to
connect to a SOCKS5 server with CIPE. If you need it, you'll want to
read the cipe.info
file that comes with CIPE.
Two other parameters, device
and debug
, are only
useful in testing, since CIPE 1.3.0 can automatically grab free
cipcb/i
interfaces as needed, and debug
is useful
for just that: debugging.
All these options can be specified in either of three ways:
/etc/cipe/options
,-o file
on the command
line,parameter=value
,-o
file
options override /etc/cipe/options
options).
The examples are roughly ordered by complexity.
I will just give you the necessary links to find other documentation on the following packages:
FreeS/WAN is a Linux based implementation of the IETF IPSec standard. If you want to know all there is to know about IPSec, see the RFC's concerned with it, esp. the famous RFC's 2401: Security Architecture for the Internet Protocol thru 2412: The OAKLEY Key Determination Protocol. Note, however, that these documents add up to 20,000 lines of pure text or 800K.
This package is very complex indeed, but as it is based on an IETF standard, it inter-operates with many other (commercial as well as open souce) VPN products, including PGPnet and the OpenBSD IPSec implementation. This makes it the single obvious choice for admins that need extensive cross-platform capabilities.
There is a very active mailing list you can subscribe to, if you send a message with the single line subscribe linux-ipsec in the body of the message to majordomo@clinet.fi.
Another, more lightweight IPSec implementation for Linux running completely in user space is pipsecd, available from http://perso.enst.fr/~beyssac/pipsec/.