Munki and Puppet have become very popular tools in the last few years, and make a great team for Mac management. While Puppet is inherently secure due to its use of client-certificate based SSL for all communication, most Munki deployments still run over plaintext HTTP. One of the best features of Puppet is its included Certificate Authority, and we can make great use of this to secure other services such as Munki. Running Munki over HTTP is problematic for two reasons. First, it leaves organizations open to man-in-the-middle attacks, whereby an attacker can compromise a machine with Munki installed by spoofing the DNS entry for the server hosting the repository. By doing this, clients will check into the attacker’s server and install any software or configuration presented. This can easily result in compromised machines, and this is especially important for machines which leave a secure campus network. The second issue with having a Munki repository served over HTTP is that the repository becomes accessible to anyone with access to the network, without any authentication. This may not be an issue if the repository hosts free software, but with most repositories hosting a variety of expensive software such as Microsoft Office or the Adobe Creative Suite, there should be a strong desire to prevent simple software piracy. This is especially important if an organization intends to expose its Munki repository to the Internet. Solving the first issue is relatively easy by using a SSL certificate for the repository and using CA pinning, but for those using Puppet along with Munki, solving both issues is very easy. Puppet uses SSL for its communication, and we can reuse this method for Munki in the form of client certificates. This will allow all traffic between the Munki repository and clients to be encrypted, for the repository to be accessible only to those clients with certificates, and to make man-in-the-middle attacks all but impossible.
Securing the Munki repository
First, the web server hosting the Munki repository will need to be Puppetized. Any web server and operating system should work, but in this example Apache 2 on Ubuntu is used. Puppet does not need to be doing any actual configuration management on the server; it simply needs a certificate issued by the local Puppet certificate authority. On most installations, Puppet’s SSL certificates will be located in /etc/puppet/ssl/ or /var/lib/puppet/ssl/. These certificates can be used directly by mod_ssl in Apache, as shown in the following example.
https://gist.github.com/eeba3d2bc02dfc1ceb60
In this simple configuration, the server will require all connections to have a valid certificate signed by the Puppet CA, and it will also use the certificate revocation list (CRL) in order to deny access to any host which has had its certificate revoked, which could be used in the case of a stolen or misplaced machine. It will use the certificate issued by the Puppet CA as the server certificate, so clients will be able to verify its authenticity as well.
Getting clients access
Now that the Munki repository has been secured, clients must be updated in order access it. Since we are using Puppet’s certificates, we should also use Puppet to place this configuration. This requires some simple Puppet code, with a prerequisite of Graham Gilbert’s
macdefaults module. With the following code, we will have Puppet make a copy of its certificates for Munki to use in case Puppet’s are accidentally deleted, and then instruct Munki to use them to contact the repository. This assumes that all other needed settings have been placed, including the CatalogURL.
https://gist.github.com/4c81c9e06b1e9266a159
Once these settings have been placed, Munki’s communication will be fully encrypted – safe enough to send directly over the Internet.
Considerations
Before placing a configuration such as this into production, there are some important items to consider. Encrypting traffic takes a large amount of resources, so this could easily overwhelm a server that has long been serving a repository over HTTP. Luckily, Intel added AES-NI support to its CPUs starting with the Westmere generation in 2010, which does hardware acceleration of SSL and TLS at a huge speedup from normal processing. OpenSSL supports this acceleration, and will automatically use it if the extensions are detected. Still, encrypting hundreds of simultaneous copies of the latest Xcode update may cause extreme load, so test extensively. In addition, make sure to have a look at the ciphers and encryption protocols being used by your web server. The defaults for Apache are extremely insecure at this point, so it is important to use something better, especially in this case where there is no worry about old web browsers needing to be able to connect. It is highly recommended to restrict all traffic to TLSv1, currently the best protocol and cipher suite Apache and OpenSSL support.
Do you still need to use an alternative Curl binary with 10.9? I think this is where I fell down last time I tried this.
Currently you do need a custom curl binary on 10.9. I just updated my curl-for-munki GitHub repo with AutoPkg recipes to build the latest curl release: https://github.com/hjuutilainen/curl-for-munki