For testing, sometimes I need to validate web behaviors like redirects on SSL, and one of the reasons I love the Mac is that it gives me a ready to roll Apache server. I actually run a local copy of my web site on my Mac, and have it set up as a virtual host so that I can just browse directly to it.
Basically I have a dummy entry in my /etc/hosts file that gives me an alias I can use in the browser, so if I type http://accuweaver/ into the URL bar, I get directed to the localhost which serves up content from my ~/Sites/accuweaver folder (I have accuweaver as a vhost in the /etc/apache2/extras/httpd-vhosts.conf file).
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost workfront accuweaver 255.255.255.255 broadcasthost ::1 localhost
Out of the box, the Apache config on the Mac doesn’t have SSL set up. In order for SSL to work, you need a certificate (along with its’ key), and to make some configuration changes.
So the first step is to get a key. If you’re emulating a production box, you could cheat and use the SSL certificate for that box, but that’s probably not a good idea since it would expose your keys if your machine was ever compromised. So in general, you’re going to want to create a self-signed certificate.
The first step is to build a CSR, with a not so simple openssl command. To make figuring out that command a bit easier, you can go to this cool web page that will build it for you: https://www.digicert.com/easy-csr/openssl.htm – you just fill in the form and you’ll end up with the command you need to run in terminal:
openssl req -new -newkey rsa:2048 -nodes -out accuweaver.csr -keyout accuweaver.key -subj "/C=US/ST=Utah/L=Salt Lake City/O=Workfront/OU=Web/CN=accuweaver"
Running that command in a Terminal window will look something like this:
robweaver:~ robweaver$ openssl req -new -newkey rsa:2048 -nodes -out accuweaver.csr -keyout accuweaver.key -subj "/C=US/ST=Utah/L=Salt Lake City/O=Workfront/OU=Web/CN=accuweaver" Generating a 2048 bit RSA private key .................................................................................+++ .+++ writing new private key to 'accuweaver.key' -----
With that key in hand, you’ll need to generate the certificate, with a bit simpler command that reads both the CSR and KEY files to create the CRT file:
robweaver:~ robweaver$ openssl x509 -req -days 365 -in accuweaver.csr -signkey accuweaver.key -out accuweaver.crt Signature ok subject=/C=US/ST=Utah/L=Salt Lake City/O=Workfront/OU=Web/CN=accuweaver Getting Private key
So you now have a certificate as well as a key, which you can use to serve SSL traffic. The next step is to copy the key pair to somewhere that Apache can get to them. I typically create a folder named “ssl” under the /etc/apache2 directory, and move the newly minted files there:
robweaver:~ robweaver$ sudo mv accuweaver.* /etc/apache2/ssl/ Password: robweaver:~ robweaver$
Now that the files are in the right place, you need to make sure SSL is working. Brian Love has a pretty nice blog post about how to set it up at http://brianflove.com/2014/12/02/enable-https-in-apache-on-mac-yosemite, which is close to what I followed to get this set up. I did shortened version of his steps starting with editing my /etc/apache2/extra/httpd-vhosts.conf file. I already have a virtual host for the accuweaver name on the default HTTP port (80):
<VirtualHost *:80> ServerName accuweaver ServerAlias accuweaver DocumentRoot "/Users/robweaver/Sites/accuweaver" ErrorLog "/private/var/log/apache2/accuweaver-error_log" CustomLog "/private/var/log/apache2/accuweaver-access_log" common ServerAdmin firstname.lastname@example.org <directory "="" users="" robweaver="" sites="" accuweaver"=""> Options Indexes FollowSymLinks AllowOverride All Require all granted
So basically I copy that section, and update it to be port 443, and add a few lines to turn on SSL:
<VirtualHost *:443> ServerName accuweaver ServerAlias accuweaver DocumentRoot "/Users/robweaver/Sites/accuweaver" ErrorLog "/private/var/log/apache2/accuweaver-ssl-error_log" CustomLog "/private/var/log/apache2/accuweaver-ssl-access_log" common #SSL Engine Switch SSLEngine on #SSL Proxy Engine Switch (for rewrites) SSLProxyEngine on #Server Certificate: SSLCertificateFile "/private/etc/apache2/ssl/accuweaver.crt" #Server Private Key: SSLCertificateKeyFile "/private/etc/apache2/ssl/accuweaver.key" ServerAdmin email@example.com <directory "="" users="" robweaver="" sites="" accuweaver"=""> Options Indexes FollowSymLinks AllowOverride All Require all granted
This turns on the SSL, and points it to the right certificates for it to work. Be sure to run “sudo apachectl configtest” before you restart to make sure you don’t have any typos or invalid parameters (I originally did a cut and paste for the SSL directives and ended up with extra characters from the blog I was following, so my Apache wouldn’t start).
Assuming everything is now set up, you simply restart Apache:
robweaver:~ robweaver$ sudo apachectl configtest Password: Syntax OK robweaver:~ robweaver$ sudo apachectl restart robweaver:~ robweaver$
There is still one more step to go through to make your site come up as if it is truly trusted. If you go to your new site over SSL (https://accuweaver/ in my case), you’ll see an error like:
Which clearly indicates that your browser doesn’t trust the certificate. To fix this, you need to import the certificate in a way that the browser can use it. You could hit the “Advanced” and simply bypass the warning, but you’ll never see the nice green lock symbol that indicates SSL is working.
So clicking on the lock icon, you can view the certificate details:
The easiest thing to do here is to import the certificate and mark it as trusted, so open “Keychain Access”, and navigate to System and set the category to Certificates:
You can either drag the certificate into the window, or use the menu to choose “File/Import items..” and browse to find it. In either case, you’ll be prompted to allow the import to happen, then you should see the new certificate in your trust store:
Double click the certificate to see the details:
Expand the Trust area to set it as trusted for SSL:
And I’d recommend only setting the value to SSL since that is what you built the certificate for.
And now when you go to the virtual host, you’ll get the green lock and the certificate shows as trusted: