How to generate your own certificates for SSL/TLS applications

If you, like me, have your own IMAP/POP/WWW/SMTP server running you may wish to provide secure access to it from a remote location (I'd say you'd be dumb not to..). Most of these programs either nativley support SSL/TLS or can be easily wrapped to do so (eg stunnel). The other part of the problem is how to generate a suitable key for use with these programs. I can't afford to buy them from a conventional key authority, and it would be fairly pointless since I don't need anyone but myself to trust the key.

Starting off

Create a directory where you are going to work, eg ~/certificates. Now copy the openssl.cnf file into it (probably in /etc/ssl or /usr/local/openssl). Edit the file to hold defaults you want to save on typing. You need to setup a few other files like so..
mkdir ~/certificates
cd ~/certificates
cp /etc/ssl/openssl.cnf .
vi openssl.cnf
echo 01 >serial
touch index.txt
mkdir newcerts

Making a Certificate Authority key

Now you need to create a key that will be used to sign other keys. This has the advantage that you only need to add one key to client machines (this one) and any keys you sign with it will be automatically trusted. To do this run the following command
openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf -days 3650
When asked for the common name specify "Foo Bar CA" (or whatever you want it called). The -days argument controls how long until the key expires. You will end up with two files ca.key which contains the private part of the key encrypted with the passphrase it asked for, and ca.crt which is the public part you tell other systems to trust.

Getting systems to trust your key

Now that you have made your CA key you can add it to other machines certificate stores. For OpenSSL using systems you need to put it in /etc/ssl/certs and make a symlink like so..
mkdir /etc/ssl/certs
cd /etc/ssl/certs
cp ~/certificates/ca.crt .
ln -s ca.crt `openssl x509 -hash -noout -in ca.crt `.0
chmod 555 .
chmod 444 *
For MS Windows you need to go into the Control Panel then Internet Options, then select the Content tab and import the key. It will ask you to verify the key is correct and you can check this by running..
openssl x509 -noout -in ca.crt -sha1 -fingerprint
Note that using the -text option will give you more information about the key as well.

Generating a server key

The next step is to generate a server key, then it must be signed with with the CA cert. Firstly we generate the key...
openssl genrsa -out server.key
Now we must create a signing request file from the server key...
openssl req -new -key server.key -out server.csr -config openssl.cnf
Note that the common name should be the hostname of the service, eg mail.foo.com, www.bar.net etc. Lastly we sign the server key with the CA key
openssl ca -cert ca.crt -keyfile ca.key -config openssl.cnf -out server.crt -infiles server.csr
Once this is done you will have the 2 files you need for your server - server.key is the private key you must keep secret, and server.crt which is the public part.

Configuring Sendmail

Once you have generated your keys you can configure the various applications that use them. For sendmail you need to modify the .mc file like so...
define(`confCACERT_PATH', `/etc/mail/certs')dnl
define(`confCACERT', `/etc/mail/certs/ca.crt')dnl
define(`confSERVER_CERT', `/etc/mail/certs/sendmail.crt')dnl
define(`confSERVER_KEY', `/etc/mail/certs/sendmail.key')dnl

# Enable SMTPS
DAEMON_OPTIONS(`Name=smtps,Port=smtps, Modifiers=s')

DAEMON_OPTIONS(`Name=smtp,Port=smtp')
This will open port 25 and port 465 and tell sendmail to look in /etc/mail/certs for certificates. You need to make a symlink as per the CA instructions previously, eg..
mkdir /etc/mail/certs
chmod 700 /etc/mail/certs
cd /etc/mail/certs
cp ~/certificates/sendmail.crt .
cp ~/certificates/sendmail.key .
cp ~/certificates/ca.crt .
ln -s ca.crt `openssl x509 -noout -hash < ca.crt`.0
Now rebuild the .cf file, install it and restart sendmail. You should now be able to connect to it and use TLS or via SSL.

Configuring Apache

You must install mod_ssl (or build Apache with SSL support) and modify the configuration to add SSL directives that point to the correct locations on your system. Similarly to sendmail you just need to copy the server.key and server.crt files into the appropriate locations and restart the server. Make sure the permissions are tight on the ssl.key directory - make sure root can read it and noone else!

Configuring Cyrus

I used a single certificate for all Cyrus services, hence I used the tls_cert_file and tls_key_file directives. Ensure that the files are in a safe place (eg /usr/local/cyrus) and that they are owned by the cyrus user and have 0600 permissions.
Daniel O'Connor
Last modified: Tue Jul 19 16:29:15 CST 2005