Enabling Kernel Extensions in High Sierra

In macOS 10.13 High Sierra, Apple is introducing Secure Kernel Extension Loading (or SKEL for short). This takes the changes introduced with SIP (requiring all KEXTs to be signed) one step further to requiring the user to enable them manually. Whilst this is great for home users, this absolutely sucks for those of us who manage macOS in the enterprise (who need things like VPN clients and anti malware tools running). ...

September 11, 2017

Open sourcing Airbnb's Puppet module for Munki

It’s probably no secret that we use Puppet to configure our macOS fleet at Airbnb. And whilst we have given several talks about how we use Puppet on macOS, there was still a lot of hand waving about how we had our modules set up. So, after several months of me saying “I should open source that”, here is our first open source Puppet module: puppet-munki. What does it do? As you may have guessed, it is a Puppet module that installs and configures Munki. More specifically: ...

September 6, 2017

High Sierra and my open source tools

With this week’s release of the first beta of High Sierra, I wanted to quickly update everyone on the current status of the tools I’ve released, and where I see the future going for them. Sal Sal appears to work fine on High Sierra. Some of the external scripts may need updating, but right now I’m not seeing anything that’s broken. I don’t see anything changing in this regard. Crypt Amazingly, the way we interact with FileVault as admins seems to not have changed at all, so Crypt has been reported to work perfectly (I will confirm when I get back to my testing computers that I don’t mind nuking). Apple has had a habit of wiping out the authorization database for basically every update during Sierra’s life, so this isn’t really a surprise. Whether managing the entries with your configuration management tool, or simply reinstalling the package will get things working again. ...

June 7, 2017

MacDevOps YVR

For those of you who are at the fantastic MacDevOps:YVR, why on earth are you reading this? Regardless, here are the slides from my talk “Something something commercial, something something open source” (and thank you for coming and not throwing things at me, you’re all lovely people). I will update this post when the video is available.

June 6, 2017

Using Python in Puppet Facts

There comes a time when writing Facts in Ruby just isn’t going to cut it - when you need to access Objective C frameworks, for example. Whilst Ruby can’t access these, Python is waiting in the wings ready to come to your rescue. There is the concept of External Facts - Facts that are written in whatever the system can run, and with Puppet 3.4 / Facter 2.0.1, they can even be distributed with pluginsync. ...

April 21, 2017

Using Caddy to HTTPS all the things

Caddy is a lightweight web server that amongst it’s features, has integration with LetsEncrypt to automatically request certificates. This means that you now have absolutely no excuse anymore to run your apps over plain old HTTP anymore. Let me be clearer. If you are running web services over HTTP, regardless of whether it touches the internet or not, you are doing it wrong. ...

April 4, 2017

Loading LaunchAgents as root

There are times when you will need to load a LaunchAgent when a script is running as root - when you are running a postinstall script from a package or when you are loading the LaunchAgent via your management tool of choice (Puppet, Munki, Jamf Pro), for example. All of these example are assuming you have a LaunchAgent at /Library/LaunchAgents/com.company.example.plist. Loading a LaunchAgent #!/bin/bash # get console UID consoleuser=`/usr/bin/stat -f "%Su" /dev/console | /usr/bin/xargs /usr/bin/id -u` /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.company.example.plist #!/usr/bin/python from pwd import getpwnam import subprocess import sys from SystemConfiguration import SCDynamicStoreCopyConsoleUser username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0] if username is None: # Exit if there isn't anyone logged in sys.exit() uid = getpwnam(username).pw_uid subprocess.call(['/bin/launchctl', 'bootstrap', 'gui/{}'.format(uid), '/Library/LaunchAgents/com.company.example.plist']) Unloading a LaunchAgent #!/bin/bash # get console UID consoleuser=`/usr/bin/stat -f "%Su" /dev/console | /usr/bin/xargs /usr/bin/id -u` /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.company.example.plist #!/usr/bin/python from pwd import getpwnam import subprocess import sys from SystemConfiguration import SCDynamicStoreCopyConsoleUser username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0] if username is None: # Exit if there isn't anyone logged in sys.exit() uid = getpwnam(username).pw_uid subprocess.call(['/bin/launchctl', 'bootout', 'gui/{}'.format(uid), '/Library/LaunchAgents/com.company.example.plist']) The Python version may look more complicated, but is slightly more robust as it is retrieving the current username using Apple’s frameworks and I have also allowed for the script not to fail if there isn’t a user logged in.

March 25, 2017

Something something commercial, something something opensource

Thanks to everyone who came to my session at MacAd.UK. I will link the video here when it is available, but in the meantime here are the slides.

February 8, 2017

Pocket Mac admin's guide to London

It’s less than three weeks now until I give my talk about our journey from commercial management tools to open source nirvana at MacADUK - and whilst I’m very excited about the conference and all the fantastic speakers, I know some of you are equally as excited about visiting London. So, here’s my pocket Mac Admin’s guide to London (views are my own etc etc) ...

January 19, 2017

Imagr with target disk mode

Imagr is a great tool when you’re wanting to deploy machines quickly in your office. But sometimes you will want to deploy machines when you’re in a smaller remote site, or a site where security concerns mean you can’t have servers. Imagr is flexible enough to handle this, and with a little creativity, we can deploy at these sites as easily as we can at our offices with NetBoot. Setup The first thing you are going to want to do it get your Imagr repo onto your own machine. I would recommend having your repo in a central repository - git fat works well, so does putting everything on an S3 bucket and using the aws cli tools to sync it down. We use an S3 bucket, as we can ship read only credentials to the machines that are performing the imaging. This guide will assume you are using S3, but you can substitute that aspect for whichever method you wish to sync your files. ...

January 11, 2017