Instant Certificate Authority script

Some software believes passionately in certificates signed by certificate authorities (CA), and will not budge without it.  This means that often enough you want to be your own CA. You cannot trust the likes of Diginotar to protect your interests: you need your own certificate authority on your own system … and you need it to be simple, because it should be. On days like this, you need an instant way of setting it up, which is what this script is.

Characteristics of scripts produced by this script:

  • SSL certificate and CA certificate are valid for 30 years: you can run this hack once, not once per year
  • Common Name is what you specify, everything else is default values.
  • Signed by your personal certificate authority, ‘ca’

If you use this for something serious then take note:

  • CA files are NOT password protected: this is for a fast and usable solution. Secure your operating system and use encrypted storage (and don’t blame me).
  • If you are still using these certificates 30 years after you generate them, you’ll need to replace them.
  • There is no practical provision for a certificate revocation list (CRL). If you lose a certificate, you should generate a new CA and new certificates.
  • If it eats your shorts, you can sue me only for the amount you pay me.

Download

instant-ssl-ca : bash shell script
Licence: GPL (GNU Public Licence v3)

Usage

This command gets you:

  • a 30 year CA
  • a CA-signed certificate for server.localdomain
  • a CA-signed certificate for client.localdomain

It’s pretty simple – the hard part is to copy the certificate to where you want it after it has been generated.

$ ./instant-ssl-ca --ssl server.localdomain client.localdomain

*****************************************************************
Making key named server.localdomain
*****************************************************************

*****************************************************************
Creating Certificate Authority: ca.{key,crt}
*****************************************************************
Generating a 1024 bit RSA private key
...............++++++
.......++++++
writing new private key to 'ca/ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [ZA]:State or Province Name (full name) [Somewhere]:Locality Name (eg, city) [Someplace]:Organization Name (eg, company) [Somepeople]:Organizational Unit Name (eg, section) []:Common Name (eg, your name or your server's hostname) [ca]:Email Address [someone@somewhere.else]:
*****************************************************************
Creating certificate signing request server.localdomain.csr
*****************************************************************
Generating a 1024 bit RSA private key
...++++++
........++++++
writing new private key to 'server.localdomain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [ZA]:State or Province Name (full name) [Somewhere]:Locality Name (eg, city) [Someplace]:Organization Name (eg, company) [Somepeople]:Organizational Unit Name (eg, section) []:Common Name (eg, your name or your server's hostname) [server.localdomain]:Email Address [someone@somewhere.else]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:
*****************************************************************
Certificate authority signing certificate => server.localdomain.crt
*****************************************************************
Using configuration from ca/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'ZA'
stateOrProvinceName   :PRINTABLE:'Somewhere'
localityName          :PRINTABLE:'Someplace'
organizationName      :PRINTABLE:'Somepeople'
commonName            :PRINTABLE:'server.localdomain'
emailAddress          :IA5STRING:'someone@somewhere.else'
Certificate is to be certified until Apr 30 18:28:28 2042 GMT (10950 days)
Sign the certificate? [y/n]:

1 out of 1 certificate requests certified, commit? [y/n]Write out database with 1 new entries
Data Base Updated

*****************************************************************
Output directory is ./server.localdomain
*****************************************************************

*****************************************************************
Making key named client.localdomain
*****************************************************************
CA: ca/ca.key and ca/ca.crt exist

*****************************************************************
Creating certificate signing request client.localdomain.csr
*****************************************************************
Generating a 1024 bit RSA private key
................................................................++++++
...........++++++
writing new private key to 'client.localdomain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [ZA]:State or Province Name (full name) [Somewhere]:Locality Name (eg, city) [Someplace]:Organization Name (eg, company) [Somepeople]:Organizational Unit Name (eg, section) []:Common Name (eg, your name or your server's hostname) [client.localdomain]:Email Address [someone@somewhere.else]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:
*****************************************************************
Certificate authority signing certificate => client.localdomain.crt
*****************************************************************
Using configuration from ca/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'ZA'
stateOrProvinceName   :PRINTABLE:'Somewhere'
localityName          :PRINTABLE:'Someplace'
organizationName      :PRINTABLE:'Somepeople'
commonName            :PRINTABLE:'client.localdomain'
emailAddress          :IA5STRING:'someone@somewhere.else'
Certificate is to be certified until Apr 30 18:28:28 2042 GMT (10950 days)
Sign the certificate? [y/n]:

1 out of 1 certificate requests certified, commit? [y/n]Write out database with 1 new entries
Data Base Updated

*****************************************************************
Output directory is ./client.localdomain
*****************************************************************

So, what did we get? We got a CA certificate (called “ca”) and two client certificates: one called “client.localdomain”, and the other called “server.localdomain”.

$ find 
.
./client.localdomain
./client.localdomain/client.localdomain.crt
./client.localdomain/client.localdomain.pem
./client.localdomain/client.localdomain.key
./client.localdomain/ca.crt
./.rnd
./ca
./ca/01.pem
./ca/ca.key
./ca/index.txt
./ca/index.txt.attr
./ca/index.txt.attr.old
./ca/serial
./ca/index.txt.old
./ca/02.pem
./ca/serial.old
./ca/ca.crt
./ca/openssl.cnf
./ca/ca.der
./server.localdomain
./server.localdomain/server.localdomain.pem
./server.localdomain/server.localdomain.key
./server.localdomain/server.localdomain.crt
./server.localdomain/ca.crt
./instant-ssl-ca

Applications

Things that you will use this for:

  • Internal HTTP, POP3 and SMTP certificates: If you install your value-free CA company-wide in your end users’ browsers, you can issue the certificates for https, pop3s and smtps / starttls, and decommission all those self-signed certificates you have floating around. For security, it would be better to have separate CA’s for mysql, VPN’s and mail/web. Actually, a certificate chain would be ideal, and this tool doesn’t do that. It’s just the basic stuff.
  • mysql: SSL certificates prevent your data from being sniffed. To set up a SSL connection, generate a certificate and copy it to the server.
    You configure the certificate in the server’s my.cnf, and then restart:

    ssl-ca=/etc/mysql/ssl/ca.crt
    ssl-key=/etc/mysql/ssl/server.localdomain.key
    ssl-cert=/etc/mysql/ssl/server.localdomain.crt

    Do the grant like this:

    GRANT ALL PRIVILEGES 
      ON `database_name`.* to 'username'@'%' 
      IDENTIFIED BY 'password' 
      REQUIRE SSL;
    

    The client side connection is:

    mysql --ssl-ca=$HOME/.mysql/ca.crt \
        --ssl-key=$HOME/.mysql/client.localdomain.key \
        --ssl-cert=$HOME/.mysql/client.localdomain.crt \
        -u 'username -p'password' -h 'server.localdomain' database_name
  • openvpn – generating the certificate files is the most painful part of the configuration.
    The certificate parts of the openvpn client configuration are:

    openvpn --client \
        --tls-remote server.localdomain \
        --ca ca.crt  --cert client.localdomain.crt --key client.localdomain.key
    

    The relevant parts of the openvpn server configuration:

    openvpn --server 10.123.0.0 255.255.255.0 \
        --ca ca.crt --cert server.localdomain.crt --key server.localdomain.key
    
  • Rabbitmq: Rabbitmq and erlang’s SSL support likes its certificate in RSA format, so you have to convert it from PEM (sorry about this – it’s a bit of a bug):
    openssl rsa < server.localdomain.key  > server.localdomain.rsakey

    Now you can configure it thusly:

    [
      {rabbit, [
        {ssl_listeners,[5671]},
        {ssl_options, [{cacertfile,"/etc/rabbitmq/ca.crt"},
                        {certfile,"/etc/rabbitmq/server.localdomain.crt"},
                        {keyfile,"/etc/rabbitmq/server.localdomain.rsakey"},
                        {verify,verify_peer},
                        {fail_if_no_peer_cert,true}]}
      ]}
    ].

Leave a Reply

Your email address will not be published. Required fields are marked *