Skip to content

Become your own SSL Certificate Authority

vibraphone edited this page Apr 23, 2013 · 2 revisions

By default the Midas instance these scripts configure will use a self-signed SSL certificate. These instructions cover how you can move up one step to a certificate signed by a Certificate Authority (CA) you generate. You'll have to add the CA to any browsers you use, but this is a way to sign certificates for use in your company without paying for a signature.

Generating a CA

See this page for detailed instructions.

mkdir -p root-ca/{conf,private,public}
chmod 400 root-ca/private
cd root-ca

Place the following into a file named conf/openssl.conf:

[ req ]
default_bits             = 2048
default_keyfile          = ./private/root.pem
default_md               = sha1
prompt                   = no
distinguished_name       = root_ca_distinguished_name
x509_extensions = v3_ca
[ root_ca_distinguished_name ]
countryName              = UK
stateOrProvinceName      = Sussex
localityName             = Brighton
0.organizationName       = Example Inc
commonName               = Example Inc Root CA
emailAddress             = me@example.com
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

Then run

openssl req -nodes -config conf/openssl.cnf -days 1825 -x509 -newkey rsa:4096 -out public/root.pem -outform PEM
openssl x509 -in public/root.pem -outform DER -out public/root.der
cp public/root.pem public/$(openssl x509 -noout -hash -in public/root.pem).0

To sign certificates, you must add the following to conf/openssl.conf:

[ ca ]
default_ca = CA_default
[ CA_default ]
dir                =.
new_certs_dir      = ./signed-keys/
database           = ./conf/index
certificate        = ./public/root.pem
serial             = ./conf/serial
private_key        = ./private/root.pem
x509_extensions    = usr_cert
name_opt           = ca_default
cert_opt           = ca_default
default_crl_days   = 30
default_days       = 365
default_md         = sha1
preserve           = no
policy             = policy_match
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ usr_cert ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
nsCaRevocationUrl     = https://www.example.com/example-ca-crl.pem

Be sure to edit nsCaRevocationUrl and perhaps the policy_match entries to indicate which fields must match your authority in order for the signature to be considered valid (i.e., are you only an authority in one state? country?). Then

mkdir signed-keys
echo "01" > conf/serial
touch conf/index

Finally, for each certificate request request.csr you wish to sign:

openssl ca -batch -config conf/openssl.cnf -in request.csr -out request.cert

The line above is repeated below for the example signature.

OpenSSL certificate signature

The commands below illustrate how to generate an SSL certificate and sign it with the CA you generated above:

# Generate a private key (add -des3 to associate a password with it)
openssl genrsa  -out my-key.pem 4096
# Generate a CSR asking a CA to sign your private key
openssl req -new -key my-key.pem -out my-cert.csr
# The command above will prompt you to provide:
  Country (C)
  State/Province (ST)
  City/Locality (L)
  Organization (O)
  Organizational Unit (OU)
  Common Name (CN). For an Amazon Elastic IP, use ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com
  Admin E-mail
  Challenge Password (optional)
  Optional Company Name
# Now sign the CSR with your CA
# Copy the key into your CA request directory (see above)
cp my-cert.csr /path/to/root-ca
cd /path/to/root-ca
# (a) Verify that the CSR common name is under control of the requestor:
openssl req -in my-cert.csr -noout -text
# (b) when you are satisfied that (a) is true, sign the request
openssl ca -batch -config conf/openssl.cnf -in my-cert.csr -out my.cert

Installing the CA-signed certificate

Now you can copy the private key (my-key.pem) and signed certificate (my.cert) onto your webserver. Make sure to protect my-key.pem at all times by transferring over an encrypted connection to a directory with proper access controls. The certificate my.cert is public. You will also want to copy the public part of the CA key (root-ca/public/*.0) to your webserver.

For the Ubuntu instance the puppet scripts target, you'll want to place

  • my-key.pem in /etc/ssl/private and
  • my-cert.pem and root-ca/public/*.0 in /etc/ssl/certs .

Once these certificates are in place, edit your webserver configuration to use them for the host you specified in the Common Name (CN) of the CSR. Again, for the Ubuntu instance targeted, edit /etc/apache2/sites-enabled/midasdocroot_sslonly and change the lines specifying the certificate and certificate-key files to:

SSLCertificateFile    /etc/ssl/certs/my-cert.pem
SSLCertificateKeyFile /etc/ssl/private/my-key.pem

Then restart Apache:

service apache2 restart