Menu

Michael Gracie

Running a secure web server on your Leopard-powered Mac

This is not something most of you would want to do, but I’m in the midst of a project that requires SSL for testing purposes. My MacBook Pro serves as a primary communications center, research tool, and as the access interface to the blog blather you’re reading right now. Plus, it’s one hell of a development platform too. SSL is a big part of building secure web services, so I’m putting this forth just in case.

Quick note: this is a fairly detailed process, so take a firm hold of the wheel and be prepared for a lengthy ride. You are going to need your terminal and su access. You will be generating encryption keys and certificates, and editing Apache conf files, after the jump.


First, you need a certificate

I’ve become the OpenSSL guy in the family, so let’s get down to the dirty work. Here goes…

Step 1

Open up a terminal window, and su root. Then, cd over to your Documents directory. Add a new directory in there using mkdir and call it certs like so:

sh-3.2# mkdir certs

Then cd into it.

Type this command…

sh-3.2# /System/Library/OpenSSL/misc/CA.pl -newca

You’ll see a whole pile of stuff fly by, piece by piece:

CA certificate filename (or enter to create) (hit enter)

Making CA certificate ...
Generating a 1024 bit RSA private key
......++++++
...........++++++
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase:
[enter a passphrase]

Verifying - Enter PEM pass phrase: [enter the passphrase again]
-----
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]:
(hit enter)
State or Province Name (full name) [Some-State]:
(hit enter)
Locality Name (eg, city) []:
(hit enter)
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
(hit enter)
Organizational Unit Name (eg, section) []:
(hit enter)
Common Name (eg, YOUR name) []:
(type ‘yourname’)
Email Address []:
(type ‘yourname@yourname.com’)

You should now have a pile of directories and files that look like this:

~/Documents/certs/demoCA
~/Documents/certs/demoCA/cacert.pem
~/Documents/certs/demoCA/certs
~/Documents/certs/demoCA/crl
~/Documents/certs/demoCA/index.txt
~/Documents/certs/demoCA/newcerts
~/Documents/certs/demoCA/private
~/Documents/certs/demoCA/serial

Use ls to check. If so, good.

Step 2

Now you are going to generate a private key for your web server…stay in ~/certs and type…

sh-3.2# openssl genrsa -des3 -out secureserver.key 1024

A file should be created in ~/certs called secureserver.key, so you can choose any name you want but make it a good one – you’ll need to reference it later. This will pass the screen:

Generating RSA private key, 1024 bit long modulus
...++++++
.......................................++++++
e is 65537 (0x10001)
Enter pass phrase for secureserver.key:
(enter a passphrase)
Verifying - Enter pass phrase for secureserver.key:
(enter the passphrase again)

Step 3

Now we’ll create a non-password protected version of the same key:

sh-3.2# openssl rsa -in secureserver.key -out secureserver.nopass.key

The command will return this:

Enter pass phrase for secureserver.key: (enter the passphrase from step 2)
writing RSA key

You should now have another file called secureserver.nopass.key (or whatever you decided for the ‘secureserver’ name), in the ~/certs directory.

Step 4

Now we’ll create a certificate request, which should wind up as yet another file called newreq.pem. Stay in ~/certs, and…

sh-3.2# openssl req -config /System/Library/OpenSSL/openssl.cnf -new -key secureserver.key -out newreq.pem -days 3650

…and noting all that goes on one line before you hit enter. This is creating a cert request good for ten years, using that key (secureserver.key) you created in step 2.

Output will look like so:

Enter pass phrase for secureserver.key:
(enter the passphrase from step 2 again)
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]:
(hit enter)
State or Province Name (full name) [Some-State]:
(hit enter)
Locality Name (eg, city) []:
(hit enter)
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
(hit enter)
Organizational Unit Name (eg, section) []:
(hit enter)
Common Name (eg, YOUR name) []:
(type ‘yourname’)
Email Address []: (type ‘yourname@yourname.com’)

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

Check to make sure newreq.pem is in ~/certs, and then we’ll move on to signing that certificate request.

Step 5

Next, enter:

sh-3.2# /System/Library/OpenSSL/misc/CA.pl -signreq

Output…

Using configuration from /System/Library/OpenSSL/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
(enter a passphrase)
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number:
82:e1:99:21:c1:a8:de:66
Validity
Not Before: Mar 26 17:19:45 2009 GMT
Not After : Mar 26 17:19:45 2010 GMT
Subject:
countryName = AU
stateOrProvinceName = Some-State
organizationName = Internet Widgits Pty Ltd
commonName = yourname
emailAddress = yourname@yourname.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
B4:DC:51:EA:17:29:DD:3C:34:EC:6D:37:02:9E:44:C0:FE:71:88:1F
X509v3 Authority Key Identifier:
keyid:19:B0:82:96:E8:2C:E9:DC:B0:9D:5F:77:DD:F6:EB:31:90:9F:1C:50
DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=yourname/emailAddress=yourname@yourname.com
serial:82:E1:99:21:C1:A8:DE:65

Certificate is to be certified until Mar 26 17:19:45 2010 GMT (365 days)
Sign the certificate? [y/n]:
(hit ‘y’ then enter)

1 out of 1 certificate requests certified, commit? [y/n] (hit ‘y’, then enter)
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem

After signing, you should have all four files in the ~/certs directory…they are:

secureserver.key
secureserver.nopass.key
newreq.pem
newcert.pem

Very nice. You can park those files anywhere you like, but I’d suggest moving the entire certs directory under ~/Library/WebServer.

Off to Apache

Thank goodness Apple decided to update the Apache server in Leopard – I was getting mighty tired of digging around for version 1.3 implementation instructions. Apache 2.2 was a welcome upgrade. Further, the configuration files in the base install are almost ready to go – you need to add/change about a dozen lines total.

Step 6

Mose on over to /private/etc/apache2/extra and open up the httpd-ssl.conf file (you’ll need to have admin access for editing – I do this stuff in Xcode while logged in as root, but that’s otherwise your call). Scroll down to ‘Server Certificate’ and make sure the following lines are commented out:

#SSLCertificateFile "/private/etc/apache2/server.crt"
#SSLCertificateFile "/private/etc/apache2/server-dsa.crt"

Then add this line:

SSLCertificateFile "/Library/WebServer/certs/newcert.pem"

In the next config group, ‘Server Private Key’, comment out…

#SSLCertificateKeyFile "/private/etc/apache2/server.key"
#SSLCertificateKeyFile "/private/etc/apache2/server-dsa.key"

…and add…

SSLCertificateKeyFile "/Library/WebServer/certs/secureserver.nopass.key"

Again, under ‘Certificate Authority (CA)’, comment out…

#SSLCACertificatePath "/private/etc/apache2/ssl.crt"
#SSLCACertificateFile "/private/etc/apache2/ssl.crt/ca-bundle.crt"

…then add:

SSLCACertificateFile "/Library/WebServer/certs/demoCA/cacert.pem"

And one last time, under ‘Certificate Revocation Lists (CRL)’ you’ll comment out…

#SSLCARevocationPath "/private/etc/apache2/ssl.crl"
#SSLCARevocationFile "/private/etc/apache2/ssl.crl/ca-bundle.crl"

…and add:

SSLCARevocationPath "/Library/WebServer/certs/demoCA/crl"

Save and close, boys and girls, because you are almost home.

Step 7

Open up the httpd.conf file under /private/etc/apache2, then scroll all the way to the bottom where it says ‘Secure (SSL/TLS) connections’ and UNCOMMENT this line:

Include /private/etc/apache2/extra/httpd-ssl.conf

Now, the stock httpd.conf file should have the line that says…

LoadModule ssl_module libexec/apache2/mod_ssl.so

…already uncommented, but if there is a # in front of it take it out. Everything else in the Apache config file should be kosher.

Step 8

If you’ve gotten this far, you are probably going to want to do some editing to your hosts file, so you are hitting the URL locally. But, if you gotten this far you probably don’t need me to tell you how to do that either.

Restart your web server, and pour yourself a nice stiff cocktail.

MG signing off (to enhance some more security).

Editor’s note: please be advised…I haven’t messed with OS X Server – these instructions are for the desktop addition, and for testbed purposes only.

Comments

mogra says:

I followed all the steps and finally checked configuration using following command:

/private/etc/apache2% : apachectl configtest

I get following error:
Syntax error on line 101 of /private/etc/apache2/extra/httpd-ssl.conf:
SSLCertificateFile: file ‘/Library/WebServer/certs/newcert.pem’ does not exist or is empty

line 101 in httpd-ssl.conf is : SSLCertificateFile “/Library/WebServer/certs/newcert.pem”

wc -l newcert.pem
67 newcert.pem
So file exits and is not empty.

mogra says:

Stupid of me : I found the mistake – had problem with path 🙂

Mogra – very glad it worked out for you!

fred says:

small typo in steps 6 and 7 :
~/private/etc/apache2/extra

should of course be:
/private/etc/apache2/extra

Corrected. Thank you Fred.

Perry says:

I’ve been searching for days to find a description like this that will allow me to set up SSL on a non-server Leopard machine. This is the best one yet. However, I still need to figure out how to modify this guide to allow me to use a registered ssl cert that I purchased a couple of weeks ago. I need to generate the CSR in order to complete the process and it looks like you did just that, but you used 1024 bit instead of the 128-bit key. Can this be done without buying OSX server? Any tips on where to find the details would be appreciated.

Thanks,
Perry

Sorry for not getting back to you sooner Perry. I don’t know anything about OS X Server i.e. it’s particular nuances. I produced this guide just for those who wanted SSL running locally for test purposes.

Further, this process does not seem to be running correctly on 10.6 – there are some quirks creating/signing the certs that result in Apache failing to respond. Not getting any error messages either.

Wish I could be of more help.

Regards,

MG

[UPDATE] Now working on Snow Leopard. The fix (at least here) was putting hashing out the revocation path line (SSLCARevocationPath “/Library/WebServer/certs/demoCA/crl”). Since this implementation is for demo/testing only, I’ve taken to creating a new CA instead of messing around with revoking certs, so this should not be an issue otherwise.

Colin Brown says:

A couple of other things:
…under ~/Library/WebServer

should read:
…under /Library/WebServer

And, for some reason, on my 10.8 instance, if you enter the same Common name twice, you will receive an error (which you may miss in the spewing output):
failed to update database
TXT_DB error number 2
Signed certificate is in newcert.pem

…and your generated newcert.pem will be zero bytes!

To fix this, provide 2 different common names when prompted. E.g.:
1st time: Common Name (eg, YOUR name) []: (type ‘yourname1’)

2nd time: Common Name (eg, YOUR name) []: (type ‘yourname2’)

Thanks!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.