Key and CSR Generation Instructions - method 1

First you have to know the Fully Qualified Domain Name (FQDN) of the website for which you wan to request a certificate. When you want to access your website through https://www.virtualhost.com then the FQDN of your website is www.virtualhost.com.

Second, select five large and relatively random files from your hard drive (compressed log files are a good start). These will act as your random seed enhancers. We refer to them as file1:file2:...:file5 below. On platforms where /dev/random exists this device is a good choice, too.

Step 1 - Generate the Key

Use the following command:

    $ openssl genrsa -rand file1:file2:...:file5 -out <hostname>.key 2048

or the commands:

    $ head /dev/urandom > /dev/null
    $ openssl genrsa -rand /dev/urandom -out <hostname>.key 2048

This command will generate 1024 bit RSA Private Key and stores it in the file www.virtualhost.com.key. If you add -des3 to the command line then you will be asked for a pass phrase: use something secure and remember it. Your certificate will be useless without the key.

Step 2 - Generate the CSR

Use the command:

$ openssl req -new -key www.virtualhost.com.key -out www.virtualhost.com.csr

This command will prompt you for the X.509 attributes of your certificate. Remember to give the name \tt www.virtualhost.com when prompted for `=Common Name (eg, YOUR name)='. Do not enter your personal name here. We are requesting a certificate for a webserver, so the Common Name has to match the FQDN of your website (a requirement of the browsers).

Step 2 Alternate - Generate CSR with Subject Alternate Names

If a CSR that supports multiple Subject Alternate Names must be generated a customized openssl.conf file must be used. The following steps are one way to do this.

  1. Copy the system openssl.conf file to a new location.

     $ cp /etc/ssl/openssl.cnf ~/openssl-san.conf
    
  2. Modify the local configuration by uncommenting the line:

     # req_extensions = v3_req # The extensions to add to a certificate request
    
  3. Modify the local configuration by adding the following lines in the v3_req section.

     subjectAltName=${ENV::SAN}
    
  4. The following commands will generate the CSR:

    $ setenv SAN "DNS:www.virtualhost.org DNS:www.virtualhost.net" $ openssl req -new -key www.virtualhost.com.key -out www.virtualhost.com.csr

Step 3 - Generate a self-signed Certificate

Use the command:

    $ openssl x509 -req -days 30 \
       -in www.virtualhost.com.csr \
       -signkey www.virtualhost.com.key \
       -out www.virtualhost.com.crt

This command will generate a certificate a self-signed certificate in www.virtualhost.com.crt.

To Get a Certificate Signed by a Certificate Authority

You will now have a RSA Private Key in www.virtualhost.com.key and a Certificate Signing Request in www.virtualhost.com.csr. The file www.virtualhost.com.key is your secret key. The file www.virtualhost.com.csr is your CSR, and the important bit looks something like this:

    -----BEGIN CERTIFICATE REQUEST-----
    MIIBPTCB6AIBADCBhDELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2Fw
    ZTESMBAGA1UEBxMJQ2FwZSBUb3duMRQwEgYDVQQKEwtPcHBvcnR1bml0aTEYMBYG
    A1UECxMPT25saW5lIFNlcnZpY2VzMRowGAYDVQQDExF3d3cuZm9yd2FyZC5jby56
    YTBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQDT5oxxeBWu5WLHD/G4BJ+PobiC9d7S
    6pDvAjuyC+dPAnL0d91tXdm2j190D1kgDoSp5ZyGSgwJh2V7diuuPlHDAgEDoAAw
    DQYJKoZIhvcNAQEEBQADQQBf8ZHIu4H8ik2vZQngXh8v+iGnAXD1AvUjuDPCWzFu
    pReiq7UR8Z0wiJBeaqiuvTDnTFMz6oCq6htdH7/tvKhh
    -----END CERTIFICATE REQUEST-----

The CSR in www.virtualhost.com.csr is what you now paste into the appropriate online enrolment form or sign it with your own certificate authority.

Key and CSR Generation Instructions - method 2

A new key and CSR can be created in a single step with the following command:

 $ openssl req -out ?.csr -new -newkey rsa:2048 -nodes -keyout ?.key

Create a Certificate Authority

This is mostly a summary of the steps documented at http://www.davidpashley.com/articles/cert-authority.html. There is also a good description of the same steps with makefile automation at http://sial.org/howto/openssl/ca/.

  1. Make a place to hold the CA files===

     mkdir -p /opt/cert-authority-zephyr/{conf,private,public,newcerts}
     chmod 700 /opt/cert-authority-zephyr/private
    
  2. Create the key for the CA===

Make an OpenSSL configuration file for the CA to be used to generate the key. The file, conf/openssl.conf, should contain:

     [ ca ]
     default_ca      = CA_default            # The default ca section

     [ CA_default ]

     dir            = /opt/cert-authority-zephyr # top dir
     database       = $dir/conf/index        # index file.
     new_certs_dir  = $dir/newcerts              # new certs dir

     certificate    = $dir/public/cacert.pem  # The CA cert
     serial         = $dir/conf/serial        # serial no file
     private_key    = $dir/private/cakey.pem  # CA private key
     RANDFILE       = $dir/private/.rand      # random number file

     default_days     = 3650                  # how long to certify for
     default_crl_days = 30                    # how long before next CRL
     default_md       = md5                   # md to use

     policy         = policy_any            # default policy
     email_in_dn    = no                    # Don't add the email into cert DN

     name_opt       = ca_default            # Subject name display option
     cert_opt       = ca_default            # Certificate display option
     copy_extensions = none                 # Don't copy extensions from request

     [ policy_any ]
     countryName            = supplied
     stateOrProvinceName    = optional
     organizationName       = optional
     organizationalUnitName = optional
     commonName             = supplied
     emailAddress           = optional

     [ 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             = US
     stateOrProvinceName     = California
     localityName            = Half Moon Bay
     0.organizationName      = ca-zephyr.org
     commonName              = CA Zephyr Org
     emailAddress            = bill@ca-zephyr.org

     [ v3_ca ]
     subjectKeyIdentifier   = hash
     authorityKeyIdentifier = keyid:always,issuer:always
     basicConstraints       = CA:true

Execute the command:

    openssl req -nodes -config conf/openssl.conf -days 7300 -x509 -newkey rsa:2048 -out public/root.pem -outform PEM

Sign a Digital Certificate

  • Make a place to hold signed keys and create initial overhead structures.

      mkdir /opt/cert-authority-zephyr/newcerts
      echo "01" > /opt/cert-authority-zephyr/conf/serial
      touch /opt/cert-authority-zephyr/conf/index
    
  • Sign a certificate using the command:

      openssl ca -config /opt/cert-authority-zephyr/conf/openssl.conf \
                 -in /opt/a_checkouts/servers/common/etc/ssl/csr/?.csr \
                 -out /opt/a_checkouts/servers/common/etc/ssl/certs/?.pem
      openssl ca -batch -config conf/openssl.conf -in request.csr -out request.cert
    

Using MySQL with ssl

Shamelessly copied from http://www.waterlovinghead.com/MysqlSSL.

Make sure your MySQL has ssl support

To check:

SHOW VARIABLES LIKE '%ssl%';

If have_ssl or have_openssl says NO, you don't have ssl support. If it says DISABLED, you have ssl support. On freebsd, you can recompile MySQL with ssl support via ports. Simply go to the port directory and do make WITH_OPENSSL=YES install clean

From MySQL's doc, one should check ssl support with the command. The following tells you ssl support is absent.

    shell> mysqld --ssl --help
    060525 14:18:52 [ERROR] mysqld: unknown option '--ssl'

Creating the certificates

Generate a CA certificate

    shell> openssl genrsa 2048 > ca-key.pem
    shell> openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem

Create a server certificate

    shell> openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem
    shell> openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

Create a client certificate

    shell> openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem
    shell> openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

Editing MySQL Configuration

Edit your .my.cnf and add:

    ssl-ca=/var/db/mysql/ca-cert.pem
    ssl-cert=/var/db/mysql/client-cert.pem
    ssl-key=/var/db/mysql/client-key.pem

Edit you my.cnf file adding the following and then restart the server.

    [mysqld]
    ssl-ca=/var/db/mysql/ca-cert.pem
    ssl-cert=/var/db/mysql/server-cert.pem
    ssl-key=/var/db/mysql/server-key.pem

Testing the Configuration

When a connection is established, you can check your connection by

    mysql> \s
    --------------
    mysql  Ver 14.12 Distrib 5.0.22, for redhat-linux-gnu (i686) using readline 5.0

    Connection id:          8
    Current database:
    Current user:           root@192.168.18.198
    SSL:                    Cipher in use is DHE-RSA-AES256-SHA
    Current pager:          stdout
    Using outfile:          ''
    Using delimiter:        ;
    Server version:         5.0.37
    Protocol version:       10
    Connection:             192.168.18.192 via TCP/IP
    Server characterset:    latin1
    Db     characterset:    latin1
    Client characterset:    latin1
    Conn.  characterset:    latin1
    TCP port:               3306
    Uptime:                 53 min 36 sec

    Threads: 2  Questions: 8  Slow queries: 0  Opens: 12  Flush tables: 1  Open tables: 6  Queries per second avg: 0.002
    --------------

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA | 
    +---------------+--------------------+
    1 row in set (0.01 sec)