Note: this is based on the README for the Munki-SSL docker container.
In a previous post, we ran a Docker container serving Munki repo content via Nginx. That works fine, but only serves insecure HTTP content. It’s generally in everyone’s best interest to use a secure connection between the Munki web server and its clients, and that’s described in detail: either through basic authentication or with SSL client certificates.
Using SSL client certificates is not a trivial matter, as it involves setting up a CA, or using a third-party CA to generate your client certificates, which involves a lot of work on both server and client end.
Thankfully, Sam Keeley has already written a great article about using Puppet, a configuration management tool, as the cornerstone for client-server certificate-based communication: https://www.afp548.com/2014/06/02/securing-a-munki-deployment-with-puppet-ssl-certificates/. I’ll be using this article as the basis for our configuration.
The general idea is that Puppet has its own CA, and it installs client certificates on each client you register to it, to guarantee secure communication between the Puppet master server and the clients. We can use the Puppet client certs to allow the Munki clients to communicate with the Munki webserver through certificate-based SSL.
Creating a Munki container that incorporates Puppet:
We have an existing Munki image, so we can use that as a base and just install Puppet on it. Here’s the Dockerfile:
FROM nmcspadden/munki MAINTAINER Nick McSpadden firstname.lastname@example.org ENV PUPPET_VERSION 3.7.3 RUN apt-get update RUN apt-get install -y ca-certificates ADD https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb /puppetlabs-release-wheezy.deb RUN dpkg -i /puppetlabs-release-wheezy.deb RUN apt-get update RUN apt-get install -y puppet=$PUPPET_VERSION-1puppetlabs1 ADD csr_attributes.yaml /etc/puppet/csr_attributes.yaml
The great thing about Dockerfiles is that they can be inherited from. Using the
FROM directive, we take everything accomplished in the Munki container, and simply build on top of it.
ENV PUPPET_VERSION 3.7.3
Here, the puppet version is explicitly set so that we can get the same behavior every time we build the Docker image.
RUN apt-get update
RUN apt-get install -y ca-certificates
ADD https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb /puppetlabs-release-wheezy.deb
RUN dpkg -i /puppetlabs-release-wheezy.deb
RUN apt-get update
RUN apt-get install -y puppet=$PUPPET_VERSION-1puppetlabs1
In order to install the updated version of Puppet, we need to acquire the correct Puppetlabs repo and GPG keys. The Munki container is based on Debian wheezy, so we acquire the appropriate installer by ADDing the key package, and then use
dpkg to install it. We’ll also grab the updated
ca-certificates to guarantee that the certificate used to sign https://apt.puppetlabs.com/ is trusted.
Once we’ve installed the correct Puppetlabs repo and GPG key, we can install Puppet from that repo.
ADD csr_attributes.yaml /etc/puppet/csr_attributes.yaml
The CSR attributes file is described on Puppet’s website. It’s used to add extra information from a client to the CSR (Certificate Signing Request) generated on the client when the puppet agent runs for the first time and tries to get a certificate from the Puppetmaster. It can be used to write scripts that sign certificates based on certain kinds of information or policies.
In our Puppetmaster container, CSR requests get automatically signed, so this isn’t important yet. In our next iteration, we’ll see how we can put extra information from the client to use in policy-based request signing.
Building the Container:
You can either build the container by git cloning the repo:
docker build -t name/munki-puppet .
or you can pull the automated build container:
docker pull macadmins/munki-puppet
Once you’ve got the container built, let’s run it.