The initial test is between phoenix (10.0.1.57) and cardinal (10.1.2.45). This
test will use both AH and ESP; packet and payload encryption. The test is
using only transport mode (i.e. it is not creating a tunnel). Phoenix and Cardinal
reside on different network segments, there is a router between them but no
firewall, nat or packet filtering.
Phoenix setup
This is the AH protocol setup:
setkey -c
add 10.0.1.57 10.1.2.45 ah 15700 -A hmac-md5 "1234567890123456";
add 10.1.2.45 10.0.1.57 ah 24500 -A hmac-md5 "1234567890123456";
^D
This sets up the AH protocol using hmac-md5 as the encryption algorithm.
hmac-md5 requires a 128bit key, which means it must be 16 characters (bytes)
long.
Breakdown of the first line:
10.0.1.57 source
10.1.2.45 destination
AH protocol
15700 SPI (unique ID#)
-A hmac-md5 authenication algorithm to use
"1234567890123456" secretkey
SPI tells the kernel which encryption rule and algorithm to use on traffic tagged
with that SPI
Now we will configure both machines to use AH and ESP. We will use the level of
default. Which means the kernel consults the sysctl variable esp_trans_deflev
to determine whether to encrypt or not. This allows us to remotely setup one
end (phoenix in this case) without losing connectivity. The default value of esp_trans_deflev
is 1. After looking at /sys/netinet6/ipsec.h and then doing a quick tcpdump
of the traffic between phoenix and cardinal, I have selected a value of 1, means
use encryption if available.
This is the relevent section from ipsec.h:
/* Security protocol level */
#define IPSEC_LEVEL_DEFAULT 0 /* reference to system default */
#define IPSEC_LEVEL_USE 1 /* use SA if present. */
#define IPSEC_LEVEL_REQUIRE 2 /* require SA. */
#define IPSEC_LEVEL_UNIQUE 3 /* unique SA. */
Cardinal
setkey -c
spdadd 10.1.2.45 10.0.1.57 any -P out ipsec
esp/transport/10.1.2.45-10.0.1.57/default
ah/transport/10.1.2.45-10.0.1.57/default;
Phoenix
setkey -c
spdadd 10.0.1.57 10.1.2.45 any -P out ipsec
esp/transport/10.0.1.57-10.1.2.45/default
ah/transport/10.0.1.57-10.1.2.45/default;
Note: the above spdadd line is one line and it encrypts all traffic (the `any' before
the -P). Check the setkey man page for info on how to encrypt certain
packets, e.g. rsh.
I'm only encrypting outbound traffic. And the format for the spdadd line is: spdadd
<src> <dst> <upperspec> <policy>
<upperspec> is upper layer protocol; tcp, udp or any are the options
<policy> is one of the following: -P direction discard
-P direction none
-P direction ipsec protocol/mode/src-dst/level
What's it look like?
A tcpdump of the traffic between phoenix and cardinal shows this:
One thing learned afterwards was the kernel loses the keys after a reboot.
There is a mechanism built into /etc/rc.conf which set the keys for
you at boot time. Note: do not modify /etc/defaults/rc.conf, make the
changes to /etc/rc.conf instead.
$ grep -i IPSEC /etc/defaults/rc.conf
ipsec_enable="NO" # Set to YES to run setkey on
ipsec_file
ipsec_file="/etc/ipsec.conf" # Name of config file for setkey
If you put your setkey commands into /etc/ipsec.conf, and set ipsec_enable
to true, your keys will be set for you at system startup. My thanks to Michael C.
Cambria for pointing this out to me.