Google Chrome update notifications with Yo

Web browsers are critical to pretty much any organization. For many people, the browser is everything, right down to their email client. Since the browser is probably the most used piece of software, and users are putting all kinds of private information into it, it’s vital browsers are kept patched. Fortunately our default browser is Google Chrome, and Chrome is really good at keeping itself updated. Unfortunately it completely sucks at letting the user know that there is an update to install. I mean really, we’re just going to leave it at three tiny lines changing from grey to orange? ...

March 14, 2018

MacAD.UK 2018: Curing operating system blindness

Thanks to those who came to our talk yesterday (if you did come, I don’t blame you, the other talk was much better). If you feel so inclined, here are the slides.

February 21, 2018

Custom DEP Packages

I’m sure everyone who didn’t have an MDM a few weeks ago is scrambling to get one set up - I’m not going to go into anything about MDM, since it really isn’t that interesting. They install profiles and packages - all very unexciting. This article will take you through some of the decisions we made when developing our DEP enrollment package. First attempt If you are of the open source management tool persuasion, chances are that like me, you are very happy with what you have already and see MDM merely as a method for delivering those tools. Before we considered MDM, our deployment workflow was essentially: Imagr lays down a base image Imagr installs Google’s Plan B Plan B install Puppet Puppet performs the configuration As part of that configuration, Puppet installs Munki Munki installs the software So on the face of it, it looked pretty simple for us to use our existing Plan B package with InstallApplication via an MDM. DEPNotify DEPNotify is a great tool by Joel Rennich - you can pass in various commands and it will let your users know what is going on. So we would open up DEPNotify and then kick off our Plan B installation. Which could sit there for 10 minutes without letting the user know what was going on other than “something is happening”. Whilst this obviously wasn’t a great experience for our users, it got the job done. First optimization Rather than make our users sit there and twiddle their thumbs whilst their computer sorted it’s life out, stopped and though about what our users needed to do first off. From our perspective, we really wanted the computer encrypyed before they did anything, and we needed them to get going with our SSO solution and change their password, set up 2FA etc. So this boiled down to two basic requirements: Install Chrome - this is where the majority of ‘IT Time’ is spent during onboarding, so there was no need to wait for Munki to finally put it there. Install and configure Crypt - let’s get the disruptive logout out of the way and let the user use their computer undisturbed. ...

December 20, 2017

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