|
Divya Mukundan (divi@ku.edu) Muthuvelan KP (kpm@ku.edu) Directed by Dr. Joseph B. Evans Department of Electrical Engineering and Computer Science The University of Kansas Lawrence, KS 66045 |
![]() |
Fall 2001Download code.See Real Video (80 kbps, 56 kbps). See PPT slides. |
| September 1 - September 30 | Reading NAT, AH, ESP, IKE, IETF IPsec-NAT drafts |
| September 1 - September 30 | Installation and testing of FreeS/wan IPsec system on Linux machines |
| October 1 - October 15 | Understanding FreeS/wan KLIPS implementation |
| October 16 - October 30 | Design of IPsec-NAT functionality changes |
| October 31 - November 30 | Implementation of Phase-1 |
| December 1 - December 15 | Phase-1 Testing & Troubleshooting |
| December 16 - December 17 | Preparation of project website and presentation |

We need to configure NAT on the linux machine which acts as the gateway for my private network. Any outgoing packet from 192.168.1.2 is mapped by NAT to the registered IP address (w.x.y.z). This is called Basic NAT i.e. mapping one IP address to another. Basic NAT can be used if we have a set of registered IP addresses. We can then map one IP address from that set with a private IP address. But in our case, it is NAPT (Network Address Port Translation) that allows the netbsd machine to communicate with the Internet.
NAPT maps a private address and TCP/UDP port to a registered IP address and chosen TCP/UDP port. NAPT allows TCP/UDP traffic as well as ICMP messages. To support ICMP packets, it maps the IP address and identifier in the ICMP header to a registered IP address and chosen identifier. To enable response packets to reach the requester machine, NAT maintains the mapping information.
If we need to permit inbound access (to the private network), i.e. if we want to run a web server on the netbsd machine, NAT can be configured to redirect packets destined to a specified TCP/UDP port service to a machine on the private network.
IPSEC is a solution to make Virtual Private Networks (VPN) possible. It provides security services such as data origin authentication, integrity, confidentiality (encryption) at the IP layer. IPSEC allows hosts/gateways to select the security protocols and algorithms they want to use and also provide a mechanism to exchange cryptographics the authentication/encryption algorithms may need. IPSEC can be setup to provide security services for traffic passing between host-host, gateway-gateway, host-gateway.Figure-1 - Host-Host
Figure-2 - Gateway - Gateway
Figure-3 - Host - Gateway
The following are the security protocols used in IPSEC.
Authentication Header (AH)
AH provides integrity, authentication and anti-replay services. It protects the upper layer data as well as certain portions of the IP header, extension headers and options. See AH encapsulation below.
Figure-4 shows the location of the AH header (transport mode) in an IP packet.Figure-4
Figure-5 shows the location of the AH header (tunnel mode) in an IP packet.
Figure-5
Encapsulating Security Payload (ESP)
ESP provides confidentiality in addition to the services provided by AH and is the preferred protocol. However, ESP only protects the payload portion of the IP packet. Figure-6 and Figure-7 show the location of the ESP header in transport and tunnel mode respectively.Figure-6
Figure-7
Internet Key Exchange (IKE)
The security protocols need cryptographic keys in place to serve as input to the algorithms they may use. The keys can be setup between the machines using either manual or automatic key distribution. IKE provides automatic key management functionality.Security Association (SA)
A security association is a one-way connection between two machines that specifies the services that are applied to the traffic flowing between those machines. The SA specifies the protocol used (can be either AH or ESP but not both). For example, in Figure-1, if the end hosts require ESP to protect the traffic between them, we would need to establish two SAs, one on each host. If both AH and ESP are required to protect the traffic, then we need to establish two SAs on each host, one for AH and the other for ESP. An SA is identified by the Security Parameter Index (SPI), IP destination address and the security protocol.The SA also specifies the mode - transport or tunnel mode. A transport mode SA is setup between two hosts whereas a tunnel mode SA is an SA applied to an IP tunnel. The following table lists the basic combinations of SAs that can be setup on hosts/gateways.
For the setup shown in Figure-1, any one of the following SAs could be used.
Transport Mode [IP1] [AH] [upper] - [IP1] [ESP] [upper] - [IP1] [AH] [ESP] [upper] Tunnel Mode [IP2] [AH] [IP1] [upper] - [IP2] [ESP] [IP1] [upper] Table-1 For the setup in Figure-2, any one of the following SAs could be used.
No Transport Mode - Tunnel Mode [IP2] [ESP] [IP1] [upper] - [IP2] [AH] [IP1] [upper] Table-2 For the setup in Figure-3, only a tunnel mode SA can be setup between the host-gateway. See Table-2.
Read Security Architecture for the Internet Protocol.
NAT provides a simple, economic solution to the problem of tight IPv4 address space. All the computers in a small sized network could be provided access to the Internet without investing in a whole lot of globally registered IP addresses. IPSEC, on the other hand, is the standard solution for VPN. If the network above needed secure access to its main network across the Internet, IPSEC would be its choice. See Figure-4.
Figure-4
One of the main services provided by IPSEC is message integrity. But, NAT modifies the IP header of outgoing packets. Here, lies the problem.
AH calculates the Authentication Data or Integrity Check Value (ICV) using IP source and destination addresses (See 3.3.3.1.1 in RFC 2402). With NAT changing these fields on the way, the ICV would be invalidated. ESP does not suffer from this problem while calculating the ICV as it computes this over the ESP packet minus the Authentication Data (See 2.7 in RFC 2406).2. TCP/UDP Checksums and NAT
TCP/UDP checksums are based on the pseudo-header. "The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length.": Source RFC 768. These checksums are recalculated by the NAT device. This will however invalidate the ESP Authentication Data as the packet has been altered en route.
- IKE must not generate packets with the Initiator Cookie field set to all zeroes.
- IKE must not generate ESP SPIs that are all zero.
- UDP encapsulation of ESP header (See 2.1 in draft-ietf-ipsec-udp-encaps-00.txt).
- UDP encapsulation of AH header (See 2.2 in draft-ietf-ipsec-udp-encaps-00.txt).
- Sending NAT keepalive packets (See 2.3 and 4 in draft-ietf-ipsec-udp-encaps-00.txt). The reciver should ignore this packet.
- The source and destination ports of the UDP header (just added) should be the same as used by the IKE traffic.
The file /etc/lilo.conf is updated as below and lilo command is executed before
rebooting the system.
The above procedure is done on testbed30 & testbed35 on which IPSEC needs to
be installed. The machines are rebooted with the new kernel as below.
Before applying the freeswan patch, the machines should be tested to see if the
existing or newly installed kernel functions properly. This would help in
detecting problems, which may occur later.
The new kernel is copied to an appropriate location.
The file /etc/lilo.conf is updated as below the lilo command is executed.
The two machines are rebooted with the ipsec enabled kernel.
We can verify the installation of ipsec by looking at dmesg or by executing
ipsec. The output of dmesg should show you the following. klips_info:ipsec_init:
KLIPS startup, FreeS/WAN IPSec version: 1.91.
Test Setup
Testing the Installation
Test Setup
Logical Topology
![]()
Physical Topology
![]()
Testing the Installation
Configuration
Turn on IP forwarding on all the machines. Add route information on the IPsec test machines so that packets sent between them are sent via the NAT gateway.testbed30:
route add -host 129.237.127.235 gw 129.237.125.242 echo "1" > /proc/sys/net/ipv4/ip_forwardtestbed35:route add -host 129.237.126.205 gw 129.237.125.242 echo "1" > /proc/sys/net/ipv4/ip_forwardtestbed21:echo "1" > /proc/sys/net/ipv4/ip_forwardThe above configuration can be tested by running traceroute on the two IPsec machines.testbed30:
traceroute testbed35testbed35:
- traceroute to testbed35.ittc.ku.edu (129.237.127.235), 30 hops max, 40 byte packets
- 1 testbed21 (129.237.125.242) 0.584 ms 0.300 ms 0.328 ms
- 2 testbed35 (129.237.127.235) 0.678 ms 0.827 ms 0.729 ms
traceroute testbed30The FreeS/WAN IPsec subsystem and VPN connection configuration is added to /etc/ipsec.conf and /etc/ipsec.secrets.
- traceroute to testbed30.ittc.ku.edu (129.237.126.205), 30 hops max, 38 byte packets
- 1 testbed21 (129.237.125.242) 0.558 ms 0.389 ms 0.372 ms
- 2 testbed30 (129.237.126.205) 2.353 ms 0.961 ms 0.773 ms
See an example configuration for manual connection - ipsec.conf , an example for automatic connection ipsec.conf and ipsec.secrets for testbed30.
See an example configuration for manual connection - ipsec.conf , an example for automatic connection ipsec.conf and ipsec.secrets for testbed35.Authentication in PLUTO can be done using RSA or by using shared keys.
Generating RSA keys
The RSA private/public key pair can be generated on the testbeds using the following command. The output from the command is added to ipsec.conf and ipsec.secrets.testbed35:
ipsec rsasigkey --verbose 2048 >testbed35testbed30:
- getting 32 random bytes from /dev/random...
- looking for a prime starting there (can take a while)...
- found it after 29 tries.
- getting 32 random bytes from /dev/random...
- looking for a prime starting there (can take a while)...
- found it after 283 tries.
- swapping primes so p is the larger...
- computing modulus...
- computing lcm(p-1, q-1)...
- computing d...
- computing exp1, exp1, coeff...
- output...
- # RSA 512 bits testbed35.ittc.ku.edu Wed Oct 31 23:42:32 2001
- # for signatures only, UNSAFE FOR ENCRYPTION
- #pubkey=0sAQOTMVGj6lWAzyKAqo4rzx6hfoFndgCZDtxNfuwB8UM7m5PsNj/O/uURitPT2P2nPg8pZE6sCNfKTSu1NHQ+QT1X
- #IN KEY 0x4200 4 1 AQOTMVGj6lWAzyKAqo4rzx6hfoFndgCZDtxNfuwB8UM7m5PsNj/O/uURitPT2P2nPg8pZE6sCNfKTSu1NHQ+QT1X
- # (0x4200 = auth-only host-level, 4 = IPSec, 1 = RSA)
- Modulus: 0x933151a3ea5580cf2280aa8e2bcf1ea17e81677600990edc4d7eec01f1433b9b93ec363fcefee5118ad3d3d8fda73e0f29644eac08d7ca4d2bb534743e413d57
- PublicExponent: 0x03
- # everything after this point is secret
- PrivateExponent: 0x18883845fc639577db1571c25ca2851aea6ae693aac42d24b7952755a835df4455840cb066fdb14cb58ce7f01a0161faeaa63ad6304b6caeab05866cc1ae0997
- Prime1: 0xff233af68837b83ec0ca03e6eb8c274a200310036e2dc9f3d28372b0cdd65a95
- Prime2: 0x93b0af26dcd5050688bc60517612cae3897bdda378e5744157109b36e656a93b
- Exponent1: 0xaa177ca45acfd029d5dc0299f25d6f86c0020aacf41e86a28c57a1cb33e43c63
- Exponent2: 0x6275ca19e88e0359b07d958ba40c87425ba7e917a5ee4d80e4b5bccf4439c627
- Coefficient: 0x126315ef4c52b834fa12c0bea11225737778ed9c81583ce2af7f6efff1391151
ipsec rsasigkey --verbose 2048 >testbed30
- getting 32 random bytes from /dev/random...
- looking for a prime starting there (can take a while)...
- found it after 106 tries.
- getting 32 random bytes from /dev/random...
- looking for a prime starting there (can take a while)...
- found it after 70 tries.
- computing modulus...
- computing lcm(p-1, q-1)...
- computing d...
- computing exp1, exp1, coeff...
- output...
- # RSA 512 bits testbed30.ittc.ku.edu Wed Oct 31 23:43:55 2001
- # for signatures only, UNSAFE FOR ENCRYPTION
- #pubkey=0sAQPgjVKjzmVFznS0TxEiUzfVVXxvKQyPOtl4p170s6q8/w/4YDemf879IVpqdiSltby73FsDp21bZ9ReVPxM0O7V
- #IN KEY 0x4200 4 1 AQPgjVKjzmVFznS0TxEiUzfVVXxvKQyPOtl4p170s6q8/w/4YDemf879IVpqdiSltby73FsDp21bZ9ReVPxM0O7V
- # (0x4200 = auth-only host-level, 4 = IPSec, 1 = RSA)
- Modulus: 0xe08d52a3ce6545ce74b44f11225337d5557c6f290c8f3ad978a75ef4b3aabcff0ff86037a67fcefd215a6a7624a5b5bcbbdc5b03a76d5b67d45e54fc4cd0eed5
- PublicExponent: 0x03
- # everything after this point is secret
- PrivateExponent: 0x256ce31b4d10e0f7be1e0d2d85b8894e38ea1286d76d3479941be528c89c74d4dd686a8126e399f41482c6ac583429c443180e184aa372c67c06a9a0d348b39d
- Prime1: 0xf041f9e5e59e4450923e233aadfd018ed090dfe761b35ea45c33e1b02e31bb2b
- Prime2: 0xef43e74ad78beef4140b9f31656fb99458bb268a85e54c1c900279872aeafdff
- Exponent1: 0xa02bfbee99142d8b0c296cd1c953565f35b5ea9a41223f183d77ebcac9767cc7
- Exponent2: 0x9f829a31e507f4a2b807bf76439fd10d907cc45c594388130aac5104c74753ff
- Coefficient: 0x077d3d4c716febdb39125cb4b61028c9cb1f02c9615efd37817f4b0c6c8ce3b8
Generating shared secret keys
Pre-shared secret keys can be used to authenticate PLUTO in IPSEC. The keys can be generated using the following command. ipsec ranbits --bytes 25
- 0x187da44c_0e64589f_1696470f_b2dc6476_51dc8853_5cb052c5_e1
The output should be added to ipsec.secrets at both IPSEC endpoints as shown below.
: PSK "0x187da44c_0e64589f_1696470f_b2dc6476_51dc8853_5cb052c5_e1"Testing the IPSEC installation and sample connection
Boot the test machines once the .conf and .secrets files are ready. Check /proc/net/ipsec_tncfg file to verify that the ipsec interface has been setup. It should look like this.- ipsec0 -> eth0 mtu=16260(1500) -> 1500
- ipsec1 -> NULL mtu=0(0) -> 0
- ipsec2 -> NULL mtu=0(0) -> 0
- ipsec3 -> NULL mtu=0(0) -> 0
If you don't see an IPsec interface associated with a physical interface, execute the 'ipsec tncfg' command. ipsec tncfg --attach --virtual ipsec0 --physical eth0Testing traffic before setting up an IPsec connection
The following can be used to test the traffic between testbed30 and testbed35.testbed35:
ping -p feedfacedeadbeef testbed30
testbed21: tcpdump -i eth0 -x -v dst host testbed30- 00:45:20.757888 < testbed35.ittc.ku.edu > testbed30.ittc.ku.edu: icmp: echo request (DF) (ttl 64, id 0)
- 4500 0054 0000 4000 4001 3816 81ed 7feb
- 81ed 7ecd 0800 9d12 db27 2d00 80d8 e83b
- 5291 0b00 face feed dead beef face feed
- dead beef face feed dead beef face feed
- dead beef face feed dead beef face feed
- dead beef
Starting IPSEC (KLIPS and PLUTO)
Below is a list of ipsec commands, sample output and its usage.To start KLIPS and PLUTO on a testbed, use the following.
ipsec setup --start- ipsec setup: Starting FreeS/WAN IPsec 1.91...
ipsec setup --status
To check the status of IPsec, use...- IPsec running
- pluto pid 10670
To check the status of a PLUTO, use... ipsec whack --status- 000 interface ipsec0/eth0 129.237.126.205
- 000
- 000 "host-host": 129.237.126.205---129.237.125.242...129.237.125.242---129.237.127.235
- 000 "host-host": ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0
- 000 "host-host": policy: RSASIG+ENCRYPT+PFS; interface: eth0; unrouted
- 000 "host-host": newest ISAKMP SA: #0; newest IPsec SA: #0; eroute owner: #0
- 000
ipsec whack --listen
To listen on port 500 for IKE messages, use...- 002 listening for IKE messages
- 002 forgetting secrets
- 002 loading secrets from "/etc/ipsec.secrets"
ipsec auto --up host-host
To start a connection using automatic keying, use...
(where host-host identifies the connection to be started)- 104 "host-host" #1: STATE_MAIN_I1: initiate
- 106 "host-host" #1: STATE_MAIN_I2: from STATE_MAIN_I1; sent MI2, expecting MR2
- 108 "host-host" #1: STATE_MAIN_I3: from STATE_MAIN_I2; sent MI3, expecting MR3
- 004 "host-host" #1: STATE_MAIN_I4: ISAKMP SA established
- 112 "host-host" #2: STATE_QUICK_I1: initiate
- 004 "host-host" #2: STATE_QUICK_I2: sent QI2, IPsec SA established
ipsec whack --status
To check the status of the connection, use...- 000 interface ipsec0/eth0 129.237.126.205
- 000
- 000 "host-host": 129.237.126.205---129.237.125.242...129.237.125.242---129.237.127.235
- 000 "host-host": ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0
- 000 "host-host": policy: RSASIG+ENCRYPT+PFS; interface: eth0; erouted
- 000 "host-host": newest ISAKMP SA: #1; newest IPsec SA: #2; eroute owner: #2
- 000
- 000 #2: "host-host" STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 28038s; newest IPSEC; eroute owner
- 000 #2: "host-host" esp.9ff11fca@129.237.127.235 esp.47503eed@129.237.126.205
- 000 #1: "host-host" STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 2588s; newest ISAKMP
ipsec setup --stop
To stop both KLIPS and PLUTO on a testbed, use...- ipsec setup: Stopping FreeS/WAN IPsec...
ipsec status --status- IPsec stopped
ipsec auto --down host-host
Remember that the aboce command should be executed on both end-points.For manual keying,
ipsec manual --up host-host ipsec manual --down host-hostTesting traffic after setting up an IPsec connection
Test Plan
Basic Testing
To test the new implementation, we need to do the following.
- Testing outgoing IPsec packets
- Verify that outgoing IPsec packets are encapsulated in UDP appropriately both for transport and tunnel mode connections.
- Verify that outgoing IPsec packets with ESP encapsulation contain the non-IKE marker in addition to the UDP header.
- Verify that outgoing IPsec packets with AH encapsulation contain the non-IKE marker, non-ESP marker and AH envelop in addition to the UDP header.
- Verify that all other packet construction procedures still behave as in the original 1.91 FreeS/wan version.
- Testing packet reception and processing
- Testing NAT keep alives.
Testing with NAT
To test whether the new implementation solves the incompabitibilities between NAT and the IPSEC security protocols (AH/ESP), we need to configure NAT between the testbeds that implement IPSEC. See test setup. We need to configure manual key distribution in IPSEC because IKE and NAT still have their differences which is not addressed in this implementation. See Figure-7.
- Configure alias address 192.168.1.1 on eth0 on testbed35.
- Configure NAT (ipchains) on testbed21 to map 192.168.1.1 to the pubilc address 129.237.127.235.
- Add route on testbed21 for 192.168.1.1.
- See configuration file.
Test Tools
The following test tools were used to aid the testing & debugging process.
- PING Program
- To verify that outgoing IPsec packets have been properly encapsulated by the new implementation, and check packet contents (i.e. encryption and authentication data) against that of the older version (1.91), we need finer control over the PING program. The PING source code was modified to generate ICMP Echo Requests with zero Identification, Sequence Number and Time Stamp fields. The source code was also modified to generate payload with a specified pattern.
- Browse the source code here.
The following files in FreeS/wan were modified to make KLIPS conform to the specifications in UDP Encapsulation of IPsec Packets.
| Config.in | ipsec_rcv.c |
| ipsec_tunnel.c | ipsec_netlink.c |
| ipsec_ah.h | ipsec_xform.c |
| ipsec_esp.h | pfkey_v2_parser.c |
| ipsec_init.c |
Introduction to FreeS/WAN
FreeS/WAN is a Linux implementation of the IPSEC (IP security) protocols. Their implementation consists of three parts.The IPSEC layer is implemented as a virtual device. KLIPS defines four device structures dev_ipsec0, dev_ipsec1, dev_ipsec2, dev_ipsec3. The command IPSEC_TNCFG is used to attach one of these virtual devices to a physical device on the machine. For example,
- KLIPS (kernel IPSEC) implements AH, ESP, and packet handling within the kernel.
- Pluto (an IKE daemon) implements IKE, negotiating connections with other systems.
- Various scripts that provide an administrative interface to the IPsec.
ipsec tncfg --attach --ipsec0 --eth0
The ipsec devices register themselves with the linux kernel in the ipsec_init() function. The following functions are called to perform device registration - register_netdevice_notifier, register_netdev. The security protocols ESP, AH also register with INET in the ipsec_init() function by calling inet_add_protocol(). Device and protocol registration enables the IPsec system to receive packets from the kernel.The data structure central to IPsec is struct tdb (tunnel descriptor block). This structure contains all the details about a Security Association. KLIPS maintains a hash table of such structures called tdbh. When a transport or tunnel mode connection is setup (either manually or automatically by IKE), the SAs negotiated are added to the tdbh. The combination of SPI, security protocol and destination IP address serves as the hash value to find the tunnel descriptor structure in tdbh. For example, when a transport mode connection with ESP SA is setup, we have the following list in the tunnel descriptor hash.
Figure-10
![]()
When a tunnel mode connection with ESP SA is setup, we have the following list in the tunnel descriptor hash.
Figure-11
![]()
Figure-9 explains the flow of outgoing packets through the kernel. Suppose that an ICMP packet needs to be transmitted.
Figure-12 shows the flow of incoming packets through the kernel.
Implementation
The following were the basic changes.
- Encapsulation of IPsec packets in UDP header.
- This is handled in ipsec_tunnel_start_xmit() function. The UDP header is be added when the encapsulation for the last tunnel descriptor block is being done. Depending on the protocol (IPPROTO_ESP, IPPROTO_AH), the Non-IKE marker, Non-ESP marker, AH-Envelop fields are added after the UDP header is added. This does not alter the flow of packets through the kernel. See Figure-9.
Figure-13
- De-encapsulation of UDP header before IPsec processing.
- When the UDP encapsulated IPsec packet is received, the packet is processed at the UDP layer by the udp_rcv() function. We remove the UDP header from the sk_buff structure, modify the packet so that ipsec_rcv function can process it as before, and then call netif_rx() function. This alters the flow of the IPsec packet through the kernel. See Figure-13. The packet flow then follows the same path as shown in Figure-12.
![]()
- Transmission of NAT keep-alive packets between every pair of IKE peers.
- For each IKE peer, we transmit a UDP packet with payload FF after every 'timeout' period of time. This is implemented in the IKE (PLUTO) module.
1. Testing packet transmission (on testbed35 - version 1.91) to observe outgoing IPsec packets.
Testing transport mode ESP connection. See configuration file.