Scripts and descriptions for setting up IPSEC with client authentication using certificates.

Markus Hennecke 0f943cfda4 Automate certificate and tarball creation 8 vuotta sitten
bin 0f943cfda4 Automate certificate and tarball creation 8 vuotta sitten
.gitignore 0f943cfda4 Automate certificate and tarball creation 8 vuotta sitten
LICENSE d816b202f0 initial commit 8 vuotta sitten
README.md 5e9e5ae511 Add setup description. 8 vuotta sitten
x509v3.cnf 0f943cfda4 Automate certificate and tarball creation 8 vuotta sitten

README.md

IPSEC on OpenBSD using Certificates

The following document will use the domain name example.com when refering to the domain name the CA authority should be created for. Replace it with your domain name.

1. Preparation

1.1 Certificate Configurations

Create a directory holding all CA related files. Make this directory read only for your user / or root. To make certificate creation easier copy the file /etc/ssl/openssl.cnf to the directory and add default values for these entries under the req_distinguished_name block:

  • countryName (two letters, DE)
  • stateOrProvince
  • localityName (e.g. city)
  • 0.organisationName (Your name, company name, domain)
  • organizationalUnitName ("VPN Auth")
  • commonName (ca@example.com)

Create a directory named private below the CA's root directory and make the directory accessible only to the user managing the CA (e.g. chmod 700 private/).

openssl.cnf:

CNAME                   = ca@example

[ req ]
default_bits            = 2048
default_md              = sha256
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
prompt                  = no

[ req_distinguished_name ]
countryName                     = DE
stateOrProvinceName             = NRW
localityName                    = Big City
0.organizationName              = John Doe
organizationalUnitName          = VPN Auth
commonName                      = $ENV::CNAME

1.2 CA Configuration

File x509v3.cnf:

CERTPATHLEN             = 1
CERTUSAGE               = digitalSignature,keyCertSign,cRLSign
EXTCERTUSAGE            = serverAuth,clientAuth
CADB                    = index.txt
CASERIAL                = serial.txt
NSCERTTYPE              = server,client

[ x509v3_extensions ]
nsCertType                      = 0x40

[ x509v3_CA ]
basicConstraints                = critical,CA:true,pathlen:$ENV::CERTPATHLEN
keyUsage                        = $ENV::CERTUSAGE

[ ca ]
default_ca                      = CA_default

[ CA_sign_policy ]
countryName                     = optional
stateOrProvinceName             = optional
localityName                    = optional
organizationName                = optional
organizationalUnitName          = optional
commonName                      = supplied
emailAddress                    = optional

[ CA_default ]
database                        = $ENV::CADB
serial                          = $ENV::CASERIAL
default_md                      = sha256
default_days                    = 365
default_crl_days                = 365
unique_subject                  = yes
email_in_dn                     = yes
policy                          = CA_sign_policy

1.3 Network setup

Create the enc0 interface:

echo up > /etc/hostname.enc0

and start it:

sh /etc/netstart enc0

2. Key Creation and Signing

Create a password for the private key first, you may type it in every time you use the CA private key or you can store the passphrase in a file (e.g. ca.pass) for the time setting up the CA. You can add the -passin file:ca.pass and -passout file:ca.pass arguments to the openssl commands listed below.

Hint for password creation:

tr -cd [0-9A-Za-z.,_-] < /dev/urandom | dd bs=1 count=32 2>/dev/null >ca.pass
chmod 600 ca.pass

Feel free to add more characters to the set of characters not to be deleted passed to tr.

2.1 Key Creation

Create the password protected CA key:

openssl genrsa -aes256 -out private/ca.key 4096

Use the -passout file:ca.pass parameter or type in the CA password.

2.2 Create Signing Request

openssl req -new -key private/ca.key -config openssl.cnf -out ca.csr

Use the -passin file:ca.pass parameter from now on when using a password file. Don't fill in the emailAddress and use "ca@example.com" for the commonName value.

2.3 Sign the CA Certificate

openssl x509 -sha256 -req -days 3650 -in ca.csr -signkey private/ca.key \
    -extfile x509v3.cnf -extensions x509v3_CA -out ca/ca.crt

Adjust the valid period of the certificate to your needs.

3. Creating Certificates

Certificate creation can either be done on the target system or on the system the CA resides on. To keep things central and simple the next steps will assume that all keys and certificates are created on the CA system and the necessary files are distributed to the IPSEC clients from there. All files created and required for a client are put into separate directories below a newly created clients dirctory. Assuming creating a certificate and key for the client named foobar, with foobar beeing the full qualified domain name the following script would create the certificate:

#! /bin/sh
# TODO

Since libressl removed the support for passing environment variables we need to pass our own config file for the x509v3 FQDN extension.

4. Setup ipsec.conf

Variable Value
CLIENT_NET_OR_IP e.g. 10.x.y.z/16
SERVER_IP IP address of lo1
SERVER_PUBLIC_IP Public IP address of the server
FQDN_CLIENT CN of the client certificate
FQDN_SERVER CN of the server certificate

Feel free to change the used ciphers for your needs. aes-128 is just the one cipher that is fully supported by the hardware crypto device in my soekris 5501 router.

4.1 Client

ike dynamic esp from CLIENT_NET_OR_IP to SERVER_IP peer SERVER_PUBLIC_IP \
        main auth hmac-sha2-256 enc aes-128 group modp1024 \
        quick auth hmac-sha2-256 enc aes-128 group modp1024 \
        srcid FQDN_CLIENT dstid FQDN_SERVER

4.2 Server

ike passive esp from SERVER_IP to CLIENT_NET_OR_IP peer any \
        main auth hmac-sha2-256 enc aes-128 group modp1024 \
        quick auth hmac-sha2-256 enc aes-128 group modp1024 \
        srcid FQDN_SERVER dstid FQDN_CLIENT

Each tunnel definition can be live in a single file using the include statement inside /etc/ipsec.conf. Adding tunnels that way enables you to remove tunnels on the fly using ipsecctl -d -f CLIENT.conf.

4.3 Startup

Add the following lines to /etc/rc.conf.local:

ipsec=YES
isakmpd_flags=-4 -K