Using https / self-signed certificates and basic authentication with Munki

If you want to go full throttle...

The Munki Wiki has some detailed instructions (and a script) to set up your own certificate authority and then issue (and revoke) client certificates:
Using Munki With SSL Client Certificates

If you want something secure but simple

If you want something a little bit simpler but not straight plain text with no authentication, another option is to enable SSL and couple it with basic authentication. This post will walk you through that process, using a Mac desktop Apache server (process is probably similar for Ubuntu or Windows Apache, but there may be small tweaks).

Set up a self-signed certificate

On your Apache server, you're going to create a self-signed certificate, which means it will be untrusted by pretty much any web browser when visiting https, but for Munki it will be fine as long as we put the .pem file in the right place.

Generate the server key:

openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout server.key -out server.crt
Answer the questions based on your organization's details. If you're unsure how to answer the questions, Using Munki With SSL Client Certificates actually goes into quite a bit of detail on what to answer and what to skip.

Create a .pem

openssl x509 -outform der -in server.crt -out ca.pem
Move the server.key and server.crt files and change ownership to root
sudo mv server.key /etc/apache2/
sudo chown root:wheel /etc/apache2/server.key
sudo mv server.crt /etc/apache2
sudo chown root:wheel /etc/apache2/server.crt
Save the ca.pem file for later—your Munki clients will need that file.

Enable SSL on Apache

Edit the httpd.conf file while making a backup

sudo nano -B /etc/apache2/httpd.conf
Uncomment (remove the # from the beginning of) the following lines:
LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache2/mod_ssl.so
Include /private/etc/apache2/extra/httpd-ssl.conf
Save the file (Control-X).

Edit the httpd-ssl.conf file while making a backup

sudo nano -B /etc/apache2/extra/httpd-ssl.conf
Edit the virtual host setup to reflect your actual setup. Here's an example, but make sure you put in your actual details (don't just copy and paste from below):
# General setup for the virtual host
DocumentRoot "/Library/WebServer/Documents/munki_repo"
ServerName subdomain.domainname.org:443
ServerAdmin youremail@domainname.org
Save the file (Control-X)

Enable basic authentication

If your Munki repo isn't in /Library/WebServer/Documents/munki_repo, feel free to adjust to your actual setup:

cd /Library/WebServer/Documents/munki_repo
htpasswd -c .htpasswd munki
You'll be prompted for a password (with no visual feedback—it is still being accepted and processed). Feel free to create as many usernames (not just munki) and passwords as you want. Probably best to start with just one to make sure everything's working. Don't forget this password, at least not until you get at least one client set up.

Go back and edit your httpd.conf file

sudo nano /etc/apache2/httpd.conf
Apparently you're supposed to find the <Directory> section and add this after the existing configuration directives, but I put it in some random spot, and it still seemed to work. To be safe, you may want to put it where you're supposed to, though:
## Basic authentication for Munki repo
<Directory "/Library/WebServer/Documents/munki_repo">
AuthType Basic
AuthName "Authentication Required"
AuthUserFile /Library/WebServer/Documents/munki_repo/.htpasswd
Require valid-user
Order allow,deny
Allow from all
</Directory>
Save the file (Control-X).

Test your Apache config

Since you've been editing a couple of configuration files, make sure you didn't make any syntax errors:

sudo apachectl -t
If that passes and says your syntax is okay, then restart the Apache service:
sudo apachectl restart

Set up your clients to use basic authentication

Okay. Remember how I said not to forget the password for basic authentication? Well, you need that password now. On your client you'll be running a bunch of commands. Don't save your commands for this session to the ~/.bash_history file:

unset HISTFILE
Create a base 64–encoded username/password combo:
python -c 'import base64; print "Authorization: Basic %s" % base64.b64encode("munki:somestrongpasswordyoupicked")'
which should output something like
Authorization: Basic bXVua2k6Y2Fyb2xqY2xvdmV=
That last encoded bit will vary, obviously, based on the username and password you choose.

Write that to the "secret" (still readable by admins who escalate to root) Managed Installs .plist:

sudo defaults write /private/var/root/Library/Preferences/ManagedInstalls AdditionalHttpHeaders -array-add "Authorization: Basic bXVua2k6Y2Fyb2xqY2xvdmV="
Also write the now-https location of your Munki repo:
sudo defaults write /Library/Preferences/ManagedInstalls SoftwareRepoURL "https://subdomain.yourdomainname.org"

Copy the ca.pem from your server to the client machine (in its desktop folder, for example). Then, on the client machine, move it to the appropriate place with the appropriate permissions:

sudo mkdir -p /Library/Managed\ Installs/certs
sudo mv ~/Desktop/ca.pem /Library/Managed\ Installs/certs/
sudo chown -R root:wheel /Library/Managed\ Installs/certs
sudo chmod 700 /Library/Managed\ Installs/certs
sudo chown 600 /Library/Managed\ Installs/certs/ca.pem

Finally, test it out and make sure everything works!

sudo /usr/local/munki/managedsoftwareupdate --checkonly
If it doesn't work, try
sudo /usr/local/munki/managedsoftwareupdate -vvv
to see if you can find out more details in the verbose output.

How secure is this?

All this secures is network traffic, so you're not passing information in plain text. It also means random computers that just know the address of your repository can't randomly access all the packages in your Munki repo.

But this does not secure against your actual users, especially if they have admin privileges on their machines (or have extended physical access to their machines, which—with a little know-how or Google Fu—is essentially root access).

To a certain extent, this may be a moot point if your Munki server isn't public-facing, but it's still a nice, small barrier to put up in case you have someone somehow get on your internal network and want to sniff around.

Acknowledgements

The instructions above I cobbled together based on instructions from these tutorials:

7 thoughts on “Using https / self-signed certificates and basic authentication with Munki”

  1. Thanks for the excellent guide!

    Is there a way to automate client configuration? I have an existing http setup and would like to implement https, preferably without having to touch every machine individually…

    1. Yes, you can definitely automate it. Just keep in mind that with http you currently have the barn door wide open. And if you automate switching to https, you’re locking the barn door but giving pretty much anyone the key to it before locking it.

      You would just create a .pkg with the ca.pem as a payload and then a postinstall script that changes the SoftwareRepoURL and adds in the authorization information. You can use Packages, MunkiPkg, or The Luggage to create the .pkg. Add that .pkg to your Munki repo and make a managed_install, and then your clients will switch over.

      Alternatively, if you have all your devices on ARD, you can push out the .pkg that way when the devices are online if you don’t want to just hand the https authorization to anybody.

    1. I’m not sure I understand the question. You mean instead of using Munki or Finder (directly on the server itself if it’s macOS or via some kind of network share if it’s on Linux)? Like in a Firefox or Chrome web browser? If you mean the latter, you would just visit whatever page you wanted (most Munki setups do not allow for directory listings—so you’d go directly to a file) and then the browser would prompt you for a username and password.

  2. Alan, first of all thank your for this write up.
    So I first created a .key
    sudo openssl genrsa -out machine.key 2048
    I then used machine.key to create a machine.csr
    sudo openssl req -new -sha256 -key machine.key -out machine.csr
    I then took the machine.csr and created a machine.cer (company policy).
    Is this the file that I put in /etc/apache2?
    Also files do I put on the client machine?

    Thanks a million!

    1. Angel, the commands I put up there move the certs to the right folders on the Apache server. The .pem file is what you put on the client machines. The only time I see .csr and .cer on this page is in your comment.

      I just know the steps in this blog post work (or worked when I wrote it). I’m not really an expert on certificates, so if you deviate from the instructions, I’m not sure what you should do.

Leave a Reply

Your email address will not be published. Required fields are marked *