Note: For my mac dev box, I load my custom Apache configurations in a standalone file, e.g. /etc/apache2/other/mysites.conf. I tend to leave the default apache files in place for reference. You may prefer to edit or replace the default files instead.
I started by reading this set of instructions, but had to workaround a few other issues to get https working. Here are the full steps I used.
Steps
1. Per my last post about setting up https in production, generate a private key this way (if you don’t have the one for production):
$ openssl req -nodes -newkey rsa:2048 -keyout mysslprivatekey.key -out localhost_mycompany.csr Generating a 2048 bit RSA private key .............................................+++ .......................+++ writing new private key to 'mysslprivatekey.key' ----- 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]:California Locality Name (eg, city) []:MyTown Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:www.mycompany.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Note I didn’t set a password, email, or anything optional.
2. With that private key, create a local certificate. (Note that I use the hostname localhost.mycompany.com for my browser testing in development. I have an entry in my /etc/hosts file pointing this name to 127.0.0.1. Using the FQDN for localhost allows access to full cookie functionality.)
$ openssl req -new -x509 -key mysslprivatekey.key -out localhost_mycompany_com.crt -days 1095 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]:California Locality Name (eg, city) []:MyTown Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Organizational Unit Name (eg, section) []:Common Name (e.g. server FQDN or YOUR name) []:localhost.mycompany.com Email Address []:
3. Copy the *.csr, *.key, and *.crt file to a directory for apache, creating it if doesn’t exist:
sudo mkdir /etc/apache/ssl sudo cp *.csr *.key *.crt /etc/apache/ssl
4. I had some trouble getting port 443 working. I could see it wasn’t listening when I ran the command
netstat -nap tcp|grep 443
When everything is working correctly, you should see something like this line in your netstat output:
tcp46 0 *.443 *.* LISTEN
I tried a number of things, including verifying that I had no Firewall turned on (System Preferences > Security & Privacy > Firewall). In the end, all I needed to do was uncomment the following Include line in /etc/apache2/httpd.conf
Include /private/etc/apache2/extra/httpd-ssl.conf
Verify that mod_ssl is being loaded by this line in the file:
LoadModule ssl_module libexec/apache2/mod_ssl.so
5. Verify the following critical items in /etc/apache2/extra/httpd-ssl.conf or in your configuration flow.
# this is the line needed to get your server listening on port 443, and see it in netstat
Listen 443
# comment out the default lines which point to non-existent files, and insert your own real paths:
#SSLCertificateFile "/private/etc/apache2/server-dsa.crt" #SSLCertificateKeyFile "/private/etc/apache2/server-dsa.key" SSLCertificateFile "/private/etc/apache2/ssl/localhost_mycompany_com.crt" SSLCertificateKeyFile "/private/etc/apache2/ssl/mysslprivatekey.key"
Note – I tried skipping these 2 lines *in this file* since I use them later, but this caused https to fail, with this error in error.log:
Server should be SSL-aware but has no certificate configured [Hint: SSLCertificateFile] (/private/etc/apache2/extra/httpd-ssl.conf:74)
6. Now in your main configuration area (in my case /etc/apache/other/mysites.conf), add the following:
#! without this line, https requests were going to the wrong DocumentRoot (from the default VirtualHost). You could also put this line in httpd-ssl.conf presumably
NameVirtualHost *:443
#This is the main configuration block to add
#remove the space after the start and end VirtualHost tags. removed for tumblr's sake. <VirtualHost *:443> SSLEngine on ServerName localhost.mycompany.com #next 2 lines are dupes from http-ssl.conf, but https fails without them with connection refused SSLCertificateFile "/private/etc/apache2/ssl/localhost_gigabody_com.crt" SSLCertificateKeyFile "/private/etc/apache2/ssl/mysslprivatekey.key </VirtualHost>
7. Restart Apache
sudo /usr/sbin/apachectl restart
8. Open your browser and test for your particular domain
The first time you hit https, you’ll get an error that the certificate is untrusted, ignore it and allow the browser to use it, since you know it’s safe. These 2 urls should both work and bring up the same default page, when everything is working.
9. For general troubleshooting, you can check out the Apache error log. I see these warnings in my error.log, but they are safely ignored in development.
[warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?) [warn] RSA server certificate CommonName (CN) `localhost.mycompany.com' does NOT match server name!?