We use a self-signed https certificate for our server, and they expire every year or so. When they do, and you visit a page using https, you see something like:
So, we have to renew or re-create the certificate. I think I succeeded in writing a script to do this, namely “server-certificate” (poor name), which is a wrapper for genkey.wc, which is a wellesley modification of an older genkey script from RedHat. But, apparently, that’s obsolete, and the genkey.wc script doesn’t run.
I found the following: https://access.redhat.com/site/documentation/en-US/Red_Hat_Certificate_System/8.0/html/Admin_Guide/Renewing_Certificates.html. It seems to be on the right topic, but it’s incomprehensible to me. That page describes a choice between “re-generate” and “re-create,” and I think we want “re-generate.”
Ack, this makes no sense. I googled for various things like “RHEL 6 renew https certificate” and got nowhere. Eventually, I stumbled on http://superuser.com/questions/622434/can-self-signed-ssl-certificate-be-renewed-how which explained that you can’t renew a self-signed certificate, so I just need to create a new one, and I might as well give it a long expiration time. That may be easier.
Boy, it’s hard to find RHEL 6 documentation. Eventually, I found the following: https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html-single/Deployment_Guide/index.html#s2-apache-mod_ssl which seems to be trying to explain how to create SSL certificates for Apache.
The first substantive step I did was to install crypto-utils:
yum install crypto-utils
Aha! That installs the “genkey” command! Oh, but they’ve really changed the script:
[root@tempest tls] diff -bB /usr/bin/genkey /root/bin/genkey.wc | wc 1008 4500 31119 [root@tempest tls]
Oh well. Let’s just follow the instructions and not try to script this, yet.
genkey cs.wellesley.edu
That starts a GUI that prompts for the various pieces of information:
1. It informs me that the key will be stored in
/etc/pki/tls/private/cs.wellesley.edu
and the certificate will be stored in
/etc/pki/tls/certs/cs.wellesley.edu.crt
2. I chose the default 1024-bit key size. It then starts generating the keys, but it needs to collect some randomness, and, wow, that takes a long time. I think it’s been 5 minutes or more, and it’s only 75% done.
3. I said “no” to whether I want to send a certificate request (CSR) to a certificate authority (CA). That means I’ll get a self-signed certificate.
4. I skipped having a passphrase, to make it easier for apache to start up at boot time (or whatever) without having to give a passphrase.
5. Finally, I get to put in the data about our server:
Country Name: US State or Province: Massachusetts Locality: Wellesley Organization Name: Wellesley College Organizational Unit: Computer Science Department Common Name: cs.wellesley.edu
That finishes the job and the program exited.
Next, I restarted the web server:
apachectl graceful
and re-tried the https connection. Hmm. No luck.
I ran /etc/cron.daily/certwatch and it generated an email saying that the certificate had expired and explicitly said the certificate was in /etc/pki/tls/certs/localhost.crt. So if I just alias (via ln) the localhost files to the cs.wellesley.edu files, that should work:
cd /etc/pki/tls/certs/ [root@tempest certs] pwd /etc/pki/tls/certs [root@tempest certs] mv localhost.crt localhost.crt.old [root@tempest certs] ln cs.wellesley.edu.crt localhost.crt [root@tempest certs] cd ../private/ [root@tempest private] ls -l *.key -r--------. 1 root root 937 Jan 26 18:44 cs.wellesley.edu.key -rw-------. 1 root root 887 Aug 15 2012 localhost.key [root@tempest private] mv localhost.key localhost.key.old [root@tempest private] ln cs.wellesley.edu.key localhost.key [root@tempest private] apachectl graceful [root@tempest private]
And re-try the web connection…. In Chrome, I still get all kinds of warnings, with no good way to say “add exception” but it *is* using the new certificate. Firefox is much better, allowing me to add an exception. However, the new certificate expires in one month! (2/26/2014). What the heck?!
More googling and frustration. Aha, I found this excellent post where all the steps seem to make a lot of sense: http://stevejenkins.com/blog/2010/08/renewing-a-self-signed-ssl-certificate-on-fedoracentos/
Furthermore, I found a nice script that fits well with that blog post, called make-dummy-cert, which is in the openssl package.
So, let’s first follow step 1 of Steve’s blog post:
[root@tempest certs] grep SSLCertificate /etc/httpd/conf.d/00_ssl.conf # Point SSLCertificateFile at a PEM encoded certificate. If SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateKeyFile /etc/pki/tls/private/localhost.key # Point SSLCertificateChainFile at a file containing the # the referenced file can be the same as SSLCertificateFile #SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt [root@tempest certs]
Okay, so that’s why I have to use “localhost” and not cs.wellesley.edu; fine. Let’s check the permissions, as Steve suggests:
[root@tempest certs] ls -l /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key -rw-rw----. 2 root root 995 Jan 26 18:44 /etc/pki/tls/certs/localhost.crt -r--------. 2 root root 937 Jan 26 18:44 /etc/pki/tls/private/localhost.key [root@tempest certs]
Okay, I can tighten those a bit.
Now, I’m going to modify step three, to put a wrapper around the openssl command, so that I don’t have to retype all that stuff each time. I based this wrapper on /etc/pki/tls/certs/make-dummy-cert. I’m going to copy that to /home/sysadmin/fixes and put the derivative script, make-wellesley-cert in the same directory.
I made some modifications to that script, reducing the number of bits to 1024 (per RedHat’s recommendations) and hard-coding the site info and filename locations. Here’s the finished script:
#!/bin/sh umask 077 answers() { echo US echo Massachusetts echo Wellesley echo Wellesley College echo Computer Science Department echo cs.wellesley.edu echo cs-sysadmin@wellesley.edu } name="localhost" key="/etc/pki/tls/private/$name.key" crt="/etc/pki/tls/certs/$name.crt" answers | /usr/bin/openssl req -newkey rsa:1024 -keyout $key -nodes -x509 -days 365 -out $crt 2> /dev/null ls -l $key $crt apachectl graceful
Okay, that seems to have worked. Woo-hoo! Thank you, Steve Jenkins!