Page 1 of 1

Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Sun Oct 28, 2012 5:12 pm
by manwithaplan
So, after working on this for over a week, I thought I'd commit this to paper, for anyone in similar situation.

This guide is designed for people who are running Mac OSX Server, whether it be Snow Leopard Server, Lion Server, Mountain Lion Server, etc. Instructions should be the same for all of them, though it should be noted that I performed this on Mountain Lion servers, specifically running 10.8.2 with Server 2.1.1. Again, it should not matter. These instructions do however differ from spookybathtub's excellent tutorial here http://forum.subsonic.org/forum/viewtopic.php?f=6&t=9400, in that his was written for folks running basic Mac OSX, not for those of us who run Server and already have pre-existing certs in the cert store on the box. There are real differences, some of which make our process easier and some of which make it more finicky - the point is, it's different on Server, and so I am laying out a process here for folks who have OSX Server up and running already, and now want to deploy Subsonic using SSL-based access. Okay then...

System Requirements for this process to work as written:
1. Intel-based Mac running Leopard Server, Snow Leopard Server, Lion Server, or Mountain Lion Server.
2. An installed and working SSL certificate (and any applicable intermediate certs to complete the cert chain) within Server Admin. ****BTW, If you don't know how to load a real cert into Mac OSX Server, there are plenty of Apple docs explaining how to do it. This is not the focus of this tutorial****. The cert itself is assumed to NOT be a self-signed cert, but actually a purchased root CA-signed certificate. [Important note: the cert needs to be enabled in Server Admin as the cert for the box, though the OSX Server services themselves do not necessarily need to be enabled yet or running. For example, I performed this in one case with nothing but the DNS service running on 10.8.2 OSX Server - but the point is I had my RapidSSL cert (and applicable intermediate cert chain) installed in OSX Server per the usual Apple method for this *prior* to embarking on this exercise.]
3. It is assumed that you already have a basic Subsonic install in place.
4. It is assumed that you have already modified the Info.plist file to assign an HTTPS port. As you may know, access to 4040 for plain HTTP can be left enabled, as Subsonic will automatically URL redirect to the HTTPS port for all connections on the assigned HTTP port.
5. Lastly, I assume you are smart enough to know that Subsonic should now be shutdown completely, as in, not running, while we perform the surgery below.

So, with the above background, let's get started:

As you may or may not know, when you install OSX Server onto a Mac, one of the things it does is create a directory in /private/etc, the directory is /certificates. So let's go there...

Code: Select all
cd /private/etc/certificates/


Let's take a look at what's there...

Code: Select all
server:certificates admin$ ls -la
total 40
-rw-r--r--    1 root  wheel      1769 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.cert.pem
-rw-r--r--    1 root  wheel      5572 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.chain.pem
-rw-r-----    1 root  certusers  3512 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.concat.pem
-rw-r-----    1 root  certusers  1743 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.key.pem
drwxr-xr-x    6 root  wheel       204 Oct 21 03:29 .
drwxr-xr-x  140 root  wheel      4760 Oct 21 14:03 ..


As you can see, I am using a wildcard SSL cert, but the process is no different for a more typical host-name based cert ie, for the specific hostname 'server.mydomain.com'. I just happen to use wildcard certs for most everything I do and they work perfectly. Obviously, you can save a few bucks by getting a cert tied to a specific FQDN, but that's totally up to you. Okay then...

So what is this mess up above in /private/etc/certificates??? It is none other than your individual cert file, the full chain including any/all intermediate and root certs required, the chain by itself without the host cert, and lastly, the private key, all in .pem format. Again, this construct is created for us automatically by OSX Server when we loaded our real certs and chains in the Server Admin GUI in the first place, nothing you have to do manually to place these files there on the command line.

So, seeing that these files are exactly as expected, sitting quietly in /private/etc/certificates, let's make magic happen:

First step is to create a PKCS12 formatted file that marries the *.chain.pem file to the private key...

Code: Select all
openssl pkcs12 -export -inkey \*.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.key.pem -in \*.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.chain.pem -out cert-chain.pkcs12


You will be prompted for the pass phrase for the private key. Keep in mind that when you installed your cert in OSX Server, the OS encrypts the private key file, using a one-time random pass phrase (not one that you ever chose yourself!). In case you don't know this, you can scrape the pass phrase out of the Keychain, by going into Keychain-->System-->Passwords, and choosing the password file related to "certificate management". If you either sudo when you run Keychain, or authenticate with a server admin's password when prompted, you will be provided an option to "Show Password" in the Keychain GUI. Copy that to the clipboard, because it is critical to this process!

Okay then, paste that big long ugly lookin' pass phrase into the command line when prompted. Once done, you will get the next prompt to:

Enter Export Password:

...the Export Password *must not be left blank*, and more importantly, must be "subsonic" without the quotes. Hit enter. You will then be prompted for:

Verifying - Export Password:

...type "subsonic" again and hit enter. Okay, at this point, you should now have your new .pkcs12 cert file in /private/etc/certificates. As you probably guessed, it's called cert-chain.pkcs12. Let's check it out:

Code: Select all
server:certificates admin$ ls -la
total 472
-rw-r--r--    1 root  wheel      1769 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.cert.pem
-rw-r--r--    1 root  wheel      5572 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.chain.pem
-rw-r-----    1 root  certusers  3512 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.concat.pem
-rw-r-----    1 root  certusers  1743 Oct 21 03:29 *.mydomain.com.7AC747142D7508EF899610497D140E1DB0A8ECA4.key.pem
-rw-r--r--   1 root  wheel      5685 Oct 27 23:10 cert-chain.pkcs12
drwxr-xr-x   2 root  wheel      1904 Oct 28 00:07 .
drwxr-xr-x  24 root  wheel      3808 Oct 28 00:05 ..


Okay then, from within this same directory, it's time to use keytool to create a nice little keystore that Subsonic's jetty server will accept:

Code: Select all
keytool -importkeystore -srckeystore cert-chain.pkcs12 -srcstoretype PKCS12 -destkeystore subsonic.keystore


It prompts you to Enter Destination keystore password: [again, must be "subsonic" without the quotes]
Re-enter password: [you guessed it, "subsonic" again without the quotes]

Then you will see a prompt for Enter Source keystore password: [must be the one we used above, which by now you know is "subsonic" without the quotes]

If you did this right, you will get the following:

Code: Select all
Entry for alias 1 successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled


If it makes you feel better, do another ls -la in this directory, and you should see the new file subsonic.keystore. Right. Now, we need to shove that beautiful little keystore into Subsonic the way the good lord intended. This is the last step kids, hold on tight:

Code: Select all
jar uf /Applications/Subsonic.app/Contents/Resources/Java/subsonic-booter-jar-with-dependencies.jar subsonic.keystore


If you are simply returned to the command prompt, with no errors, you have VICTORY!

Start up Subsonic, and open your Subsonic webpage, and you'll notice that HTTPS is working on your assigned HTTPS port with NO CERTIFICATE ERRORS!!!! Try several browsers just to be sure (Safari in particular, and now IE 9, make it real nice to follow the cert chain and see that each cert in the chain is valid and installed properly). Enjoy your secure Subsonic web instance!

Cheers,
-ManWithAPlan

Re: Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Sun Oct 20, 2013 9:50 pm
by Spektrum32
Hi there,

I've been at this for quite a bit, and I am very appreciate of the steps you've outlined here. Everything went seemingly smoothly, but when all was said and done I get the error: java.net.SocketException: Permission denied and my admin page of course will not load. I've been perusing other posts about this particular error, but none of the solutions seems to work. If you've tried to fix that error after running these steps, can you let me know what you did?

Re: Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Sun Dec 01, 2013 5:25 pm
by manwithaplan
Spektrum32, I believe you have a different situation not covered by this Tutorial at all. I believe you do NOT have Mac OSX Server. You have Mac OSX client, not server. If I am wrong, please post a follow-up. If not, please don't hijack this thread which is meant to be referencing the steps required for Server. I notice you have also posted the very same question under spookybathtub's original and excellent tutorial thread. I believe that is the proper place to track your query. Unfortunately I don't think I can help you on that.

Re: Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Sun Dec 01, 2013 6:37 pm
by manwithaplan
I feel obligated to post a follow-up to my original Tutorial here, to address the issue of "what happens when my original, proper, purchased SSL certificate expires and I now have a new renewed cert?"....that is indeed what just happened to me within the last week. Thankfully, the answer is quite straightforward. The new renewal certificate must be installed in the same manner that you installed the original one. So simply following the steps of this original tutorial will work just fine. You have to re-do everything of course, because the certificate that you renewed within OSX Server takes the place of, and has different properties of, the old, now-expired cert. So you have to do every step again in the order outlined in this tutorial. No big deal, just wanted to document it officially on the record here for all that may encounter this.

Now, in addition to that, in my case, my Subsonic server instance is running directly on the same OSX Server that is also my Open Directory LDAP server, from which I authenticate all users in Subsonic. So, when I renewed my OSX Server cert, all services within OSX Server automatically start using the new cert. That's great, and saves you alot of time with things like normal web services, Wiki server, Open Directory itself, etc. But it's that last one that can throw you a curve, if and only if you are using Open Directory within OSX Server to authenticate your Subsonic users (this is an Advanced option within Subsonic). If this describes your situation, then you will also need to make sure that Java within your server is set to trust the new cert, not just OSX Server and Subsonic in general. All LDAP authentication will not work until this is resolved. The issue revolves around the fact that the Java runtime has its own keystore of trusted certificates that is separate from the OS X keychain. Once I installed my LDAP server's certificate to that keystore, voila — Subsonic can connect with LDAPS. On a Mac, the location of this keystore is /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts. To update that file is not super easy, as you cannot cat the file or vi the file or pico the file. Instead, you need to actually perform an operation using keytool.

First, export the cert using a web browser or whatever. I used Firefox, because it is easy. You should end up with a simple PEM encoded file. Here’s how you import it:

$ cd /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security
$ sudo cp cacerts cacerts.orig
$ sudo keytool -importcert -file your_cert_file_here -keystore cacerts

You’ll be prompted to trust it, then you are done. By the way, starting somewhere around OSX 10.8 or so, the Java keystore password is "changeit" without the quotes. You'll be prompted for that when you run the keytool command above.

You'll now be able to authenticate using SSL-based LDAP from the Subsonic server to the LDAPS Directory. So users can now log in and stream again. I hope that helps some folks. By the way, MAJOR credit for this last piece goes to Spookybathtub again for he had already posted elsewhere here about this LDAP issue. I just felt the need to document the entire process for those that may have followed my earlier Tutorial and wondered what to do when cert renewal time comes up! Always happens more quickly than you want. Good luck to you all, post if you have questions.

Re: Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Fri Dec 12, 2014 4:57 am
by Spektrum32
A year later with a little more knowledge on SSL certs, I'm following these steps for renewal and they work like a charm. Thanks so much!

Re: Mac OSX Server - SSL Cert Install Step-By-Step

PostPosted: Thu Apr 23, 2015 8:03 am
by manwithaplan
Okay, so after finally upgrading from SS 4.7 all the way to SS 5.2.1, I found out the hard way that some things have changed, which renders this old tutorial incomplete. Basically, I broke HTTPS as well as LDAPS for authentication , when I upgraded SS from 4.7 to 5.2.1 and also updated the version of Java I was running. Somewhere in all that, I broke authentication and all SSL. So, after many hours of troubleshooting, here is what finally fixed both issues, they are separate but equally annoying:

Issue #1: HTTPS broke for the site - I tried the simple steps in this tutorial, just repeating them, and it wouldn't work. It turns out that Sindre for some reason moved the placement of the subsonic-booter-with-jar-dependencies file, at least for a Mac install. So, instead of the file being here:

/Applications/Subsonic.app/Contents/Resources/Java

...it is now here:

/Applications/Subsonic.app/Contents/Java

So, not sure when he changed this, but essentially you now have to insert your subsonic.keystore file into the new subsonic-booter-with-jar-dependencies, like this...

Code: Select all
jar uf /Applications/Subsonic.app/Contents/Java/subsonic-booter-jar-with-dependencies.jar subsonic.keystore


Issue #2: Even after fixing Issue #1 and getting HTTPS working again, all user authentication was broken to the site, and I use LDAPS over Port 636 to authenticate end users. In the past, the errors in the SS log were a great indication that I just needed to update my cacerts file as noted earlier in this tutorial (for instance, when you renew your trusted cert and have to tell Java to trust the renewed cert). The problem now was that I was sitting there updating the wrong cacerts file! The path has changed here too, but the insidious thing is that the old path and old cacerts file is still there, it's just that the file does nothing anymore. I believe this was triggered by one of the Apple Java updates, not necessarily an SS problem directly, but it will result in Java not having the correct cacerts file with your trusted cert in it. So the path is much different now, and this is what fixed it:

cd /Applications/Subsonic.app/Contents/PlugIns/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security
sudo cp cacerts cacerts.orig
sudo keytool -importcert -file your_cert_file_here -keystore cacerts

I hope this helps someone else that may have updated their Apple OSX versions, and/or Subsonic versions, and/or Java for Mac versions, and is having the same set of problems I was. Hopefully, these things will not move again anytime soon, but as with most things Mac, hold on to your hat and don't get too comfortable, cause stuff changes around the filesystem all the damn time!!! Cheers!