Creating an internal CA¶
For services hosted within UIS we occasionally make use of the UIS traffic
manager to proxy traffic from the Big Bad Internet to our VMs which sit on
.private.cam.ac.uk
addresses. There are generally three ways the traffic
manager can be configured:
- No encryption between traffic manager and VM.
- Encryption between traffic manager and VM but without server verification.
- Encryption between traffic manager and VM with server verification.
Option 3 is to be preferred since it provides not only confidentiality but protection against man-in-the-middle attacks.
We could create a certificate signed by a global trust authority as we do for
public servers but this would lead to .private.cam.ac.uk
hostnames leaking
into the public domain via certificate transparency lists.
The traffic manager can be configured to trust a custom Certificate Authority (CA). We can maintain a separate CA per service or make use of a shared one.
Creating the CA root certificate and key¶
Create a key for the CA. The confidentiality of this key is the source of security so keep it safe.
openssl genrsa -out ca-private-key.pem 4096
Now create a new CA root certificate. The various fields such as organisation, etc don't matter but it is good form to set them to something sensible.
openssl req -new -x509 -days 3650 -key ca-private-key.pem -out ca-crt.pem
Creating the certificate signing request¶
The certificate signing request is used to create a certificate for the VM
itself. Rather than having to type each value in to openssl
you can specify
them in advance in a config file. For example, the Raven passwords app might use
the following config in password.conf
:
# Example OpenSSL configuration file for creating Certificate Signing
# Requests (CSRs) suitable for requesting certificates via
# the JISC sectigo TLS Certificate Service
#
# Edit this file as necessary (see comments), and then run (e.g.):
#
# openssl req -config qv.cnf -new -out <hostname>.csr -keyout <hostname>.key
#
# Replacing <hostname> with the primary server hostname (or
# similar). Accept most defaults but supply information for
# 'University institution' and 'Hostname'.
[ req ]
default_bits = 4096
default_md = sha256
distinguished_name = dn
# Uncomment to add SAN extensions and make further changes below
req_extensions = ext
[ dn ]
countryName = Country Name (use default)
countryName_default = GB
stateOrProvinceName = State or Province Name (use default)
stateOrProvinceName_default = Cambridgeshire
localityName = Locality Name (use default)
localityName_default = Cambridge
organizationName = Organisation Name (use default)
organizationName_default = University of Cambridge
organizationalUnitName_min = 2
organizationalUnitName_max = 64
# A common approach is to make commonName the primary DNS name of the
# service (e.g. www.is.cam.ac.uk) and use the alt_section below to set
# 'Subject Alternative Names' (SANs) for alternative names such as
# is.cam.ac.uk, intranet.is.cam.ac.uk, etc.
#
# However browsers now typically ignore commonName in favour of what
# appears in the SAN section of certificates, so it's now best practice
# to put ALL the names you want
commonName = secret-server1.srv.uis.private.cam.ac.uk
commonName_default = secret-server1.srv.uis.private.cam.ac.uk
commonName_min = 2
commonName_max = 64
[ ext ]
subjectAltName=@alt_section
[ alt_section ]
DNS.0=secret-server1.srv.uis.private.cam.ac.uk
DNS.1=secret-server2.srv.uis.private.cam.ac.uk
Generate a new key for the passwords app:
openssl genrsa -out passwords-private-key.pem 4096
Generate a certificate signing request (CSR) for the service:
openssl req -config passwords.conf -new \
-out passwords-csr.pem -key passwords-private-key.pem
Signing the CSR¶
The CA key can now be used to sign the CSR:
openssl x509 -req -days 3650 -in passwords-csr.pem \
-CA ca-crt.pem -CAkey ca-private-key.pem -set_serial 01 \
-out passwords-crt.pem -extensions ext -extfile passwords.conf
Checking our work¶
Check the generated certificate has all the server names:
openssl x509 -noout -in passwords-crt.pem -text
Deploying¶
We now have several files. The following files are not secret:
ca-crt.pem
passwords.conf
passwords-csr.pem
passwords-crt.pem
The following files are secret:
ca-private-key.pem
passwords-private-key.pem
Where the files end up depends on their use:
ca-crt.pem
can be sent to the traffic manager admins to install.ca-private-key.pem
must be kept safe and confidential so that it can be used to sign more certificates if needed.passwords.conf
andpasswords-csr.pem
can be saved for next time.passwords-crt.pem
andpasswords-private-key.pem
can be copied to the VM.
Examples¶
DevOps members can find the CA root private key for the passwords app in 1password along with the password service's private key.