Lab 06 - SSL Certificates and Apache

        CAPRICORN (Dec 23 - Jan 19)
		  You are conservative and afraid of taking risks.  You don't do much of
		  anything and are lazy.  There has never been a Capricorn of any
		  importance.  Capricorns should avoid standing still for too long as
		  they take root and become trees.

Overview

You will be creating an SSL certificate request that will be signed by the authority (Chris), which in turn will become a (sorta) valid SSL certificate to be used on the web. You will also be configuring Apache to load your SSL certificate for secure communication to your webserver. You will also be doing some other configurations in Apache to restrict access to directories from certain IP addresses, performing redirects to ensure SSL communication to certain web pages, as well as allowing users to have their own web directories. Let's get crackin'!

Credit for a good portion of this lab goes to Phil Jones, who fought long and hard last year to figure out this configuration.

All of the information in this lab was built from the following websites:
http://www.howtoforge.com/perfect_setup_ubuntu_5.10_p5
http://www.ubuntuforums.org/archive/index.php/t-4466.html
http://www.thawte.com/ssl-digital-certificates/technical-support/apache_install.html
http://attic.krampo.info/2006/01/31/howto-enable-mod_rewrite-apache2-ubuntu/

Tasks and Grading

This lab is due at 5:05pm, Thursday March 22nd, 2007.

You must complete all the following tasks for this lab. Each item is worth one (1) point.

Part 1 - Creating a Certificate Signing Request (CSR)

  1. Create an RSA private key. This will be used to generate your CSR. Enter in a passphrase for your key (you can remove this later if you want). Check out in the clarifications section how to remove a passphrase. If you leave the passphrase on the key, you will have to type it in *every single time you restart your web server*, which would suck. You need to protect this key with your life! If other people get it, they can pose as you!
    chris@coolname:~$ openssl genrsa -aes128 -out privkey.pem 1024
    Generating RSA private key, 1024 bit long modulus
    ................++++++
    ...............................++++++
    e is 65537 (0x10001)
    Enter pass phrase for privkey.pem:
    Verifying - Enter pass phrase for privkey.pem:
    
    chris@coolname:~$
    
  2. Now that you have your key generated, you can create a CSR. A critical piece that you MUST get correct in this part is that the 'COMMON NAME' field MUST be the fully-qualified domain name of your machine, and NOT your actual name!! When you create your CSR, be sure that the name of your .pem file matches the pattern <machine name>-csr.pem. Enter the information exactly as I have it below, except where your machine name or your email address applies. Also leave the last two 'extra attribute' questions blank. My test machine is 'coolname'.
    chris@coolname:~$ openssl req -key privkey.pem -new -out coolname-csr.pem
    Enter pass phrase for privkey.pem:
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [GB]:US
    State or Province Name (full name) [Berkshire]:Colorado
    Locality Name (eg, city) [Newbury]:Boulder
    Organization Name (eg, company) [My Company Ltd]:University of Colorado
    Organizational Unit Name (eg, section) []:Department of Computer Science - Sysadmin Class
    Common Name (eg, your name or your server's hostname) []:coolname.cs.colorado.edu
    Email Address []:schenkc@colorado.edu
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    chris@coolname:~$
    
  3. Now that you have your CSR (i.e. coolname-csr.pem), email it to me so I can sign the request so you will have a (semi) valid SSL Certificate to use on your server.
  4. Once you get your brand spankin' new signed certificate, the first thing you should do is verify that I have really signed your certificate, and not some fake person posing as me. To do that you need to download the CA root certificate and verify that I signed your cert. To do this you need to run the openssl verify command. It's quite simple:
    chris@coolname:~$ openssl verify -CAfile saclass-cacert.pem coolname-cert.pem
    coolname-cert.pem: OK
    

Part 2 - Configuring SSL in Apache

  1. Install the 'apache2' package. The files for Apache under Ubuntu exist under /etc/apache2. There are a couple of configuration files in that directory, /etc/apache2/apache2.conf, /etc/apache2/httpd.conf, and a few directories, mods-enabled, sites-available, etc.
  2. Create two firewall rules to allow incoming queries to destination TCP ports 80 and 443.
  3. Download the CA certificate, copy your private key file and newly signed SSL certificate to your apache2/ssl directory, and set ownership and permissions properly:
    % sudo cp coolname-cert.pem /etc/apache2/ssl
    % sudo cp coolname-privkey-nopass.key /etc/apache2/ssl
    % cd /etc/apache2/ssl
    % wget http://www.cs.colorado.edu/~schenkc/saclass-cacert.pem
    % sudo chown www-data:www-data coolname-cert.pem coolname-privkey-nopass.key saclass-cacert.pem
    % sudo chmod 400 coolname-privkey-nopass.key
    
  4. Enable the SSL module with the following command:
    chris@coolname:/etc/apache2$ sudo a2enmod ssl
    Password:
    Module ssl installed; run /etc/init.d/apache2 force-reload to enable.
    chris@coolname:/etc/apache2$ sudo /etc/init.d/apache2 force-reload
     * Forcing reload of apache 2.0 web server... 
    
    This command actually creates two symbolic links so apache will actually load the SSL module.
    • /etc/apache2/mods-enabled/ssl.conf -> /etc/apache2/mods-available/ssl.conf
    • /etc/apache2/mods-enabled/ssl.load -> /etc/apache2/mods-available/ssl.load
  5. Edit the /etc/apache2/ports.conf file and add "Listen 443" (without quotes).
  6. Create a copy of the default site configuration file to be your SSL configuration file:
    chris@coolname:/etc/apache2$ sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl
    
  7. Create a symbolic link of your new SSL site configuration so that it's loaded by Apache:
  8. chris@coolname:/etc/apache2$ sudo ln -s /etc/apache2/sites-available/ssl /etc/apache2/sites-enabled/ssl
    
  9. Edit the sites-enabled ssl file that you just created to accept ssl requests. The /etc/apache2/sites-available/ssl file should be changed to look like the following:
    NameVirtualHost *:443
    <VirtualHost *:443>
    
    (... the rest of the file is fine as is ...)
    (... if you want different directories then configure those too ...)
    
  10. Edit the sites-enabled default file to be used for non-secure requests. The /etc/apache2/sites-available/default should look like this:
    NameVirtualHost *:80
    <VirtualHost *:80>
    
    (... once again the rest of the file is fine as is ...)
    (... if you want different directories then configure those too ...)
    
  11. Now you need to edit /etc/apache2/sites-available/ssl within the VirtualHost section to reference your specific SSL certificate you obtained in part 1. For 'coolname', I'd use my cert and my unprotected private key file:
    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/coolname-cert.pem
    SSLCertificateKeyFile /etc/apache2/ssl/coolname-privkey-nopass.key
    SSLCACertificateFile /etc/apache2/ssl/saclass-cacert.pem
    

    The 'KeyFile' is the file that contains your PRIVATE key! Remember I mentioned before that if you leave the passphrase on your key, you'd have to type it in every time you start your web server, and this is why. You configure the server to have your private key, and if it's not openly readable, you have to be there.

  12. Now restart your Apache server and test access to your machine via ssl. I would be testing https://coolname.cs.colorado.edu. When my browser first sees the certificate on my machine, I am prompted to accept the certificate from an 'unknown authority'. to avoid this warning in the future, I simply import the saclass-cacert.pem CA certificate into the browser. In Firefox, this is under:
    Edit-Preferences
       -Advanced-Security-View Certificates
       -Authorities-Import-saclass-cacert.pem
       -Open and check the "Allow to identify web sites" box.
    

Part 3 - Configuring Other Things in Apache

  1. Create a directory under your webserver DocumentRoot called 'internal'. The way this directory would be accessed would be the following for my machine 'coolname': http://coolname.cs.colorado.edu/internal/.
  2. Add in the 'rewrite' module using a2enmod like we did above.
  3. Create a rewrite rule in your /etc/apache2/sites-available/default configuration file that will always redirect people to HTTPS if they try to access the '/internal' directory created above.
  4. Make this '/internal' directory only accessible by people on the 128.138.202.0/24 and 128.138.242.192/26 subnets. To do this, you will be using the '<Directory ...>' directive.
  5. Create a simple index.html file that will sit in your DocumentRoot directory with some sort of joke in it.
  6. Create another index.html that will sit in your 'internal' directory that says, "If you aren't supposed to see this, then bloody bugger off!"

Clarifications

How to remove the passphrase on your private key

I mentioned in class that your private key is protected with a symmetric block cipher who's symmetric key is generated from your passphrase. So that way if anyone actually steals your private key file, they cannot actually read it and pose as you. If we were running a real website that needed to be secure, we'd most likely leave our key protected. However, since we're in class and typing in a passphrase is annoying as hell, we're going to remove it.

The following information has been provided by Aaron Bach for how to remove the passphrase on your key. The idea is simple, just read your key with your passphrase and save the output to a different file:

  1. First, back up your private key file (just so you don't overwrite it somehow). In this example, we'll be using 'coolname-privkey.pem':
    chris@coolname:~/rsa$ cp coolname-privkey.pem coolname-privkey.pem.bak
    
  2. Now, open your key to view it and save it to another file:
    chris@coolname:~/rsa$ openssl rsa -in coolname-privkey.pem -out coolname-privkey-nopass.key
    Enter pass phrase for coolname-privkey.pem:
    writing RSA key
    
  3. Make sure the new key is ONLY readable by the owner of the file once you copy it to your webserver directory (in Part 2.3). You don't want random people to see your private key!
    % chmod 400 coolname-privkey-nopass.key
    

Notice that we have a different extension on the new key file. This is because it is no longer PEM encoded, and is simply the plain text of our private key. You can use this key in Part 2.10 in your server configuration.

Debugging your Apache config

As always, you can look at the log files, and those exist under /var/log/apache2.

The Chain of Certificate Authorities

This write-up has been provided by Nate Watkins from class, which describes how certificate chaining works. I did not know about this myself until Nate explained it to me, it's pretty cool stuff.

"Hey Chris. A few things from our class the other day..."

To get to the Certificates through Windows OS.
"Control Panel -> Internet Properties -> Content Tab -> Click Certificates button."
There is a chain of certificates.

"The certificate authority provides a few certificates in the chain. They have a root certificate which has it's private key practically locked in a vault and you can't get to it anywhere from the internet. The root cert belongs to the CA (e.g. Verisign). They use the private key of the root CA and sign a second certificate. A partition certificate. They have many partition certificates and how they choose to delegate them to different people is beyond me and the scope of this email ;) . The CA finally has a third certificate. Which is the product certificate. So for a web certificate you would get the web certificate product. This is the certificate you are receiving when you purchase a certificate. The product certificates are signed by the associated partition that they delegate for that product or (maybe partition is based on geographic region). You buy a product cert that specifies what it is legitimate for. Web certs are going for as low as $100 these days. You can get certificates for server authentication and client authentication as well. There is data associated with the product that mandates what you can do with it. You can also buy a product cert that lets you create some number of trusted certs for mucho $$. Finally you create your cert using openssl or whatever, and verasign will do all the mumbo jumbo checking out your company and if you are legit they will sign your cert using the private key of the product cert you buy.

"Your web browser will verify all of the signatures in the chain, starting with Root. Your system needs to have all three certs provided by the certificate authority. The purpose of this huge chain is for security once again. What you get when you invest into a trusted certificate authority is guarantee that if a key gets hacked, they will no longer validate that cert and your website or whatever is responsible for getting your cert resigned by a new valid certificate (and of course you wouldn't have to pay again). The chain is supposed to preserve security for the ROOT. If root gets hacked we're all fucked. All certificates would be invalid, and they would have to resign the entire chain, which means they would have to re-sign every client. If a product cert gets hacked it is less of a big deal though. An invalid cert will not get accepted, but I am not sure how the browser knows it's invalid. It would seem as though it goes to the trusted server and finds out the valid product, root, and partition cert. I have provided a diagram so you can see pictorally how the signing works."