Setting up an SSL server with the Fermilab apache product

To setup your server to serve pages both securely and non-securely you need to:
  1. create a certificate for your server
  2. update your webserver configuration
  3. update your .htaccess files or access.conf files to require SSL as needed.

Creating a certificate for your server

First you will need the openssl software.

  setup upd
  upd install -G -c openssl
  setup openssl
Then there are several steps to create a key for a webserver. If you have multiple webservers, each on their own IP, you should create a separate key for each one.

If you have multiple webservers on one IP, (i.e. via NamedVirtualHost directives, etc.) you need to make one for that group of webserver, with a Common Name (see below) that matches all of them; for example if you have fred1.fnal.gov, fred2.fnal.gov and fred3.fnal.gov you could use a Common Name of "fred[123].fnal.gov" which would match all three (as a "glob" pattern, as in it would match them if they were filenames).

Step one - create the key and request:

You probalby want to do this in the directory where you eventually want to keep the keys, then you don't have to move them around.

[For this section you want a copy of simple.cnf if you're going to get a DOEGrid signed certificate; otherwise you can omit the "-config simple.cnf" arguments, below.]

I reccomend if your webserver has config files in /foo/bar/conf that you do this stuff in /foo/bar/cert.


  openssl req -config simple.cnf -new > new.cert.csr
(If you get an error about random number seeding, you can do:

  openssl rand -rand /tmp/ps_data 100 > /dev/null
to get the random number seed setup, and then retry...),

It will ask you several questions to fill out the request.

The main thing to remember here is that the "Common Name" in the request needs to be the name of the webserver, or (i.e the name part in http://name:port/whatever).

This looks something like:

 openssl req -config simple.cnf -new > new.cert.csr
Using configuration from /fnal/ups/prd/openssl/v0_8_0/SunOS-5/lib/openssl.cnf
Generating a 1024 bit RSA private key
.........+++++
....+++++
writing new private key to 'privkey.pem'
Enter PEM pass phrase: pick something
Verifying password - Enter PEM pass phrase: pick something
-----
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) [AU]:US
State or Province Name (full name) [Some-State]:Illinois
Locality Name (eg, city) []:Batavia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Fermilab
Organizational Unit Name (eg, section) []:Operating System Support Department
Common Name (eg, YOUR name) []:www-oss.fnal.gov
Email Address []:mengel@fnal.gov

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

If you need to make a more complicated Certificate Signature Request (i.e. one good for several virtual hosts), it can be helpful to rename and update "simple.conf" file, and pass it to the "openssl req" command above, to make sure you get everything spelled right, etc. Saving that .conf file in the same directory with the other files makes it easy to use again. For example, this file is setup for two virtual hosts, and with the right answers for other questions filled in as the default -- currently doing 2 virtual hosts takes 3 Common Names, with the first being a wildcard matching the other 4 (which Netscape, and Mozilla will use) and the later 4 will be used by Internet Explorer to match the multiple virtual hosts. To use such a file, just do

 openssl req -config ./multi.cnf -new > new.cert.csr
and you can just hit return at all the prompts to make the new request. (Note: you may be tempted to try to change the commonNameMax values to a longer length to make a bigger wildcard; this won't actually work...)

Step two - remove the passphrase from the key:

This will prompt for the pass phrase you used in the previous section.

  openssl rsa -in privkey.pem -out new.cert.key

Step three - convert request into signed cert:

There are three options here
  1. Self-sign the certificate:
    This looks like:
    
       openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 365 -set_serial 2
       Signature ok
       subject=/C=US/ST=Illinois/L=Batavia/O=Fermilab/OU=Operating System Support 
        Department/CN=www-oss.fnal.gov/Email=mengel@fnal.gov
       Getting Private key
    
    Note the recently added '-set_serial' flag -- recent versions of Firefox complain if a site's self-signed certificate is updated but has the same serial number as it used to. So set the serial number higher than last time each time you sign a certificate.
  2. get a DOEGrid certificate You then get a request ID that you can use to download your certificate, usually the next business day.
  3. Request a signed certificate from elsewhere:
    Fermilab folks can request a certificate be signed by going to this form and pasting in the new.cert.csr file.
The mod_ssl directives that you need to use the resulting cert are:

  SSLCertificateFile /path/to/certs/new.cert.cert
  SSLCertificateKeyFile /path/to/certs/new.cert.key

For more details on the commands and options used above, you might look at:

Updating your configuration

You probably want to add a bit of configuration to your apache server's httpd.conf, like the following, which In my example, I have both of them using the same configuration, but you could of course serve something different in each.

Listen my-server.fnal.gov:80
Listen my-server.fnal.gov:443

<VirtualHost my-server.fnal.gov:80>
 SSLDisable
 Include conf/srm.conf
 Include conf/access.conf
</VirtualHost>

<VirtualHost my-server.fnal.gov:443>
 # this is SSLEnable in apache 1.x
 SSLEngine on
 SSLVerifyDepth 10
 SSLCertificateFile /fnal/www/cert/new.cert.cert
 SSLCertificateKeyFile /fnal/www/cert/new.cert.key

 Include conf/srm.conf
 Include conf/access.conf
</VirtualHost>

Configure pages to require SSL

You can now configure pages to require secure access, with directives like:
SSLRequireSSL
In a <Directory> directive or .htaccess file will require that SSL be used when accessing that area
SSLRequire expression
lets you write all manner of requirements for access related to the client, any client certificates, etc, like:
SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
For details, see the mod_ssl reference manual .
More information is avaliable at http://www.modssl.org/.

Setting up to allow Kerberos/kx509 authentication

This section assumes you have already setup a working SSL server per the previous sections on this page. To setup to take advantage of the Fermilab kx509 package, you need the following: And then you can use, in .htaccess files, entries like:
SSLRequireSSL
SSLVerifyClient optional
SSLOptions +StdEnvVars
SSLRequire  %{SSL_CLIENT_S_DN} =~ m/:(dane|mengel|schmidt)$/ && \
    %{SSL_CLIENT_I_DN} eq \
	"/DC=gov/DC=fnal/O=Fermilab/OU=Certificate Authorities/CN=Kerberized CA HSM"
More information is avaliable at http://www.modssl.org/.