I recently worked on something where a design requirement was to build a good snapshot restore option but not to use Time Machine backups. You can capture a snapshot of a Mac without enabling Time Machine. To do so, you’d still use the same binary as you would with Time Machine, /usr/bin/tmutil. To do so, simply use the snapshot verb as follows:
Once you’ve run that, you get output similar to the following:
Created local snapshot with date: 2019-04-12-110248
Now when it comes to making it simple for end user restores, there’s a few gaps. The first is that you have to boot with Command-R and can’t build a scripted restore option. So the following won’t work on a machine with SIP:
sudo nvram boot-args="-x"; restart
You can prune the list of snapshots so it’s simple for a user to pick the right one though. To see a list of all your snapshots for the current boot volume, use that listlocalsnapshots verb:
tmutil listlocalsnapshots /
This provides the output as com.apple.TimeMachine.2019-04-12-110248 and when deleting snapshots you don’t need the com.apple.TimeMachine. portion of that string, so to delete the last snapshot we’ll gather it into a variable with the following:
Alternatively you can list snapshots with the diskutil command, using the apfs option and listSnapshots verb, followed by your boot volume as follows, but the output isn’t pretty:
diskutil apfs listSnapshots disk1s1
Once you’ve parsed the service name portion out, you can then delete a given snapshot using the deletelocalsnapshots verb with tmutil:
tmutil deletelocalsnapshots 2019-04-12-110248
Or to use that snapshot variable:
tmutil deletelocalsnapshots $snapshot
So I can present the user, when they try to revert, with a shorter list of snapshots, hopefully helping them to select the right one. But, I can only do a scripted restore if I’m actually using Time Machine and I have a volume taking those backups. If I’m doing a snapshot restore I have to restart the Mac holding down the command- R keys and then once booted in recovery mode, select the snapshot and wait for the restore.
Booting into recovery mode takes a long time so seems like something you’d teach the desktop techs to do rather than expect users to do a-la-“Erase all Contents and Settings” button. The whole process takes about 20 minutes because of how long it takes to boot into this state and revert.
It’s actually just as quick to do a full reinstallation. This can be as simple as using the startosinstall --eraseinstall command, which provides a number of options. It seems silly to load up a whole new operating system when you have one there, but assuming you have decent internet speeds, it’s just as fast to do so. There’s even a gui wrapper for it to make the whole process easier for your users at https://scriptingosx.com/2018/10/eraseinstall-application/ which could then be provided in tools like Managed Software Center and Self Service. You could also try and remove all user and app data using a script but that has turned out to be a lot of moving parts that requires constant updates.
If you were to opt into a snapshot-based restore option, it’s also worth noting that if you have outdated certificates, outdated passwords, outdated software, etc, that it can be problematic. So we’re pretty much right back to erase-install.
Other people have gone down this same rabbit hole:
So my initial goal was to create an article on doing an elegant restore process for the Mac, where you script more of it and provide a better experience. But alas, I have failed ya’. Sorry. Do you have a better way? If so, please comment!
Encrypting a volume in OS X Mountain Lion couldn’t be easier. In this article, we will look at three ways to encrypt OS X Lion volumes. The reason there are three ways is that booted volumes and non-booted volumes have different methods for enabling encryption. The third way to enable encryption on a volume is to do so through
Encrypting Attached Storage
For non-boot volumes, just control-click or right-click on them and then click on Encrypt “VOLUMENAME” where the name of the volume is in quotes.
When prompted, provide an encryption password for the volume, verify that password and if you so choose, provide a hint.
Once the encryption process has begun, the entry previously clicked on says Encrypting “VOLUMENAME” where the name of the volume is in quotes.
Before you can encrypt a volume from the command line you must first convert it to CoreStorage if it isn’t already. As volumes on external disks aren’t likely to be CoreStorage, let’s check using diskutil along with corestorage and then list:
diskutil corestorage list
Assuming your volume was already formatted with a non-corestorage format and isn’t listed, locate the volume and document the disk identifier (in this case disk2s3). Then, run diskutil corestorage along with the convert verb and the disk, as follows (no need to run this command if it’s already listed):
sudo diskutil corestorage convert disk2s3
The output should look similar to the following:
Started CoreStorage operation on disk2s3 Reco
Resizing disk to fit Core Storage headers
Creating Core Storage Logical Volume Group
Attempting to unmount disk2s3
Switching disk2s3 to Core Storage
Waiting for Logical Volume to appear
Mounting Logical Volume
Core Storage LVG UUID: 19D34AAA-498A-44FC-99A5-3E719D3DB6FB
Core Storage PV UUID: 2639E13A-250D-4510-889A-3EEB3B7F065C
Core Storage LV UUID: 4CC5881F-88B3-42DD-B540-24AA63952E31
Core Storage disk: disk4
Finished CoreStorage operation on disk2s3 Reco
Once converted, the LV UUID (LV is short for Logical Volume) can be used to encrypt the logical volume using a password of crowbar to unlock it:
sudo diskutil corestorage encryptvolume 4CC5881F-88B3-42DD-B540-24AA63952E31 -passphrase crowbar
The output is similar to the following:
Started CoreStorage operation on disk4 Reco
Scheduling encryption of Core Storage Logical Volume
Core Storage LV UUID: 4CC5881F-88B3-42DD-B540-24AA63952E31
Finished CoreStorage operation on disk4 Reco
According to the size, this process can take some time. Monitor the progress using the corestorage list option:
diskutil corestorage list
In all of these commands, replace core storage w/ cs for less typing. I’ll use the shortened version as I go. I know that we rarely change passwords, but sometimes it needs to happen. If it needs to happen on a core storage encrypted volume, this can be done from the command line or a script. To do so, use diskutil cs with the changevolumepassphrase option. We’ll use -oldpassphrase to provide the old password and -newpassphrase to provide the new passphrase.
diskutil cs changeVolumePassphrase FC6D57CD-15FC-4A9A-B9D7-F7CF26312E00 -oldpassphrase crowbar -newpassphrase hedeservedit
I continue to get prompted when I send the -newpassphrase, so I’ve taken to using stdin , using -stdinpassphrase. Once encrypted there will occasionally come a time for decrypting, or removing the encryption, from a volume. It’s worth noting that neither encrypting or decrypting requires erasing. To decrypt, use the decryptVolume verb, again with the -passphrase option:
diskutil cs decryptvolume 4CC5881F-88B3-42DD-B540-24AA63952E31 -passphrase crowbarFileVault 2: Encrypting Boot Volumes
Boot volumes are configured a bit differently. This is namely because the boot volume requires FileVault 2, which unifies usernames and passwords with the encryption so that users enter one username and password rather than unlocking drives. To configure FileVault 2, open the Security & Privacy System Preference pane and then click on the FileVault tab. Click on the lock to make changes and then provide the password for an administrative account of the system. Then, click on “Turn On FileVault…”
When prompted with the Recovery Key, document it and then click on
Choose whether to restore the recovery key with Apple. If you will be storing the key with Apple then provide the AppleID. Otherwise, simply click the bullet for “Do not store the recovery key with Apple” and then click on the Continue button.
When prompted, click on Restart to reboot and be prompted for the first account that can unlock the FileVaulted system.
Once encrypted, the FileVault tab in the Security & Privacy System Preference pane shows the encryption status, or percent during encryption.
Use the Enable Users… button to enable additional accounts to unlock the volume (note: by default accounts cannot login until their account has been added here).
That’s it. Managing FileVault 2 using the System Preferences is about as easy as it can get. But for those who require mass management, Apple has provided a tool called fdesetup for that as well.
Using fdesetup with FileVault 2
FileVault 2 now comes with a nifty configuration utility called fdesetup. To use fdesetup to encrypt the boot volume, first check FileVault’s status by entering the fdesetup command along with the –status option (wait, no — required any more!):
As with most other commands, read the help page before starting to use just in case there are any changes to it between the writing of this article and when you kick off your automated encryption. Done using the help verb:
After confirming FileVault is off, enable FileVault with the enable option, as follows:
sudo fdesetup enable
Unless additional parameters are specified, an interactive session prompts for the primary user’s short name and password. Once enabled, a Recovery key is returned by the fdesetup command. You can also cancel this by just hitting Control-C so we can look at more complicated iterations of the command. It should be recorded or otherwise stored, something easily done by mounting in a script (e.g. a write-only share in a script for key escrowing). If more complicated measures are needed, of course check out Cauliflower Vest at code.google.com. As fdesetup is in its first version, I find it amusing that it’s actually 1.3 as indicated using:
Now, if you run fdesetup and you’ve deployed a master keychain then you’re going to have a little more work to do; namely point the -keychain command at the actual keychain. For example:
sudo fdesetup enable -keychain /Library//Keychains/FileVaultMaster.keychain
To define a certificate:
sudo fdesetup enable -certificate /temp/filename.cer
Adding additional users other than the one who enabled fdesetup is a bit different than the first:
sudo fdesetup add -usertoadd robin
To remove users, just remove them with a remove verb followed by the -user option and the username:
sudo fdesetup remove -user robin
The remove and add options also offer using the -uuid rather than the username. Let’s look at Robin’s uid :
dscl . read /Users/robin GeneratedUID | cut -c 15-50
Yes, I used cut. If you have a problem with that then take your judgmental fuc… Nevermind. Take that GUID and plug it in as the uuid using the -uuid option. For example, to do so with the remove verb:
sudo fdesetup remove -uuid 31E609D5-39CF-4A42-9F24-CFA2B36F5532
Or for good measure, we can basically replicate -user w/ -uuid for a nice stupid human trick:
sudo fdesetup remove -uuid `dscl . read /Users/robin GeneratedUID | cut -c 15-50`
All of the fdesetup commands can be run interactively or using options to define the variables otherwise provided in the interactive prompt. These are defined well in the man page. Finally, let’s look at -defer. Using -defer, you can run the fdesetup tool at the next login, write the key to a plist and then grab it with a script of some sort later. At logout, the user will get prompted for a
sudo fdesetup enable -defer /temp/fdesetupescrow.plist
Or define users concurrently (continuing to use the robin test user):
sudo fdesetup enable -user robin -defer /temp/fdesetupescrow.plist
FileVault accounts can also use accounts from Directory Services automatically. These need to synchronize with the Directory Service routinely as data is cached. To do so:
sudo fdesetup sync
This is really just scratching the surface of what you can do with fdesetup. The definitive source for which is the man page as well as a nicely done article by Rich Trouton (who I think I will start calling Trouty-mouth after having watched the Glee episode where one of the girls says that).
Encrypting Time Machine Backups
The last full disk encryption to discuss is Time Machine. To encrypt Time Machine backups, use Time Machine’s System Preference pane. The reason for this being that doing so automatically maintains mounting information in the Operating System, rather than potentially having an encrypted drive’s password get lost or not entered and therefore not have backups run.
To enable disk encryption for Time Machine destinations, open the Time Machine System Preference pane and click on Select Backup Disk… From the backup disk selection screen, choose your backup target and then check the box for “Encrypt backups”. Then, click on Use Disk.
At the overlay screen, provide a backup password twice and if you would like, a hint as to what that password is. When you are satisfied with your passwords, click on the Encrypt Disk button.
Now, there are a couple of things to know here. 1. Don’t forget that password. 2. If you use an institutional FileVault Key then still don’t forget that password as it will not work. 3. Don’t forget that password…
Encrypting data in OS X can take on other forms as well. The keychains encrypt passwords and other objects. Additionally, you can still create encrypted dmgs and many file types have built in encryption as well. But the gist is that Apple encrypts a lot. They also sandbox a lot and with the addition of gatekeeper are code signing a lot. But encrypting volumes and disks is mostly about physical security, which these types of encryption provide a substantial solution for.
While all this security might seem like a lot, it’s been in Apple’s DNA for a long time and really security is about layers and the Mac Systems Administrator batbelt needs a lot of items to allow us to adapt to the changing landscape of security threats. OS X is becoming a little more like iOS as can be expected and so I would suspect that encryption will become more and more transparent as time goes on. Overall, the options allow encrypting every piece of data that goes anywhere near a system. The mechanisms with which data is now encrypted are secure, as is the data at rest. Once data is decrypted, features like Gatekeeper and the application layer firewall supplement traditional network encryption to keep well secured.
DeployStudio has the ability to rename volumes as part of a standard workflow. These are typically set to something like “Macintosh HD” (the default) or “Computer Lab” or something like that. But what if you wanted to name the volume something unique to a given computer, which makes it easier to keep track with what you are doing across a number of servers? You could create a workflow for each computer and change the hard drive name for each to something unique; but that would be tedious and pollute your list of workflows, likely resulting in accidentally running the wrong workflow at times. Instead, you could look at a really simple script in most cases (according to how complicated your logic for assigning names would be).
To rename a volume, you can use the diskutil command along with the rename option. You would then list the existing name followed by the new name that you’d like that volume to have. In the case of DeployStudio the initial name of your boot volume might be “Macintosh HD” and to change the name to something like “Computer Lab” you would then use a command like:
diskutil rename Macintosh HD Computer Lab
It might then be logical to use a host name to rename a computer. Therefore, we could replace Computer Lab with the hostname command like so:
diskutil rename Macintosh HD `hostname`
However, this ends up showing the fully qualified name. Therefore, we could replace hostname with an scutil query for the ComputerName:
diskutil rename Macintosh HD `scutil –get ComputerName`
This would result in the name without all the .local, etc. But if you ran this as part of a DeployStudio workflow, you would end up calling the hard drive for all of your machines localhost. This is because the hostname or ComputerName will be queried from the DeployStudio set that you are booted to for running the DeployStudio Runtime. Luckily, DeployStudio has a number of variables that it can use in scripts. One of them is DS_HOSTNAME, which pulls the ComputerName being applied to the system at imaging. This means that if we were to rename the hard drive of the computer from Macintosh HD to the DS_HOSTNAME, you could use the following script:
diskutil rename /Volumes/Macintosh HD $DS_HOSTNAME
Now, one might think to oneself, couldn’t I just put $DS_HOSTNAME in the field for renaming the hard drive (part of a workflow). I tried it a number of different ways and couldn’t get it to work (in parenthesis, quoted out different kinds of ways, in different types of brackets and combinations of the above). If anyone knows of a way to use a variable in a GUI field within DeployStudio, let me know (I am guessing it can be done).
Disk Utility has a nifty little button to Verify Disk Permissions and another to Repair Disk Permissions. Many use this frequently over the course of basic Mac OS X troubleshooting.
The underlying functionality is also exposed at the command line. Diskutil (located in /usr/sbin) has the verifyPermissions and repairPermissions, which roughly correspond to the buttons in Disk Utility. Because these can be run against different disks, each will need the volume indicated following the verb. For example, to run a Verify Disk Permissions against a volume called Seldon, you would use the following command:
diskutil verifyPermissions /Volumes/Seldon
To then run a Repair Disk Permissions on that same volume, you would use:
diskutil repairPermissions /Volumes/Seldon
In most cases, repairPermissions is done to the currently booted volume. To find this volume, you can use the bless command along with the –getBoot option. For example:
Bless will then respond with the device that comprises your boot volume. To convert this into a path that can be used with diskutil, you would use the diskutil command followed by info followed by the output of the bless command. For example, if the device were /dev/disk0s2 then you would run the following:
diskutil info /dev/disk0s2
You could then script a repair permission of the boot volume using the following, which would also dump the output into a log file:
Placing this script into a package would then allow for sending a Repair Disk Permissions command to client computers though, let’s say, ARD or even allow a user to run it themselves using the JAMF self-service client. All without having to leave ones chair or provide an administrative password to a user (having said this the script will require local administrative privileges).
When new versions of operating systems come out sometimes articles need to be updated. It’s always nice when someone else does the hard part. Recently, Ben Levy, an Apple Consultant from Los Angeles, did some work on an article I did awhile back. To quote Ben, the new procedure is to:
1. Boot from something other than your intended RAIDed boot drive, open Terminal and use diskutil list to identify the relevant disks and partitions.
2. diskutil appleRAID enable mirror disk0s2 – (assuming correctly identified slice, yours may be different) This command turns your primary disk into a RAID mirror without a mirror
3. Reboot back to your boot drive
4. diskutil checkRAID and diskutil list just so you know where and what everything is…
5. diskutil AppleRAID add member disk2 8014A446-E10D-4BC9-A199-67362E54FB7C – (assuming disk2 is in fact the drive you are adding) the UUID is the UUID of the RAID as discovered in checkRAID
6. diskutil checkRAID should now show it rebuilding the RAID. This could take hours. You can check on the progress again using the same command.
Thanks to Ben for the hard work. Now, I think it’s about time I wrapped this into a GUI app…
One of those security things that pops up every now and then is to use the secure erase feature of Mac OS X, located in Disk Utility. But you can access this same feature from the command line using the secureErase option in diskutil followed by the freespace option.
The format of the command is:
diskutil secureErase freespace [level] [device]
The levels are as follows (per the man page as not all of these are specified in Disk Utility):
Single-pass zero-fill erase
Single-pass random-fill erase
US DoD 7-pass secure erase
Gutmann algorithm 35-pass secure erase
US DoE algorithm 3-pass secure erase
So for example, let’s say you had a volume called Seldon and you wanted to do a standard Single-pass zero-fill erase. In this example you would use the following:
diskutil secureErase freespace 0 /Volumes/Seldon
If you were to automate the command then you would want to dump the output into a log file. For example: