SSL
openSSL 0.9.8e
IMPORTANT: Since this version has a bug in the blowfish encryption it is recommended not to use blowfish since it is incompatible with all other openSSL versions!
Everything you read here was tested on Slackware 12
- wikipedia says about openSSL
- OpenSSL is an open source implementation of the SSL and TLS protocols. The core library (written in the C programming language) implements the basic cryptographic functions and provides various utility functions. Wrappers allowing the use of the OpenSSL library in a variety of computer languages are available.
There are many ways to use openSSL. This just covers certificates for use with httpd. You can also use easy-rsa that comes with the openVPN package and can be found in /usr/doc/openvpn-2.0.9/easy-rsa/. For more information read the included README or look here: A Guide to basic RSA Key Management. Normally you will make a Certificate Signing Request (CSR) and send this one to a Certifying Authority (CA) to be signed. But since we don't wanna pay for this and only want to use it for our own special purpose, we don't need to do that and sign everything ourself.
openSSL + httpd
Switch to /etc/ssl
cd /etc/ssl
In this directory you should see the following listing. One some non-Slackware linuxes, or if OpenSSL was installed from source, the appropriate directory might be /etc/openssl.
root@pecan:/etc/ssl# ls -l total 24 drwxr-xr-x 2 root root 4096 2007-06-13 12:40 certs/ drwxr-xr-x 2 root root 4096 2007-06-13 12:40 misc/ -rw-r--r-- 1 root root 9374 2007-06-13 12:40 openssl.cnf drwxr-xr-x 2 root root 4096 2007-06-13 12:40 private/ root@pecan:/etc/ssl#
We need to generate a private and public RSA key file. The public key is used to encrypt messages to you and is distributed with your certificate.
Creating a Self-Signed Certificate (CRT)
openssl.cnf + openSSL DB
(You should still do this step even if you are buying a commercial certificate.) First things first, so we gotta edit this file, mainly the [ CA_default ] section. The
[ CA_default ] dir = ./demoCA # Where everything is kept ... certificate = $dir/cacert.pem # The CA certificate ... crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key ...
to
[ CA_default ] dir = /etc/ssl # Where everything is kept ... certificate = $dir/certs/ca.crt # The CA certificate ... crl = $dir/crl/ca.crl # The current CRL private_key = $dir/private/ca.key # The private key ...
You can even change more options in this file but be aware what you are doing.
openSSL has a database for storing information such as Certificate Revocation Lists (CRL). Since these files don't exist on startup and we don't use the CA.sh or CA.pl scripts we got to create them ourself:
mkdir newcerts certs crl private touch serial index.txt crlnumber crl/ca.crl echo 01 | tee serial | tee crlnumber | Tee crl/ca.crl
Thanks to alienBOB. Hail to tee king! :p
You will need to create your CRL file in correct PEM format
openssl ca -config /etc/ssl/openssl.cnf -gencrl -out /etc/ssl/crl/ca.crl
You can test that the crl file is correct with the command:
openssl crl -text -in /etc/ssl/crl/ca.crl -noout
Becoming a Certification Authority (CA)
(Skip this step if you are buying a certificate from a commercial certificate authority such as GoDaddy.) Before you can create and sign your own certificates, you first have to establish yourself as a "Certificate Authority". To do so, we first create our key file (with a public and a private key) and use it to create our "master certificate" to use when signing other certificates.
- Generate the CA RSA Key (Triple-DES encrypted and PEM formatted)
openssl genrsa -des3 -out private/ca.key 4096
- Create the CA CRT with the CA RSA Key
openssl req -new -x509 -days 3650 -key private/ca.key -out certs/ca.crt
Create Server CRT
A CRT contains your RSA public key, your name, the name of the CA, and is digitally signed by the CA. Browsers that know the CA can verify the signature on that CRT, thereby obtaining your RSA public key. That enables them to send messages which only you can decrypt. The next step is to create a Server RSA key, generate a Certificate Signing Request (CSR) out of it and sign it with our CA CRT to get a working SSL CRT for our server. A CSR is a digital file which contains your public key and your name. Normally you would send the CSR to a CA, who will convert it into a real certificate, by signing it.
- Generate the Server RSA Key (Triple-DES encrypted and PEM formatted)
openssl genrsa -des3 -out private/server.key 1024
- Create the Server CSR using the Server RSA Key
- When asked for the CommonName (CN) enter your domain!
openssl req -new -key private/server.key -out private/server.csr
- Sign the CSR with our CA CRT
openssl ca -in private/server.csr -out certs/server.crt
You can now delete server.csr if you want, because it is no longer needed.
(If you are using a commercially signed certificate from a place such as GoDaddy, do the first two commands above but not the last. Then do cat private/server.csr to get the text of the certificate request, which you will paste into GoDaddy's web interface to get the certificate. GoDaddy will then email the email address listed in the whois information for that domain (Make sure you haven't put in a fake address there to avoid spam!), and after the link in that email is clicked, GoDaddy will email another link to you from which you download a zip file.
The zip file will contain two .crt files, and you should put both of them in /etc/ssl/certs. Other commerical certificate authorities follow a very similar procedure.)
Setup httpd
Edit httpd.conf
The whole httpd config is located in /etc/httpd. Fire up your preferred text editor and simply change this at Line 459:
# Secure (SSL/TLS) connections #Include /etc/httpd/extra/httpd-ssl.conf
to this
# Secure (SSL/TLS) connections Include /etc/httpd/extra/httpd-ssl.conf
to enable SSL support.
You may also have to uncomment the line that starts LoadModule ssl_module.
Edit extra/httpd-ssl.conf
Now we're going into the guts of the httpd SSL config. Search for SSLCertificateFile and SSLCertificateKeyFile change the path to our newly created CRT:
... SSLCertificateFile /etc/ssl/certs/server.crt ... SSLCertificateKeyFile /etc/ssl/private/server.key ... SSLCertificateChainFile /etc/ssl/certs/server.crt ... SSLCACertificatePath /etc/ssl/certs SSLCACertificateFile /etc/ssl/certs/ca.crt ... SSLCARevocationPath /etc/ssl/crl SSLCARevocationFile /etc/ssl/crl/ca.crl ...
(If you have purchased a certificate from a commercial authority, the SSLCertificateFile will be one of the two files you receive from the CA (GoDaddy or VeriSign or whomever), and the SSLCACertificateFile will be the other. The files will be named such that you can tell which is which -- the SSLCertificateFile will probably be something like www.yourdomainname.com.crt and the SSLCACertificateFile will be something like nameofca-bundle.crt.)
Pass-phrase on httpd startup
The reason this dialog pops up at startup and every re-start is that the RSA private key inside your server.key file is stored in encrypted format for security reasons. The pass-phrase is needed decrypt this file, so it can be read and parsed. Removing the pass-phrase removes a layer of security from your server - proceed with caution!
-
Remove the encryption from the RSA private key (while keeping a backup copy of the original file):
cd /etc/ssl mv private/server.key private/server.key.org cd private openssl rsa -in server.key.org -out server.key
-
Make sure the server.key file is only readable by root since it is decrypted:
cd /etc/ssl chmod 0400 private/server.key
Now server.key contains an unencrypted copy of the key. If you point your server at this file, it will not prompt you for a pass-phrase. HOWEVER, if anyone gets this key they will be able to impersonate you on the net. PLEASE make sure that the permissions on this file are such that only root or the web server user can read it (preferably get your web server to start as root but run as another user, and have the key readable only by root).
As an alternative approach you can use the SSLPassPhraseDialog exec:/path/to/program facility. Bear in mind that this is neither more nor less secure, of course.
Verifying and debugging
If you simply want to see every information on a CRT:
openssl x509 -noout -text -in XXX.crt
Verifying
- Verify that a private key matches its Certificate
- Generate a MD5 out of the public key/CRT and compare
openssl x509 -noout -modulus -in private/XXX.crt | openssl md5 && openssl rsa -noout -modulus -in private/XXX.key | openssl md5
Debugging
- s_server - Debugging clients
openssl s_server -accept 443 -www
- s_client - Debugging servers
openssl s_client -connect localhost:443
oropenssl s_client -connect localhost:443 -state -debug
Security
All the files expect the CRTs are only for your eyes, so we change the permissons:
chmod 0400 private/*.key
Client Revokation
This is only needed if your server certificate is compromised (eg. someone hacked your server and stole your server.key).
openssl ca -gencrl -keyfile private/ca.key -cert certs/ca.crt -out crl/ca.crl
That generated us the needed files which we use when we want to revoke a CRT.
Now that we got a compromised CRT, we got to get rid of it:
openssl ca -revoke certs/server.crt -keyfile private/ca.key -cert certs/ca.crt
Other
Change the pass-phrase
openssl rsa -des3 -in server.key -out server.key.new mv server.key.new server.key
The first time you're asked for a PEM pass-phrase, you should enter the old pass-phrase. After that, you'll be asked again to enter a pass-phrase - this time, use the new pass-phrase. If you are asked to verify the pass-phrase, you'll need to enter the new pass-phrase a second time.
CRT for Clients
Ok.. i won't write anything on this, and simply just C/P:
openssl genrsa -des3 -out private/client1_priv.key 2048 openssl genrsa -des3 -out private/client2_priv.key 2048 # and so on... depends on how much clients you wanna serv... openssl req -new -key private/client1_priv.key -out private/client1.csr openssl req -new -key private/client2_priv.key -out private/client2.csr # and so on... openssl ca -in private/client1.csr -out private/client1.crt openssl ca -in private/client2.csr -out private/client2.crt cp private/client1.crt private/client1_preconv.crt cat private/client1.key >> private/client1_preconv.crt openssl pkcs12 -export -in private/client1_preconv.crt -out private/client1_postconv.p12
Install in the clients browser... and change httpd.conf:
SSLCACertificateFile PATH/TO/server.crt SSLVerifyClient require SSLVerifyDepth 1
Convert CRT from PEM to DER format
Normally all CRTs are stored in the PEM format.
openssl x509 -in ca.crt -out ca.crt.der -outform DER
Testing the CRT
If you have live web sites, you might wish to test your configuration before restarting apache, to avoid having that panicy few minutes of downtime while you scramble to see what you can do faster, fix the problem or copy back your backup configs. Test like this:
httpd -t
Look at the error messages it prints out, or the error_log as explained below, if it doesn't work.
Restart your httpd:
/etc/rc.d/rc.httpd restart
Take a look at the httpd error_log and scroll to the end of the file:
jed /var/log/httpd/error_log
If your getting an error like this:
[error] Init: Unable to read pass phrase [Hint: key introduced or changed before restart?]
... then you should take a look at Pass-phrase on httpd startup ...
openSSL + openVPN
$foo ... maybe next month...
External Links
- SSL/TLS Strong Encryption: FAQ @ httpd.apache.org
- Creating a self-signed SSL certificate
- OpenSSL Command-Line HOWTO
- OpenSSL Quick Reference
- Setup Apache2 with OpenSSL
- Apache2, OpenSSL und HTTPS: Server- und Client-Authentifizierung mit Zertifikaten über verschlüsselte Internet-Verbindungen
- openSSL / openVPN.. comming soon