SSL

From SlackWiki
Jump to: navigation, search

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!

  1. 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
    
  2. 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
or
openssl 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