Set Up IPsec in OpenBSD






Set Up IPsec in OpenBSD

Use IPsec the OpenBSD way.

Setting up IPsec in OpenBSD is fairly easy, because it's compiled into the kernel that ships with each release and is enabled by default. All that is left to do is to create the appropriate /etc/isakmpd/isakmpd.conf and /etc/isakmpd/isakmpd.policy files and start isakmpd (the IPsec key-management daemon).

This might sound daunting, but OpenBSD's outstanding documentation and example configuration files make it easier than you might think.

Password Authentication

First, to set a password to use for the IPsec connection, you'll need to put these lines in your /etc/isakmpd/isakmpd.policy:

KeyNote-Version: 2
Authorizer: "POLICY"
Licensees: "passphrase:squeamishossifrage"
Conditions: app_domain == "IPsec policy" &&
            esp_present == "yes" &&
            esp_enc_alg == "aes" &&
            esp_auth_alg == "hmac-sha" -> "true";

Now, edit your /etc/isakmpd/isakmpd.conf file to contain the following lines:

[General]
Listen-on=              10.1.0.11
Shared-SADB=            Defined
Policy-File=            /etc/isakmpd/isakmpd.policy

[Phase 1]
10.1.0.11=              ISAKMP-peer-west
10.1.0.12=              ISAKMP-peer-east
Default=                ISAKMP-peer-east-aggressive

[Phase 2]
Connections=            IPsec-west-east

[ISAKMP-peer-east]
Phase=                  1
Local-address=          10.1.0.11
Address=                10.1.0.12
Configuration=          Default-main-mode
Authentication=         squeamishossifrage

[ISAKMP-peer-west]
Phase=                  1
Local-address=          10.1.0.12
Address=                10.1.0.11
Configuration=          Default-main-mode
Authentication=         squeamishossifrage


[ISAKMP-peer-east-aggressive]
Phase=                  1
Local-address=          10.1.0.11
Address=                10.1.0.12
Configuration=          Default-aggressive-mode
Authentication=         squeamishossifrage

[ISAKMP-peer-west-aggressive]
Phase=                  1
Local-address=          10.1.0.12
Address=                10.1.0.11
Configuration=          Default-aggressive-mode
Authentication=         squeamishossifrage

[IPsec-east-west]
Phase=                  2
ISAKMP-peer=            ISAKMP-peer-west
Configuration=          Default-quick-mode
Local-ID=               Host-east
Remote-ID=              Host-west

[IPsec-west-east]
Phase=                  2
ISAKMP-peer=            ISAKMP-peer-east
Configuration=          Default-quick-mode
Local-ID=               Host-west
Remote-ID=              Host-east

[Host-west]
ID-type=                IPV4_ADDR
Address=                10.1.0.11

[Host-east]
ID-type=                IPV4_ADDR
Address=                10.1.0.12

[Default-main-mode]
EXCHANGE_TYPE=          ID_PROT
Transforms=             3DES-SHA

[Default-aggressive-mode]
EXCHANGE_TYPE=          AGGRESSIVE
Transforms=             3DES-SHA-RSA

[Default-quick-mode]
DOI=                    IPSEC
EXCHANGE_TYPE=          QUICK_MODE
Suites=                 QM-ESP-AES-SHA-PFS-SUITE

The same configuration file can be used on both endpoints of the tunnel, with only a few changes. First, the example configuration shown above is for use on a machine with an IP address of 10.1.0.11. You can modify it to work on the other endpoint (10.1.0.12) by changing the IP address specified in Listen-on:

Listen-on=             10.1.0.12

Then, change the Default line to this:

Default=               ISAKMP-peer-west-aggressive

Finally, change the Connections line:

Connections=           IPsec-east-west

After you've edited the configuration files, you can start isakmpd by running this command:

# /sbin/isakmpd
            

Then, use one host in your tunnel to ping the other host. While doing this, start tcpdump on one of the systems. You should see some ESP packets:

# tcpdump -n
tcpdump: listening on pcn0, link-type EN10MB
21:19:38.920316 esp 10.1.0.11 > 10.1.0.12 spi 0xB9C862E7 seq 1 len 132
21:19:38.921420 esp 10.1.0.12 > 10.1.0.11 spi 0xBC4069F4 seq 1 len 132
21:19:39.926389 esp 10.1.0.11 > 10.1.0.12 spi 0xB9C862E7 seq 2 len 132
21:19:39.927216 esp 10.1.0.12 > 10.1.0.11 spi 0xBC4069F4 seq 2 len 132
21:19:40.940115 esp 10.1.0.11 > 10.1.0.12 spi 0xB9C862E7 seq 3 len 132
21:19:40.940711 esp 10.1.0.12 > 10.1.0.11 spi 0xBC4069F4 seq 3 len 132

If you want to see the decrypted packet contents, you can use tcpdump to monitor the enc0 interface:

# tcpdump -n -i enc0
tcpdump: WARNING: enc0: no IPv4 address assigned
tcpdump: listening on enc0, link-type ENC
21:21:53.281316 (authentic,confidential): SPI 0xb9c862e7: 10.1.0.11 > 10.1.0.12: icmp: echo request (encap)
21:21:53.281480 (authentic,confidential): SPI 0xbc4069f4: 10.1.0.12 > 10.1.0.11: icmp: echo reply (encap)
21:21:54.240855 (authentic,confidential): SPI 0xb9c862e7: 10.1.0.11 > 10.1.0.12: icmp: echo request (encap)
21:21:54.241059 (authentic,confidential): SPI 0xbc4069f4: 10.1.0.12 > 10.1.0.11: icmp: echo reply (encap)
               
            

Certificate Authentication

The configuration shown in the previous section allows anyone to connect with the password squeamishossifrage, but what if you want to use x.509 certificates for authentication? You'll first need to set up a Certificate Authority (CA) [Hack #69], if you don't already have one. Once you've done that, you'll need to make sure that each of your certificates has a subjectAltName, so that isakmpd can identify what certificate to use for a connection.

If you're using a version of OpenBSD prior to 3.8, you can do this easily with the certpatch tool. Otherwise, you'll need to regenerate the certificates for each endpoint from their certificate signing requests.

Using certpatch is easy; you supply the certificate to modify, the IP address or fully qualified domain name (FQDN), and the CA's key required to sign the modified certificate. If you want to patch a certificate to include an IP address in the subjectAltName field, use certpatch like this:

$ certpatch -i 10.1.0.11 -k CA.key 10.1.0.11.crt 10.1.0.11.crt   
Reading ssleay created certificate 10.1.0.11.crt and modify it
Enter PEM pass phrase:
Creating Signature: PKEY_TYPE = RSA: X509_sign: 128 OKAY 
Writing new certificate to 10.1.0.11.crt

If you want to use the FQDN, run something like this:

$ certpatch -t fqdn -i puffy -k CA.key puffy.crt puffy.crt
Reading ssleay created certificate asdf.crt and modify it
Enter PEM pass phrase:
Creating Signature: PKEY_TYPE = RSA: X509_sign: 128 OKAY 
Writing new certificate to puffy.crt

To add the subjectAltName field when signing a certificate, add -extfile /etc/ssl/x509v3.cnf -extensions x509v3_IPAddr to the openssl command you use to sign your certificates. If you want to use an FQDN rather than an IP address, replace x509v3_IPAddr with x509v3_FQDN. If your CA resides on a non-OpenBSD system, you'll need to copy /etc/ssl/x509v3.cnf to it from an OpenBSD system.

Once you're done adding the subjectAltName field, copy your CA's certificate to /etc/isakmpd/ca. Then, copy your certificates to /etc/isakmpd/certs on their corresponding host. Likewise, you'll need to copy your keys to /etc/isakmpd/private/local.key.

After you've gotten the certificate business out of the way, it's time to modify your isakmpd.conf and isakmpd.policy files. First, remove all of the Authenticate lines in the isakmpd.conf file. Then, locate the transforms line in the Default-main-mode section and change it to read 3DES-SHA-RSA_SIG. This is what tells isakmpd to use the x.509 certificates for authentication.

To tell isakmpd to allow only systems that are using certificates signed by your CA to connect, you need to modify your isakmpd.policy and tell it the distinguished name (DN) of your CA certificate:

$ openssl x509 -subject -noout -in ca/CA.crt 
subject= /C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd/CN=CA Root

Then, replace the Licensees line in your isakmpd.policy:

KeyNote-Version: 2
Comment: This policy accepts ESP SAs from hosts with certs signed by our CA
Authorizer: "POLICY"
Licensees: "DN: /C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd/CN=CA Root"
Conditions: app_domain == "IPsec policy" &&
            esp_present == "yes" &&
            esp_enc_alg != "null" -> "true";

Finally, to have isakmpd start up with each system boot, edit your /etc/rc.conf.local file (or create one if it doesn't exist) and put the following line in it:

isakmpd_flags=""

That should do it. As usual, check your system logs if your tunnel has trouble connecting.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows