So I comment a lot of lines out in my /etc/hosts file. This usually means that I end up with a lot of cruft at the top of my file. And while I write comments into files and scripts here and there, I don’t always want to see them. So I can grep them out by piping the output of the file to grep as follows:
cat /etc/hosts | grep -v "^#"
You could also do the same, eliminating all lines that start with a “v” instead:
cat !$ | grep -v "^v"
krypted February 13th, 2017
The “What’s New in macOS” page for Sierra (10.12) lays out a little known change that a colleague at Jamf was working on the other day (hat tip to Brock):
Starting in macOS 10.12, you can no longer provide external code or data alongside your code-signed app in a zip archive or unsigned disk image. An app distributed outside the Mac App Store runs from a randomized path when it is launched and so cannot access such external resources. To provide secure execution, code sign your disk image itself using the codesign tool, or distribute your app through the Mac App Store. For more information, see the updated revision to macOS Code Signing In Depth.
This is further explained in the equally misnamed “OS X Code Signing In Depth“:
If using a disk image to ship an app, users should drag the app from the image to its desired installation location (usually /Applications) before launching it. This also applies to apps installed via ZIP or other archive formats or apps downloaded to the Downloads directory: ask the user to drag the app to /Applications and launch it from there.
This practice avoids an attack where a validly signed app launched from a disk image, ZIP archive, or ISO (CD/DVD) image can load malicious code or content from untrusted locations on the same image or archive. Starting with macOS Sierra, running a newly-downloaded app from a disk image, archive, or the Downloads directory will cause Gatekeeper to isolate that app at a unspecified read-only location in the filesystem. This will prevent the app from accessing code or content using relative paths.
The gist is, if an app isn’t signed via the Mac App Store, Gatekeeper is going to limit the ability of the app to launch via “Gatekeeper Path Randomization.” Basically, treat an app from a mounted drive as if it were coming from a Safari download. There are a few ways to distribute app bundles or binaries that do not violate this. One is to sign a disk image that contains such an app:
spctl -a -t open --context context:primary-signature -v /Volumes/MyApp/MyApp.dmg
If spctl runs properly, you should see the following:
/Volumes/MyApp/MyAppImage.dmg: accepted source=mydeveloperid
In the above spctl command, we use the following options:
For more on managing Gatekeeper from the command line, see http://krypted.com/mac-security/manage-gatekeeper-from-the-command-line-in-mountain-lion/.
Another method is to remove the lsquarantine attribute, which is automagically applied, using xattr as follows:
xattr -r -d com.apple.quarantine /Volumes/MyApp/MyAppImage.app
The options in the above use of the xattr command:
Xattr has a lot of different uses; you can programmatically manage Finder tags with it, http://krypted.com/mac-os-x/command-line-finder-tags/. To see the full
xattr dump on a given file, use the -l option as follows:
xattr -l com.apple.quarantine MyAppImage.dmg
The output is as follows:
xattr: No such file: com.apple.quarantine
00000000 62 70 6C 69 73 74 30 30 A1 01 33 41 BE 31 0B A5 |bplist00..3A.1..|
00000010 70 D4 56 08 0A 00 00 00 00 00 00 01 01 00 00 00 |p.V………….|
00000020 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000030 00 00 00 00 13 |…..|
00000000 62 70 6C 69 73 74 30 30 A1 01 5F 10 22 63 69 64 |bplist00.._.”cid|
00000010 3A 69 6D 61 67 65 30 30 31 2E 70 6E 67 40 30 31 |:myappimage.dmg@01|
00000020 44 32 36 46 46 44 2E 35 37 31 30 37 30 46 30 08 |D26FFD.571070F0.|
00000030 0A 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 |…………….|
00000040 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000050 2F |/|
This could be helpful when troubleshooting and/or scripting (or just way too much informations!).
Finally, if you’re an application developer, check out new API for App Translocation in the 10.12 SDK for
<Security/SecTranslocate.h> I guess one way to think of this is… Apple doesn’t want you running software this way any more. And traditionally they lock things down further, not less, so probably best to find alternatives to running apps out of images, from a strategy standpoint.
krypted January 25th, 2017
Apple recently introduced a laptop with the same fingerprint technology found in an iPhone as well as a T-1 chip to take the sapphire Touch ID sensor information and store it securely, non-reversibly(ish), on the machine. OS X 10.12 now comes with a tool that can manage the fingerprints, stored as keys, on the device. The bioutil command is simple to use, with a few options that are mostly useful for enabling different features of the new technology.
Let’s get started by enabling the unlock option, using the -r option to see if Touch ID is enabled for the current user and -s to check the system as well:
bioutil -r -s
Now let’s enable Touch ID to be able to unlock the system, with -u (provided it’s not already enabled):
If you’ll be using ApplePay, also use -a (on a per-user basis):
Next, let’s enables Touch ID to unlock the system for the current user:
bioutil -w -u 1
This user will obviously need to provide their fingerprint in order to use Touch ID. Once done, let’s see how many fingerprints they’ve registered using the -c option (which checks for the number of fingerprints registered by the currently enrolled user):
Now let’s delete all fingerprints for the current user (note that they’re not reversible so you can’t actually look at the contents):
Next, we’ll use sudo to remove all fingerprints for all users (since we’re crossing from user land, we’ll need to provide a password):
sudo bioutil -p -s
Instead, we could have targeted just deleting the fingerprints that had been registered for user 1024, using -s and -d together, followed by the actual UID (which also requires sudo – as with all -s option combos):
sudo bioutil -s -d 1024
Now let’s disable Touch ID for the computer, using -w to write a config, and that -u from earlier, setting it to 0 for off:
sudo bioutil -w -s -u 0
And viola, you’re managing the thing. Throw these in an Extension Attribute or in Munki and you’re managing/checking/knowing/reporting/all the thingsings! Enjoy!
krypted December 16th, 2016
macOS has keychains. Sometimes they’re a thing. When they are you might want to delete them. Let’s say you have an admin account. You want to keep the keychains for that account, but remove all the others. For this, you could do a shell operator to extglob. Or you could do a quick while loop as follows:
ls /Users | grep -v "admin" | while read USERNAME do; rm -Rf "/Users/$USERNAME/Library/Keychains/*" done;
If you borrow this, be careful.
krypted December 1st, 2016
I thought there might be an easier way to do this. So there’s this binary called serverrails that I assumed would install rails – no wait, actually it’s a ruby script that tells me to ‘gem install rails’ – which fails:
cat `which serverrails`
# Stub rails command to load rails from Gems or print an error if not installed.
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
gem 'railties', version or raise
puts 'Rails is not currently installed on this system. To get the latest version, simply type:'
puts ' $ sudo gem install rails'
puts 'You can then rerun your "rails" command.'
load Gem.bin_path('railties', 'rails', version)
Given that doesn’t work, we can just do this the old fashioned way… First let’s update rails to 2.2 or 2.2.4 using rvm, so grab the latest rvm and install it into /usr/local/rvm:
sudo curl -sSL https://get.rvm.io | bash -s stable --ruby
Then fire it up:
sudo source /etc/profile.d/rvm.sh
Then install the latest ruby:
sudo rvm install 2.2
Set it as default:
sudo rvm use 2.2 –default
Then run your gem install:
gem install rails
krypted November 14th, 2016
Recently, I got a strange message when trying to run a command:
You have exceeded the maximum number of shell sessions.
I’d seen a series of commands but never really needed to use them, so I ran:
And viola, life was good. My command run. Of course, the next time I went to close the terminal correctly using the exit command. Upon doing so, I noticed:
…copying shared history…
…saving history…truncating history files…
So, I opened a new shell and ran:
And go the same result. Same with:
krypted November 8th, 2016
Automating OS installations is going to eventually be about as easy on macOS as it is in iOS (er, if you have MDM that is). But in the meantime, it’s getting a bit more challenging. The obvious way Apple would prefer this to happen these days is via the startosinstall command that first shipped with El Capitan and with brtool getting moved around all the time, and becoming less of a thing, there’s one quick and easy thing you can do:
sudo "/Applications/Install macOS Sierra.app/Contents/Resources/startosinstall" --applicationpath "/Applications/Install macOS Sierra.app" --agreetolicense --nointeraction --volume /Volumes/Macintosh\ HD
In the above command, we’ve dropped “Install macOS Sierra.app” on a machine. While you’d guess that it would find the application path based on its own surname, we went ahead and supplied it as that seems to basically be a thing. Basically, –agreetolicense keeps us from having to run some expect scripts to accept a license agreement, –nointeraction suppresses as many of the screens as possible, and –volume allows us to install to any volume we’d like. This isn’t fully automated, but I have been able to layer in some more logic to quit apps before the script fires and then expect out other items from the script to automate a restart, watching for osinstallersetupd as a key.
This is all a bit bulkier than just using something like createOSXinstallPkg but it’s important to mention that there are a number of system components that are allowed for in SIP that use osinstallersetupd and so this blessed mechanism is likely the future until you can trigger an OS upgrade (and update I suppose) using an MDM command.
krypted October 23rd, 2016
The software patching configuration built into most operating systems is configured so that all a user has to do is open a box at home, join the network and start using the computer right away. As environments grow from homes to small offices and then small offices grow into enterprises, at some point software updates and patches need to be managed centrally. OS X Server 5.2 (on Sierra), as with its macOS Server predecessors has a Software Update service. The service in the Server app is known as Software Update and from the command line is known as swupdate.
The Software Update service, by default, stores each update in the /var/db/swupd directory. The Software Update service is actually comprised of three components. The first is an Apache server, invoked by the /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons/com.apple.swupdate.host.plist LaunchDaemon. This LaunchDaemon invokes a httpd process and clients access updates from the server based on a manifest of updates available in the sucatalog.
These are synchronized with Apple Software Updates via /Applications/Server.app/Contents/ServerRoot/usr/sbin/swupd_syncd, the LaunchDaemon for swupdate at /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons/com.apple.swupdate.sync.plist.
Clients can be pointed at the server then via a Profile or using the defaults command to edit the /Library/Preferences/com.apple.SoftwareUpdate.plist file. The contents of this file can be read using the following command:
defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist
To point a client to a server via the command line, use a command such as the following:
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL http://osxserver.krypted.com:8088/index.sucatalog
But first, you’ll need to configure and start the Software Update service. Lucky you, it’s quick (although quick in a hurry up and wait kind of way). To get started, click on the View menu in Server and select the Software Update service.
By default, updates are set to simply mirror the Apple servers, by default, enabling each update that Apple publishes, effectively proxying updates. You can use the Manual button if you would like to configure updates to either manually be approved and manually synchronized or just manually approved but automatically copied from Apple. Otherwise click on the ON button and wait for the updates to cache to simply mirror the Apple servers. If you would like to manually configure updates, click on the Manual option and then click on the Updates tab.
The first item in the Updates tab is the “Automatically download new updates” checkbox. This option downloads all of the updates but does not enable them. The Updates tab also displays all available updates. click on one and then click on the cog-wheel icon towards the bottom of the screen to configure its behavior (Download, Enable, Disable, Remove and View Update).
Note: The only option for updates in an Automatic configuration environment is disable.
The service can be managed using serveradmin. To start Software Update, use the start option, followed by the swupdate service identifier:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin start swupdate
To stop the service, replace start with stop:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin stop swupdate
To see the status of the service, including the location of updates, the paths to log files, when the service was started and the number of updates running, use the fullstatus option:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin fullstatus swupdate
The output of which appears as follows:
swupdate:state = "RUNNING"
swupdate:lastChecktime = 2016-08-07 01:25:05 +0000
swupdate:syncStatus = "INPROGRESS"
swupdate:syncServiceState = "RUNNING"
swupdate:setStateVersion = 1
swupdate:lastProductsUpdate = 2016-08-16 04:02:16 +0000
swupdate:logPaths:swupdateAccessLog = "/var/log/swupd/swupd_access_log"
swupdate:logPaths:swupdateErrorLog = "/var/log/swupd/swupd_error_log"
swupdate:logPaths:swupdateServiceLog = "/var/log/swupd/swupd_syncd_log"
swupdate:readWriteSettingsVersion = 1
swupdate:pluginVers = "10.12"
swupdate:checkError = no
swupdate:updatesDocRoot = "/Library/Server/Software Update/Data/" swupdate:hostServiceState = "RUNNING" swupdate:autoMirror = no swupdate:numOfEnabledPkg = 0 swupdate:servicePortsAreRestricted = "NO" swupdate:numOfMirroredPkg = 0 swupdate:autoMirrorOnlyNew = no swupdate:startTime = 2016-08-07 01:25:05 +0000 swupdate:autoEnable = no
There are also a number of options available using the serveradmin settings that aren’t exposed to the Server app. Available Settings include:
swupdate:checkError = no
swupdate:limitBandwidth = no
swupdate:PurgeUnused = yes
swupdate:portToUse = 8088
swupdate:autoEnable = yes
swupdate:valueBandwidth = 0
swupdate:syncStatus = “Initializing”
swupdate:autoMirror = yes
swupdate:syncBandwidth = 0
swupdate:updatesDocRoot = “/Library/Server/Software Update/Data/”
swupdate:autoMirrorOnlyNew = no
These include a feature I used to use a lot in the beginning of deployments with poor bandwidth, only mirroring new updates, which is available to swupdate via the autoMirrorOnlyNew option. To configure:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:autoMirrorOnlyNew = yes
Also, the service can throttle bandwidth for clients. To use this option, run the following command:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:limitBandwidth = yes
And configure bandwidth using the syncBandwidth option, as follows:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:syncBandwidth = 10
To automatically sync updates but not enable them (as the checkboxes allow for in the Server app, use the following command:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:autoEnable = no
The port (by default 8088) can be managed using the portToUse option, here being used to set it to 80 (clients need this in their catalog URL from here on out):
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:portToUse = 80
Finally, administrators can purge old packages that are no longer needed using the PurgeUnused option:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings swupdate:PurgeUnused = yes
One of the biggest drawbacks of the Software Update is the fact that it does not allow for serving 3rd party packages (not that Apple has much control over this, since these aren’t sourced from the App Store) from vendors such as Microsoft or Adobe. To provide those vendors with a manifest file and a quick little path option to add those manifest files while doing a little man in the middle protection would be a nice middle ground between the Mac App Store and the built in software update options in macOS. But then, we wouldn’t want to make it too easy. I don’t know, maybe by creating the Caching service… 😉
krypted October 10th, 2016
Apple developers in growing development teams invariably need a continuous integration system. This automates the build, analysis, and testing solution for software development using Xcode. macOS Server has an Xcode service, capable of integrating your developer account with git, providing many of the options required to build a continuous integration system.
Before you configure the Xcode service that can take committed code and then test and build your software, you’ll need an Apple developer account. The Xcode service then links git to a developer account and runs automations, referred to as bots, in Xcode. Therefore, you’ll also need to have Xcode installed on the computer running the Xcode service. Bots are then managed and reported on using a web app that the Server app runs.
Once the pre-requisites are met, open the Server app and click on the Xcode service.
Click on the Choose Xcode button.
When prompted, browse to the version of Xcode you have installed on the server.
Configure the user account to use for the service.
The service will then require you to login. Do so when prompted.
This enables the user account, which you will then need to login as.
You’ll see a new user environment. Use fast user switching to then switch back to your other account. Xcode will require access to the Accessibility framework to run unit tests. Click on Request Access to provide the rights to Xcode to do so. Once access has been granted to Xcode, you’ll see the version indicated in the Build Using field.
Next, click on Add Team, in order to identify the correct team from your Apple Developer account that will have access to the Xcode service.
When prompted, select the team from your Apple Developer account that you wish to provide access to the server, note that you need to be a team agent or an administrator of the developer organization.
Click on the Repositories tab. Here, you will define repositories for your Xcode projects. Click on the Repository Access button to define what protocols git should be accessible via.
At the Repository Access screen, select HTTPS or SSH. Click OK.
Click the Edit Repository Creators button. At the Repository Access screen, add any groups of users that should have access to create new git repositories. Once all of the appropriate users or groups have been added, click on OK.
Select your repository again, and click on the HTTPS Access button to provide access via HTTPS. Once saved, double-click on the repository again to see the uri for each type of access. And that’s it.
Next, you’ll want to add a repository to the Xcode app. To do so, open Xcode and then use the Source Control menu to select Check Out. From there, you’ll get a Check Out screen.
At the Check Out screen, enter the uniform the repository screen, shown in the previous step of this article and click on the Next button. Next, you’ll need to create bots to automate your build process.
krypted October 8th, 2016
There are a couple of ways to create groups in macOS Server 5.2, running on Sierra. The first is using the Server app, the second is using the Users & Groups System Preference pane and the third is using the command line. In this article we will look at creating groups in the directory service with the Server app.
Once a server has been an Open Directory Master all user and group accounts created will be in the Local Network Group when created in Server app. Before that, all user and group objects are stored locally when created in Server app. Once promoted to an Open Directory server, groups are created in the Open Directory database or if you select it from the directory domain drop-down list, locally. Groups can also be created in both locations, using a command line tool appropriate for group management.
Once changes have been made, click Done to commit the changes.
krypted October 7th, 2016
Posted In: Mac OS X Server