2. Operation.

Here is a simplified view of my testbed:


    +---------+						   +---------+
    | tortise |						   |  ping3  |
    +----*----+						   +----*----+
   eth0 * 192.168.4.104      	        		   eth0 * 192.168.3.104
	*							*
    *************************               *************************
			*			*
                   eth1 * 192.168.4.110    eth1 * 192.168.3.100
                   +----*-----+	           +----*-----+
                   | gonzales |            | magellan |
                   +----*-----+            +----*-----+
		   eth0 * 192.168.2.110    eth0 * 192.168.2.100
			*			*	
		    *********************************


Only magellan and gonzales need to run IPSEC. 

All netmasks are 255.255.255.0.

Tortise has a route to 192.168.3.x via gonzales, and ping3 has a route to
192.168.4.x via magellan. 

gonzales and magellan know how to route only to their connected subnets;
gonzales does not (yet) know how to get to 192.168.3.x and magellan does
not know how to get to 192.168.4.x. 

First, let us set up gonzales. 


Now, ipsec0 needs to be associated with a real interface. In our case,
we shall associate it with the interface on the 192.168.2.0 subnet, that
is, eth2, because that's where IPSEC'ed traffic will flow. Then we
need to configure the new pseudo interface. Because
there is already a route to subnet 192.168.2.0 using eth2, we also need
to remove than and let the ipsec0 interface handle it:

	gonzales# tncfg attach ipsec0 eth0
	gonzales# ifconfig ipsec0 192.168.2.110 netmask 255.255.255.0 

On magellan, just load the module.

	magellan# depmod -a
	magellan# modprobe ipsec

2.1. Transport Mode.  (This doesn't work yet)

Let us have gonzales and magellan communicate securely, using the latest and
greatest IPSEC transform: triple-DES with replay protection and
96-bits of MD5 hash.

First, let's route all the packets destined for magellan through the ipsec0
interface:

	gonzales# route del 192.168.2.100 (to clear any old routes)
	gonzales# route add -net 192.168.2.100 \
			netmask 255.255.255.255 dev ipsec0

Issue the following command, which tells gonzales to process packets
originating with it and destined for magellan by applying a transform
defined by destination address 192.168.2.100 (magellan) and SPI 125

	gonzales# addrt 192.168.2.110 255.255.255.255 \
			192.168.2.100 255.255.255.255 \
 			192.168.2.100 125

To verify it has worked, type:

	gonzales# cat /proc/net/ipsec-route

you should get:

	(192.168.2.110/255.255.255.255 -> 192.168.2.110/255.255.255.255) =>
		(192.168.2.110, 0x00000125)

To set the actual Security Association, type:

	gonzales# setsa 192.168.2.100 125 esp 3des-md5-96 i \
		 1000000000000001 6630663066303132

And type the same thing on magellan, so it will know how to decrypt packets:

	magellan# setsa 192.168.2.100 125 esp 3des-md5-96 i \
		 1000000000000001 6630663066303132

If you ping magellan from gonzales, and look at the traffic on the wire,
you'll see that packets from gonzales to magellan are encrypted (and
authenticated), while packets from magellan to gonzales are in the clear.
Needless to say, you can set up a symmetric set of transforms on magellan
and gonzales, repspectively, so that the reverse traffic is also encrypted.

2.2. Tunnel mode.

Now, we want to set up gonzales so that packets from tortise to ping3 will be
tunneled through the (gonzales->magellan) tunnel. The first step is to set up a
route to net 192.168.4.0 through the ipsec0 interface:

	gonzales# route del 192.168.3.0 (to clear any old routes)
	gonzales# route add -net 192.168.3.0 \
			netmask 255.255.255.0 \
			dev ipsec0 gw 192.168.2.100

[ To understand what this does, remember that we "attached" eth0 to
ipsec0; the route is set up so that packets will be routed through
magellan, but they will first pass through the ipsec0 interface; then, when
they have been processed, they will be passed on to the attached
interface and delivered to the next-hop specified in the gw parameter
in the route command. ]

Now, issue the following command:

	gonzales# addrt 192.168.4.0 255.255.255.0 \
		   192.168.3.0 255.255.255.0 \
		   192.168.100 103

To verify it has worked, type:

	gonzales# cat /proc/net/ipsec-route

you should get:

	(192.168.4.0/255.255.255.0 -> 192.168.3.0/255.255.255.0) =>
		(192.168.4.0, 0x00000103)


This means that packets originating from net 192.168.4.x and destined
for net 192.168.3.x should be IPSEC-processed, with a "Destination
Address" of 192.168.2.100 and a "Security Parameters Index" of 103. The
Destination Address indicates the other point of the tunnel, whether
it is a real tunnel (as in this case), or simply the destination (in
what we call "transport mode" which doesn't quite work yet). The
Security Parameters Index, or SPI, is an opaque value that indicates,
along with the DA, what processing these packets will receive at our
end as well as the remote end. The pair (DA, SPI) is called a SAID
(Security Association IDentifier) in this document.

We now want to tell the IPSEC code what the processing for packets
which have been selected to be processed with DA=192.168.2.100 and
SPI=103. First, they will be encapsulated in simple IP-in-IP (proto 4)
encapsulation, and to enable that we type:

	gonzales# setsa 192.168.2.100 103 ip4 \
			192.168.2.110 192.168.2.100

This tells the IPSEC code that packets which have been selected to be
processed with DA=192.168.2.100 and SPI=103 should be run through algorithm
1 (IP-in-IP), with "outer" (encapsulating packet) source and
destination addresses of 192.168.2.110 (gonzales) and 192.168.2.100 (magellan)
respectively. Type
	
	gonzales# cat /proc/net/ipsec-spi

to verify that the SAID has been formed. You should get

	(192.168.2.100, 00000103, 1: [192.168.2.110 -> 192.168.2.100])

So far so good, but we've simply reproduced already existing
functionality. Now, let's add security. First, we'll tell the code to
encrypt packets using the ESP-DES-CBC transform. We'll create another
SAID, this time for algorithm 4 (ESP-DES-CBC).

	gonzales# setsa 192.168.2.100 105 esp des-cbc \
			66306630 6630663066303132

This tells the IPSEC layer that packets destined to be processed with
DA=192.168.2.100, SPI=105, should be processed with algorithm #4
(ESP-DES-CBC), use 0x66306630 as the DES-CBC Initialization Vector,
and use 0x6630663066303132 as the DES key (the DES parity bits are
ignored, so this yields the 56-bit DES key). 

Finally, we also want to authenticate the resulting packet, so we
create another SAID, this time for the AH-MD5 transform:

	gonzales# setsa 192.168.2.100 106 ah md5 \
			66306630663031326630663066303132

Now comes the crucial step. What the original addrt command did was to
establish that outgoing packets are to be processed with IP-in-IP
encapsulatino first. Now, we need to "link" this transform (IPIP) to the ESP
transform and then the AH. We do that with the spigrp ("group SPIs")command:

	gonzales# spigrp 192.168.2.100 103 \
			192.168.2.100 105 \
			192.168.2.100 106

To see the picture so far, type:

	gonzales# cat /proc/net/ipsec-spi

You should have:

	(192.168.2.100, 00000106, 2: klen = 16, alen = 16)
	(192.168.2.100, 00000105, 4: ivlen = 4, iv = 66 30 66 30)
	(192.168.2.100, 00000103, 1: [192.168.2.110 -> 192.168.2.100])

Now, on magellan, to receive and decode these packets, we need:

	magellan# setsa 192.168.2.100 105 esp des-cbc \
			66306630 6630663066303132
	magellan# setsa 192.168.2.100 106 ah md5 \
			66306630663031326630663066303132

since IP-in-IP does not need any special handling.  ESP and AH,
however, need the SAIDs to be established.  We use the same commands we
used for the outgoing packets on gonzales.

Typing:

	magellan# cat /proc/net/ipsec-spi 

should give us:

	(192.168.2.100, 00000106, 2: klen = 16, alen = 16)
	(192.168.2.100, 00000105, 4: ivlen = 4, iv = 66 30 66 30)

On magellan, now, we have to send things up the opposite way. Here are the
commands to use:

	magellan# tncfg attach ipsec0 eth0
	magellan# ifconfig ipsec0 192.168.2.100 netmask 255.255.255.0
	magellan# route del 192.168.4.0 (to clear any old routes)
	magellan# route add -net 192.168.4.0 netmask 255.255.255.0 dev ipsec0

	magellan# addrt 192.168.3.0 255.255.255.0 \
			192.168.4.0 255.255.255.0 \
			192.168.2.110 113

	magellan# setsa 192.168.2.110 113 ip4 \
			192.168.2.100 192.168.2.110
	magellan# setsa 192.168.2.110 115 esp des-cbc \
			66306630 6630663066303132
	magellan# setsa 192.168.2.110 116 ah md5 \
			66306630663031326630663066303132

	magellan# spigrp 192.168.2.110 113 \
			192.168.2.110 115 \
			192.168.2.110 116

Now, we also need to specify what will happen when gonzales receives
magellan's packets.

	gonzales# setsa 192.168.2.110 115 esp des-cbc \
			66306630 6630663066303132
	gonzales# setsa 192.168.2.110 116 ah md5 \
			66306630663031326630663066303132

To see the whole picture, type:

	gonzales# cat /proc/net/ipsec-spi

to get:

	(192.168.2.110, 00000116, 2: klen = 16, alen = 16)
	(192.168.2.110, 00000115, 4: ivlen = 4, iv = 66 30 66 30)
	(192.168.2.100, 00000106, 2: klen = 16, alen = 16)
	(192.168.2.100, 00000105, 4: ivlen = 4, iv = 66 30 66 30)
	(192.168.2.100, 00000103, 1: [192.168.2.110 -> 192.168.2.100])

Type:

	magellan# cat /proc/net/ipsec-route 

to get:

	(192.168.3.0/255.255.255.0 -> 192.168.4.0/255.255.255.0) =>
		(192.168.2.110, 0x00000113)

and type:

	magellan# cat /proc/net/ipsec-spi 

to get:

	(192.168.2.110, 00000116, 2: klen = 16, alen = 16)
	(192.168.2.110, 00000115, 4: ivlen = 4, iv = 6f 30 66 30)
	(192.168.2.110, 00000113, 1: [192.168.2.100 -> 192.168.2.110])
	(192.168.2.100, 00000106, 2: klen = 16, alen = 16)
	(192.168.2.100, 00000105, 4: ivlen = 4, iv = 66 30 66 30)

If you ping ping3 from tortise, ICMP packets will leave tortise, reach
gonzales, get encapsulated in IPIP, encrypted with DES and authenticated
with MD5, tunneled to magellan, get decapsulated, and then sent to ping3;
the return packets will follow the inverse path.

For completeness, let us show part of the routing tables on all four machines:

gonzales# netstat -r -n
Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        3 eth0
192.168.3.0     0.0.0.0         255.255.255.0   U     0      0        2 ipsec0
192.168.4.0     0.0.0.0         255.255.255.0   U     0      0        2 eth1
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        4 lo
0.0.0.0         <firewall>      0.0.0.0         UG    0      0        0 eth0

magellan# netstat -r -n
Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        1 eth0
192.168.3.0     0.0.0.0         255.255.255.0   U     0      0        2 eth1
192.168.4.0     0.0.0.0         255.255.255.0   U     0      0        1 ipsec0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        1 lo
0.0.0.0         <firewall>      0.0.0.0         UG    0      0        0 eth0

tortise# netstat -r -n
Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
192.168.3.0     192.168.4.110   255.255.255.0   UG    0      0        1 eth0
192.168.4.0     0.0.0.0         255.255.255.0   U     0      0        1 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        1 lo
0.0.0.0         192.168.4.110   0.0.0.0         UG    0      0        0 eth0

ping3# netstat -r -n
Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
192.168.3.0     0.0.0.0         255.255.255.0   U     0      0        1 eth0
192.168.4.0     192.168.3.100   255.255.255.0   UG    0      0        1 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        1 lo
0.0.0.0         192.168.3.100   0.0.0.0         UG    0      0        0 eth0

