Scripts and descriptions for setting up IPSEC with client authentication using certificates.
Markus Hennecke 0f943cfda4 Automate certificate and tarball creation | преди 8 години | |
---|---|---|
bin | преди 8 години | |
.gitignore | преди 8 години | |
LICENSE | преди 8 години | |
README.md | преди 8 години | |
x509v3.cnf | преди 8 години |
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.
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:
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
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
Create the enc0 interface:
echo up > /etc/hostname.enc0
and start it:
sh /etc/netstart enc0
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
.
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.
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.
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.
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.
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.
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
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
.
Add the following lines to /etc/rc.conf.local
:
ipsec=YES
isakmpd_flags=-4 -K