Mac OSX (Server): import LE certificate?

I did find this post which works as a solution to the apache2 proxy problem you saw (see the last post to use the custom proxy site by DDJarod).

I tried it and it works like a charm, I just needed to change the proxy port to 34580 for regular http. After that I no longer had to use a separate machine to run the python web server.

1 Like

Interesting! Thanks for sharing.

I’m running an OS X server with Let’s Encrypt certificates installed. I ran into the problems discussed earlier and ended up getting the certificate in manual mode while temporarily redirecting the name to a Ubuntu box. Hopefully when it comes to renewal I can figure out the command-line flow.
I do have a tip for opening arbitrary directories in Finder: the open command-line tool. For example, to open the current directory, open ., or in this case, open /etc/letsencrypt/live.

I was able to solve the permission issues by importing the certificate with the -A option.

security import /etc/letsencrypt/live/$1/letsencrypt_sslcert.p12 -f pkcs12 -k /Library/Keychains/System.keychain -P topsecret -A

However I then block at the procedure to add this certificate to a web site. There seem to be a way using serveradmin but I haven’t figured it out yet (not to speak from the renewal).

I don’t prefer the -A option (It allows access for all applications to the private Key) Instead i would prefer:

security import /etc/letsencrypt/live/$1/letsencrypt_sslcert.p12 -f pkcs12 -k /Library/Keychains/System.keychain -P topsecret -T /Applications/Server.app/Contents/ServerRoot/System/Library/CoreServices/ServerManagerDaemon.bundle/Contents/MacOS/servermgr

which only give access to servermgr.

While doing this i run into Problems with the keychain access. The System Log showes

1/7/16 11:03:15.278 AM SecurityAgent[2110]: Ignoring user action since the dialog has received events from an untrusted source

Workaround is to do this locally at the server, not remote via ARD.

hello folks, fantastic work!!!
(special thank´s to majorsl post > “[Solved] Apple server proxy blocks access to .well-known”)
i´m actually at the same point like wiku… (i think…)
my certificates are in /etc/letsencrypt and added to os x server keychain, also i can see the certificate in server-app but i can´t use it…
if i want to use the certificate for a webpage i can sign it, but the server-app still turns it back to the previous one.
any ideas?
(sorry about my english, i´m not a native speaker… :sweat_smile: )

Did you check the authorizations for the private key (Keychain Access, double click on the key and check Access Control) ? You need to make sure that the Server app can use the private key from the Keychain.

thanks cyrilpic, i think you’re right it´s a permissions problem…

if i clicked at the key i can see that only “system” can use it.

but if wan´t to change os x ask
1st for admin (because change the keychain)
and
2nd for another admin? could this be root?

at the end i can´t change the permissions for this key… (i think it´s a problem because i´ve put the *.p12 file by root (sudo tcsh) in keychain… right?)

I’m sorry. I can’t directly help you further. I have had no problems changing the permissions of the key (even though I imported it with root user).

Many thanks to the folks that have posted here and the related thread regarding the .well-known issue.

I have successfully installed several letsencrypt certs on my Mac running OS X 10.11.4 + Server.app 5.1. I thought I would post my steps here in one concise post to help anyone else that might be struggling with this.

UPDATE YOUR MAC:

Update to OS X 10.11.4
Update Server.app to 5.1

SET UP / INSTALL LETSENCRYPT

brew update

sudo mkdir /etc/letsencrypt
sudo mkdir /var/lib/letsencrypt
sudo mkdir /var/log/letsencrypt

brew install letsencrypt

Please note: I already had homebrew installed. Visit the homebrew site for instructions on installing homebrew or use a different method to install letsencrypt.

TEST FIRST:

You want to make sure that it succeeds at creating and verifying a test certificate first, otherwise you might hit a rate limit at letsencrypt for your domain.

sudo letsencrypt certonly --webroot -w /Library/Server/Web/Data/Sites/SiteRootDirectory/PublicDirectory** -d example.com -d www.example.com **--test-cert**

ONCE THE TEST SUCCEEDS:

sudo letsencrypt certonly --webroot -w /Library/Server/Web/Data/Sites/SiteRootDirectory/PublicDirectory -d example.com -d www.example.com

It will ask if you want to replace/renew and you want to say yes because the successful test cert won’t be verified

CONVERT CERT FOR OS X:

sudo openssl pkcs12 -export -inkey /etc/letsencrypt/live/example.com/privkey.pem -in /etc/letsencrypt/live/example.com/cert.pem -certfile /etc/letsencrypt/live/example.com/fullchain.pem -out /etc/letsencrypt/live/example.com/letsencrypt_sslcert.p12 -passout pass:topsecret

VERIFY CERT (OPTIONAL/MIGHT FAIL):

sudo security verify-cert -c /etc/letsencrypt/live/example.com/letsencrypt_sslcert.p12

This failed for me but after importing into the keychain and applying the cert to the site in Server.app, it worked like a charm.

IMPORT CERT TO OS X KEYCHAIN:

sudo security import /etc/letsencrypt/live/example.com/letsencrypt_sslcert.p12 -f pkcs12 -k /Library/Keychains/System.keychain -P topsecret -T /Applications/Server.app/Contents/ServerRoot/System/Library/CoreServices/ServerManagerDaemon.bundle/Contents/MacOS/servermgrd

Once the cert has been added to the OS X keychain open (or quit and relaunch) Server.app and apply the cert to your site. If you had Server.app open while adding the cert to the keychain, Server.app will not see the new cert until you quit and relaunch Server.app

NOTES:

I replaced instances of “topsecret” with my own password. Instances of example.com should be replaced with your domain. SiteRootDirectory is the directory that your project lives in, PublicDirectory is the directory that apache points to for serving files. In some cases these may be the same directory depending on your web site is organized.

There may be things I haven’t done entirely perfectly here and I welcome any comments / revisions.

2 Likes

Hi ChristopherRaymond,

Thanks for posting this walkthrough, it's been very helpful getting Let's Encrypt working on my Mac Server running 10.11.6 and Server.App 5.1.7. I just had a couple of quick questions.

First, when it comes to renewal time, does the renewed cert need to be manually imported into the Server app via the terminal each time, or will it automatically detect the renewal after running

certbot renew --quiet

Have you put together any scripts to handle renewal that you might be willing to share?

Second, have you had any success with a reverse proxy setup? I have two http reverse proxies setup based on the instructions at Precursor Systems OS X Server 5 Reverse Proxy . I've gotten your instructions to work with the main domain and www, but when I try to use it to provide certs with my two other subdomains (sub1 on the same server and sub2 on another server on the local network), I'm getting the following error:

IMPORTANT NOTES:
 - The following errors were reported by the server:
   Domain: sub1.example.com
   Type:   connection
   Detail: Could not connect to
   http://sub1.example.com/.well-known/acme-challenge/CkNKHFlhIiedd9wTgsjNcjXigaT2XmlFr3VmS8rZ0r0
   Domain: sub2.example.com
   Type:   connection
   Detail: Could not connect to
   http://sub2.example.com/.well-known/acme-challenge/EWhvY-IE_n5FvTDZJkk1r1s3A55sEQwRc5dNg83dQlo
   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webfoot path you provided.

Would you happen to have any suggestions? Thanks in advance!

Hi fkick,

Yes, you need to do the conversion and import step at every renewal.

Here is a small script that I wrote for automating the process : https://gist.github.com/cyrilpic/4504527de3a7b08ed84e
When renewing, it asks certbox to renew the certificates, insert new certificates in the keychain, ask the server app to use the new certificates (through certupdate) and remove the old certificates from the keychain.
Use at your own risks :wink:
(You need to sudo to use it.)

As for the reverse proxy part, updating to Server 5.1.7 solved all issues for me. Maybe try to delete the sub-domain and recreate it…

Thanks cyrllpic,

Just to make sure I understand what needs to happen, I need to run certbox4osx with sudo, passing in either renew or new, my domain name, and my -w pathway.

Does it accept certificates with multiple subdomains? i.e. example.com and www.example.com and sub1.example.com?

The script is very basic.

To renew:
sudo certbot4osx renew

To get a new certificate:
sudo certbot4osx new my.domain.com /path/to/site/folder

The get a new certificate part only works for a single domain (lack of time to implement a full and nice interface), but you could easily change the script to fit your needs.

You don’t need to use the “new” command to be able to use the “renew” command, but it assumes that the pkcs12 version of the certificate is called letsencrypt_sslcert.p12. I would expect the renew command to work also for multiple subdomains but I haven’t tested it.
Again, the script is not very user friendly, but it does what I need. I’ll gladly accept improvement suggestions!

Reading your post: does it imply that certbot might not work on OSX earlier than 10.11 ?

This appears to mostly work. I am able to create & use certs for websites hosted by my mini.

However, when attempting to use a LE cert for Server.app itself, I receive the following error:

Server cannot access the private key for this certificate. To grant access, click Continue and enter your user name and password when prompted.

When I click continue, nothing happens.

Any ideas what I've done wrong?


Update: apparently "nothing happens" because it Just Works™ but you can't tell that unless you click into the "custom..." menu.

I’ve encountered nasty bug when importing certificate to keychain. I’ve submited radar to Apple.

Basically it looks like this:

  1. There is a letencrypt cert and some website is configured via Server.app to use it. Everything is happy.
  2. Cert is automatically renewed and imported via security command to keychain
  3. Some Server daemon notices new certificate and updates configuration files.
  4. Apache web proxy gets misconfigured with duplicate entries in /Library/Server/Web/Config/Proxy/apache_serviceproxy_customsites.conf
  5. Webserver is broken.

BTW I noticed @cyrilpic scripts uses certupdate. According to man page:

When the System Keychain changes, certupdate will be called with the remove or replace command. 
certupdate will in turn call each of the helper tools and return the highest numbered exit status from the helper tools

From what I see and read in man pakge invoking certupdate manually should not be required as it is automatically invoked when cert is imported into keychain.

The workaround I use is to switch the website to a self-signed cert (any one will work, just used as a place holder). Delete the old LE cert(s), let the scripts import the renewed cert(s) and the select the right cert(s) for each website. A pain, but you don’t have to start from scratch each time. At least until they fix the issue. Same problems exists in 5.3.

I’m having kind of the same issue as you report.

And yes using certupdate is messing things up. I haven’t had much time to dig into this.
Currently, I run my script and then I manually reset the certificates in the Server.app. Definitely not ideal!

If you see similiar problems please file radars with Apple.
Feel free to reference my radar (rdar://30991727)

I would like to create fully automated setup I don’t have to worry about breaking :slight_smile: