Practical 16: IP Security (IPsec) Configuration
Chapter Twenty-One
Syllabus topic Module 2, "IP Security (IPsec) Configuration: Configure IPsec on network devices to provide secure communication and protect against unauthorized access and attacks."
Pages 162 to 168 of 206
Aim
To configure IPsec between two hosts, to show that traffic between them is unreadable on the wire afterwards, and to say what IPsec protects and what it does not.
What you need to know before you start
Everything in this module so far has protected one message. IPsec protects every packet, and it does it inside the operating system, so the programs sending the packets do not know it is happening and do not have to be changed. A web browser, a database client and a print job are all protected at once.
RFC 4301 gives it two protocols, and the difference is a standard question.
AH, the Authentication Header, authenticates the packet and its source address. It does not encrypt, so anybody can read the contents; they just cannot change them undetected.
ESP, the Encapsulating Security Payload, encrypts the contents and authenticates them as well. It is what is used in practice, and RFC 4301 says so in terms: an IPsec implementation "MUST support ESP and MAY support AH", because experience showed that there are very few situations ESP cannot cover, ESP being usable for integrity alone when confidentiality is not wanted.
And two modes:
| Transport mode | Tunnel mode | |
|---|---|---|
| What is protected | the payload of the packet | the whole original packet |
| The IP header | the original one, in the clear | a new outer one; the original is encrypted |
| Who can see the real addresses | anybody | nobody outside |
| Used for | host to host | a gateway to gateway VPN |
Two databases hold the configuration, and both names are examinable:
- The Security Association Database, SAD, holds the keys and algorithms for each one-way protected connection. A security association is one direction only, so two hosts talking need two.
- The Security Policy Database, SPD, says which traffic must be protected, which may pass in the clear, and which must be discarded.
Each association is identified by a Security Parameters Index, the SPI, which travels in every packet so the receiver knows which keys to use.
Step 1: two hosts, and the traffic in the clear
Two network namespaces joined by a virtual cable. Everything that follows happens inside one container.
$ ip netns add hostA
$ ip netns add hostB
$ ip link add vethA type veth peer name vethB
$ ip link set vethA netns hostA
$ ip link set vethB netns hostB
$ ip -n hostA addr add 10.9.0.1/24 dev vethA
$ ip -n hostB addr add 10.9.0.2/24 dev vethB
$ ip -n hostA link set vethA up
$ ip -n hostB link set vethB up
$ ip -n hostA link set lo up
$ ip -n hostB link set lo up
$ ip netns exec hostA ping -c 2 -W 2 10.9.0.2 2>/dev/null | tail -3
--- 10.9.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.000/0.000/0.000/0.000 msPractical 16: IP Security (IPsec) Configuration
Two hosts that can reach each other. Now look at what a listener sees, with a message deliberately put inside the ping so that it is easy to find.
#!/bin/bash
# Capture two packets on hostB's end of the cable while hostA pings, then
# print them. tcpdump has to start BEFORE the ping and be waited for
# afterwards, so it is a script rather than three lines typed at the prompt:
# a background job left running at a prompt is the commonest way a capture
# comes out empty. `setsid` puts tcpdump in a session of its own, so it cannot
# hold the terminal open after the script has finished with it, and --wait
# makes setsid wait for it, so `wait` below really waits for the capture
# rather than for setsid itself. Two seconds is how long tcpdump needs to
# be listening before the first packet: with one, the capture came out empty.
# NOTE: `timeout 8` is not decoration: if tcpdump never sees its two packets it
# waits for ever, and the whole session waits with it.
setsid --wait timeout 8 ip netns exec hostB tcpdump -n -i vethB -c 2 -w /tmp/cap.pcap icmp >/dev/null 2>&1 </dev/null &
TD=$!
sleep 2
ip netns exec hostA ping -c 2 -i 0.4 -p 53454352455453454352455453454352 -s 15 10.9.0.2 >/dev/null 2>&1
wait $TD 2>/dev/null
tcpdump -n -r /tmp/cap.pcap -A 2>/dev/null-p 5345435245 54... fills the ping's payload with the bytes 53 45 43 52 45 54 over and over, which spell SECRET. Run it and read the capture.
$ bash capture.sh > /tmp/clear.txt 2>&1
$ grep -c "ICMP echo" /tmp/clear.txt
2
$ grep -c SECRET /tmp/clear.txt
2
$ grep -o "SECRET[A-Z]*" /tmp/clear.txt | head -1
SECRETSECRETSECThe count is 2, one for each captured packet, and the word is plainly visible in the readable column of the hex dump beside the bytes that produced it. Anybody on the path can read the contents of every packet, which is the state IPsec exists to change.
Step 2: configure IPsec
An association needs a direction, a protocol, an SPI, a mode and two keys: one for authentication and one for encryption. In real use those keys come from an IKE negotiation, which is Diffie-Hellman of Practical 15 with authentication over it; here they are written out so that the configuration itself is the thing being studied.
$ KA=0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20
$ KE=0x000102030405060708090a0b0c0d0e0f
$ ip -n hostA xfrm state add src 10.9.0.1 dst 10.9.0.2 proto esp spi 0x201 mode transport auth "hmac(sha256)" $KA enc "cbc(aes)" $KE
$ ip -n hostA xfrm state add src 10.9.0.2 dst 10.9.0.1 proto esp spi 0x202 mode transport auth "hmac(sha256)" $KA enc "cbc(aes)" $KE
$ ip -n hostB xfrm state add src 10.9.0.1 dst 10.9.0.2 proto esp spi 0x201 mode transport auth "hmac(sha256)" $KA enc "cbc(aes)" $KE
$ ip -n hostB xfrm state add src 10.9.0.2 dst 10.9.0.1 proto esp spi 0x202 mode transport auth "hmac(sha256)" $KA enc "cbc(aes)" $KE
$ ip -n hostA xfrm policy add src 10.9.0.1 dst 10.9.0.2 dir out tmpl proto esp mode transport
$ ip -n hostA xfrm policy add src 10.9.0.2 dst 10.9.0.1 dir in tmpl proto esp mode transport
$ ip -n hostB xfrm policy add src 10.9.0.2 dst 10.9.0.1 dir out tmpl proto esp mode transport
$ ip -n hostB xfrm policy add src 10.9.0.1 dst 10.9.0.2 dir in tmpl proto esp mode transport
$ ip -n hostA xfrm state | grep -E "^src|spi|auth|enc" | head -8
src 10.9.0.2 dst 10.9.0.1
proto esp spi 0x00000202 reqid 0 mode transport
auth-trunc hmac(sha256) 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 96
enc cbc(aes) 0x000102030405060708090a0b0c0d0e0f
src 10.9.0.1 dst 10.9.0.2
proto esp spi 0x00000201 reqid 0 mode transport
auth-trunc hmac(sha256) 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 96
enc cbc(aes) 0x000102030405060708090a0b0c0d0e0fPractical 16: IP Security (IPsec) Configuration
Four states and four policies, and the reason for four of each is the sentence to write in the journal: a security association is one-way, so each host needs one for the traffic it sends and one for the traffic it receives, and each host needs an outbound policy and an inbound policy to match.
auth "hmac(sha256)" and enc "cbc(aes)" are the two algorithms, and they are exactly the two halves of Practicals 13 and 11: a MAC for integrity and authenticity, and a block cipher for secrecy. IPsec is not new cryptography; it is the cryptography of this module applied to every packet.
Step 3: the same traffic, after
#!/bin/bash
# The same capture, filtered on `icmp or esp` rather than `icmp`: after IPsec
# there are no ICMP packets on the wire at all, and a capture that matched
# nothing would look like a broken capture rather than a result.
setsid --wait timeout 8 ip netns exec hostB tcpdump -n -i vethB -c 2 -w /tmp/cap2.pcap "icmp or esp" >/dev/null 2>&1 </dev/null &
TD=$!
sleep 2
ip netns exec hostA ping -c 2 -i 0.4 -p 53454352455453454352455453454352 -s 15 10.9.0.2 >/dev/null 2>&1
wait $TD 2>/dev/null
tcpdump -n -r /tmp/cap2.pcap -A 2>/dev/null$ bash capture2.sh > /tmp/esp.txt 2>&1
$ grep -c "ICMP echo" /tmp/esp.txt
0
$ grep -c SECRET /tmp/esp.txt
0
$ grep -c "ESP(spi=0x00000201" /tmp/esp.txt
1
$ grep -o "ESP(spi=0x00000201,seq=0x1)" /tmp/esp.txt | head -1
ESP(spi=0x00000201,seq=0x1)Zero occurrences of SECRET, and the packets now read as ESP. The word that was plainly visible in step 1 is not in the capture at all, and what the listener sees instead is the protocol name, the SPI and a length. The ping still works, because the two kernels decrypt and re-encrypt without the ping program knowing anything about it.
Practical 16: IP Security (IPsec) Configuration
Confirm that the traffic really is still flowing, and look at the counters the kernel keeps.
$ ip netns exec hostA ping -c 3 -W 2 10.9.0.2 2>/dev/null | tail -2
3 packets transmitted, 3 received, 0% packet loss, time 2026ms
rtt min/avg/max/mdev = 0.000/0.000/0.000/0.000 ms
$ ip -n hostA xfrm state | grep -c "spi 0x00000201"
1
$ ip -n hostA xfrm policy | head -6
src 10.9.0.2/32 dst 10.9.0.1/32
dir in priority 0
tmpl src 0.0.0.0 dst 0.0.0.0
proto esp reqid 0 mode transport
src 10.9.0.1/32 dst 10.9.0.2/32
dir out priority 0Step 4: what happens when one side is wrong
A configuration exercise is not finished until it has been broken on purpose, because that is what the examiner will ask about.
$ ip -n hostB xfrm state delete src 10.9.0.1 dst 10.9.0.2 proto esp spi 0x201
$ ip netns exec hostA ping -c 2 -W 2 10.9.0.2 2>/dev/null | tail -2
2 packets transmitted, 0 received, 100% packet loss, time 1016ms
$ ( ip netns exec hostA ping -c 2 -W 2 10.9.0.2 >/dev/null 2>&1 ); echo "ping exit status $?"
ping exit status 1100 per cent packet loss, and ping exits 1. The second line runs ping on its own rather than through tail, because a pipeline reports the status of its LAST command and tail always succeeds.
100 per cent packet loss. Host A still encrypts, because its policy still says to; host B no longer has the key to decrypt, so it drops every packet. Nothing reports an error to the user: the ping simply does not come back, and that is exactly what a misconfigured IPsec looks like in real life. Check both ends.
$ ip -n hostB xfrm state add src 10.9.0.1 dst 10.9.0.2 proto esp spi 0x201 mode transport auth "hmac(sha256)" 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 enc "cbc(aes)" 0x000102030405060708090a0b0c0d0e0f
$ ip netns exec hostA ping -c 2 -W 2 10.9.0.2 2>/dev/null | tail -2
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.000/0.000/0.000/0.000 msPut the association back and it works again.
Step 5: clean up
$ ip -n hostA xfrm policy flush
$ ip -n hostA xfrm state flush
$ ip -n hostB xfrm policy flush
$ ip -n hostB xfrm state flush
$ ip netns delete hostA
$ ip netns delete hostB
$ ip netns list | wc -l
0Practical 16: IP Security (IPsec) Configuration
What IPsec protects, and what it does not
It protects: the contents of every packet, against reading and against alteration; the source address, against spoofing, because a packet from the wrong source has no valid association; and, in tunnel mode, the real addresses too.
It does not protect: against a compromised endpoint, because the packets are in the clear at both ends; against traffic analysis, because an observer still sees that two addresses are talking, how much and when; and against anything at all if the keys are wrong, weak or shared.
And the manual keys in this chapter are not how it is done. A real deployment runs IKEv2 to negotiate the keys, which is Practical 15's Diffie-Hellman authenticated by Practical 14's signatures or by a certificate, rekeying periodically so that a stolen key exposes only a short window. Manual keying is used here because the exercise is about the associations and the policies, and because IKE would hide the very thing being studied.
Procedure
- Create two network namespaces and join them with a veth pair. Give each an address and confirm they can ping.
- Capture the traffic with tcpdump and find the payload in the clear.
- Choose an authentication key and an encryption key, and add four security associations, two on each host, one for each direction.
- Add four policies, an inbound and an outbound on each host.
- Print the state and the policy and identify the SPI, the mode and the two algorithms.
- Capture again, and record that the payload is gone and the packets are ESP.
- Confirm the ping still works.
- Delete one association and record what the failure looks like. Put it back.
- Flush both databases and delete the namespaces.
Observations
| Measured | Value |
|---|---|
| Hosts | 10.9.0.1 and 10.9.0.2, two network namespaces joined by a veth pair |
| Before IPsec, the word SECRET in the capture | present |
| Security associations added | 4, two per host, one per direction |
| Policies added | 4, an in and an out on each host |
| SPI, A to B and B to A | 0x201 and 0x202 |
| Protocol and mode | ESP, transport |
| Authentication algorithm | hmac(sha256) |
| Encryption algorithm | cbc(aes) |
| After IPsec, the word SECRET in the capture | absent |
| After IPsec, packets identified as ESP | present, with the SPI visible |
| Ping after IPsec | still works |
| One association deleted | 100 per cent packet loss, no error message |
| Association restored | works again |
Result
IPsec was configured between two hosts created as network namespaces inside one machine. Before configuration a capture on the link showed the payload of every packet in the clear, including a word placed there to be found. Four ESP security associations were then added, two on each host because an association is one-way, together with four policies, and the association carried HMAC-SHA256 for authentication and AES in CBC mode for encryption under SPI 0x201 in one direction and 0x202 in the other. A second capture of identical traffic contained no occurrence of the payload word and showed ESP packets carrying the SPI instead, while the ping continued to work unchanged. Deleting one association produced 100 per cent packet loss with no error message, which is what a one-sided misconfiguration looks like, and restoring it restored the traffic.
Practical 16: IP Security (IPsec) Configuration
Where marks are lost
Configuring one direction. A security association is one-way. Two hosts need four, and four policies.
A state without a policy, or a policy without a state. The policy says protect this traffic; the state says with what. Both, on both hosts.
Keys that do not match. The packets are silently dropped and nothing says why.
Expecting an error message. A broken IPsec looks like a network that has stopped working. The counters in ip xfrm state are where to look.
Saying AH encrypts. It authenticates only. ESP encrypts and authenticates.
Confusing the two modes. Transport protects the payload and leaves the original header; tunnel wraps the whole packet in a new one and is what a gateway VPN uses.
Presenting manual keys as normal practice. IKEv2 negotiates them, using Diffie-Hellman with authentication, and rekeys.
Not showing the before. A capture showing ESP proves nothing unless a capture of the same traffic beforehand showed the payload.
For the journal
Aim; AH against ESP and transport against tunnel, as two tables; SAD, SPD and SPI defined; the commands that build the two hosts; the capture before, with the payload visible; the four states and four policies with the algorithms named; the capture after, with the payload absent and the SPI visible; the ping that still works; the deliberate breakage and what it looked like; the clean-up; what IPsec protects and what it does not; the note that real deployments use IKEv2; the observation table; the result.
Quick revision
- IPsec protects every packet, in the kernel, so applications need no change.
- AH authenticates. ESP encrypts and authenticates. ESP is what is used.
- Transport mode protects the payload; tunnel mode wraps the whole packet in a new one.
- The SAD holds keys and algorithms; the SPD says which traffic to protect.
- A security association is ONE WAY. Two hosts need four associations and four policies.
- The SPI identifies the association and travels in every packet.
ip xfrm stateandip xfrm policyare the two commands.- A wrong key or a missing state gives silent packet loss, not an error.
- Real deployments negotiate keys with IKEv2, which is authenticated Diffie-Hellman.
- IPsec does not hide who is talking to whom, or how much.
Practical 16: IP Security (IPsec) Configuration
Questions you must be able to answer
1. What is the difference between AH and ESP? AH authenticates the packet and its source but does not encrypt, so the contents stay readable. ESP encrypts the contents and authenticates them as well, and it is what is used in practice.
2. What is the difference between transport and tunnel mode? Transport protects the payload and keeps the original IP header, which suits host-to-host protection. Tunnel encrypts the entire original packet inside a new one, which hides the real addresses and is what gateway VPNs use.
3. What are the SAD and the SPD? The Security Association Database holds the keys, algorithms and parameters for each protected one-way connection. The Security Policy Database says which traffic must be protected, which may pass and which must be dropped.
4. Why did you configure four security associations for two hosts? Because an association is one-way. Each host needs one for what it sends and one for what it receives, and both hosts must hold both.
5. What is the SPI, and why is it needed? The Security Parameters Index identifies which association a packet belongs to. It travels in the packet so the receiver knows which keys to apply, since it may hold many.
6. How did you prove the traffic is protected? By capturing the same ping before and after. Before, the payload word appeared in the capture; after, it did not appear at all and the packets were ESP with the SPI visible.
7. You deleted one association and the ping stopped. Was there an error message? No. The sender encrypted as its policy required and the receiver had no key, so it dropped the packets silently. A misconfigured IPsec looks like a network that has stopped working.
8. Where do the keys come from in a real deployment? From IKEv2, which runs an authenticated Diffie-Hellman exchange and rekeys periodically. Writing keys by hand is a teaching arrangement.
9. Does IPsec hide who is talking to whom? In transport mode, no: the original addresses are in the clear. In tunnel mode the inner addresses are hidden, but an observer still sees the two gateways, and how much traffic passes and when.
10. Application-level encryption already exists. Why protect at the IP layer? Because it covers every application at once, including ones that have no encryption of their own, and it requires no change to any of them.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.