I previously wrote about how to make Mac OS’s FileVault disk encryption feature use separate passwords for unlocking the disk and logging into the system once it is running. This allows for better separation of concerns, but it goes against the proverbial grain, as the front end for FileVault tries its best to keep the passwords for unlocking the disk in sync with passwords for user accounts in an effort to keep people from locking themselves out of their machines.
This design remains true today, though the tech is different: rather than using HFS+ volumes and Core Storage volume groups, Mac OS now uses APFS volumes and APFS containers to do the same job. Surprisingly, the main roadblock that caused me to write this article is not the new storage back end, but rather several changes to Mac OS 10.14 that make it far more aggressive about the way it handles FileVault passwords:
- When initial setup runs from a FileVault-encrypted disk, it refuses to create the first user unless it can also add that user to FileVault.
fdesetup, the tool for managing users on FileVault volumes, refuses to delete the last user from a volume even if that volume has a disk password.
- The boot-time program that unlocks the disk refuses to allow one to enter a disk password at all if the volume has any users.
- You cannot add a disk password to a volume with users.
Previously, one could simply install the system as usual and delete the user created during initial setup, but these changes now make that impossible. I worked around this by skipping initial setup entirely.
Create an APFS container and volume
APFS is similar to ZFS and btrfs in that formatting a partition with it creates a container and carves that up into thin volumes that occupy only the space that their contents need. An APFS volume can optionally reserve a minimum amount of space or specify a maximum that it is allowed to take, but by default it has neither. Creating an APFS container and an encrypted volume to install Mac OS onto is simpler than it was with Core Storage, taking only two commands while booted into an installer disk:
# diskutil apfs createcontainer disk0s2 Creating container with disk0s2 Started APFS operation on disk0s2 Untitled Creating a new empty APFS Container Unmounting Volumes Switching disk0s2 to APFS Creating APFS Container Created new APFS Container disk1 Disk from APFS operation: disk1 Finished APFS operation on disk0s2 Untitled # diskutil apfs addvolume disk1 apfs 'Macintosh HD' -passprompt Passphrase: Repease passphrase: Exporting new encrypted APFS Volume "Macintosh HD" from APFS Container Reference disk1 Started APFS operation on disk1 Preparing to add APFS Volume to APFS Container disk1 Creating APFS Volume Created new APFS Volume disk1s1 Mounting APFS Volume Setting volume permissions Disk from aPFS operation: disk1s1 Finished APFS operation on disk1
Though the underlying technology is different, logically, this setup is largely the same as what we had before.
# diskutil apfs list APFS Container (1 found) | +-- Container disk1 1AA9AEE4-521E-4AA6-9BA9-08FD20DBF6AE ==================================================== APFS Container Reference: disk1 Size (Capacity Ceiling): 380295426048 B (380.3 GB) Capacity In Use By Volumes: 149790720 B (149.8 MB) (0.0% used) Capacity Not Allocated: 380145635328 B (380.1 GB) (100.0% free) | +-< Physical Storage disk0s2 B0646769-963F-4322-89A5-4D2E63510C70 | ------------------------------------------------------------- | APFS Physical Store Disk: disk0s2 | Size: 380295426048 B (380.3 GB) | +-> Volume disk1s1 6296A941-52A6-42DF-93C6-363944FA5DB0 --------------------------------------------------- APFS Volume Disk (Role): disk1s1 (No specific role) Name: Macintosh HD (Case-insensitive) Mount Point: /Volumes/Macintosh HD Capacity Consumed: 20480 B (20.5 KB) FileVault: Yes (Unlocked)
Now that the machine has an encrypted volume to install to, return to the installer and install Mac OS onto it. Once it is installed it will prompt for the disk password and then boot into initial setup.
Create the first user by hand
We can’t use the machine without creating a user, but if we proceed through the setup process to create one it will prompt for the disk password, add the new user to FileVault, and we will be stuck with it since we can’t remove it. Stuck between a rock and a hard place, we have little choice but to bypass this setup process entirely and try and replicate what it does by hand. Turn the machine off by quitting the installer with Command+Q, then reboot into single-user mode by holding Command+S and turning it back on again.
Once booted into single-user mode (note that since we didn’t create a user the disk password still works), we get to add the initial user by hand. This is a more ardurous process than it is on most other unix-ish systems because Mac OS stores user accounts in a directory service that it runs locally, similar to if a Linux machine were to run a small OpenLDAP instance instead of using
group(5)files. This service does not run in single user mode, so we need to remount the disk for writing and start it.
# mount -uw / # launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist
Then add the bits that comprise a user account, one at a time. This will show some errors that appear to be there because the file name from the previous command is new in version 10.14 and the
dsclcommand was never updated to address the change.
# dscl . -create /Users/gholms # dscl . -create /Users/gholms UserShell /bin/zsh # dscl . -create /Users/gholms RealName "gholms" # dscl . -create /Users/gholms UniqueID 501 # dscl . -create /Users/gholms PrimaryGroupID 20 # dscl . -create /Users/gholms NFSHomeDirectory /Local/Users/gholms
UniqueID, the user’s ID number, can be any number greater than 500. The setup program normally uses 501 for the first user, so we do, too. The
PrimaryGroupIDof 20 corresponds to the
staffgroup that all local users belong to.
/Localportion of the home directory looks a bit strange, but it is mandatory and the new user will not be able to log in if it isn’t there.
Next, set a password for the new user and add that user to the
# dscl . -passwd /Users/gholms # dscl . -append /Group/admin GroupMembership gholms
Admin users on Mac OS are typically members of far more than just the
admingroup. Skipping them may break some things, but I don’t log in using the admin account on my machine and it has yet to cause me any issues. Just be warned that it is not quite a stock configuration.
After this, create the new user’s home directory.
# install -d -o 501 -g 20 /Users/gholms
Finally, tell the system that initial setup has already run and then reboot.
# touch /private/var/db/.AppleSetupDone # reboot
After reaching this point I unlocked the disk using the disk password, logged in as the new admin user, then created a non-admin user using System Preferences as usual.
Ultimately, it is still possible to continue using a disk password to boot Mac OS, but the tooling in 10.14 is far more hostile to it. To make matters worse, it does not appear to be possible to add recovery keys to such disks either:
# fdesetup changerecovery -personal Enter the user name:
Apple’s intentions are certainly good — after all, they are simply trying to keep people from locking themselves out of their data by doing things that they don’t understand. Apple’s mistake in this release was to stop treating disk passwords and user passwords as equals and instead to consider disk passwords a degenerate case. That said, Apple could still make this scenario less painful without compromising this goal by making a few small tweaks:
- Allow one to add a recovery key to a volume with no users. A recovery key can only make it harder to lock oneself out because it provides an additional means of unlocking the disk.
- Allow disk passwords to unlock the disk even when user passwords are present. Again, as an additional means of unlocking the disk this can only make it more difficult to lock oneself out.
- Allow one to delete the last user on a volume when a disk password is present. Disk passwords are not normally present on the boot volume, so when one is there it is there intentionally and one should be able to use it.
- Do not insist on adding the initial user to a volume during system setup when a disk password is present. Again, when a disk password is present it is there for a reason and should be usable.
It is my hope that future releases of Mac OS will make separate FileVault disk passwords easier to manage than they are today, or at the very least, not make them more difficult. Disk passwords and user passwords are both useful use cases, and it is possible to support them equally without compromising the user experience for the majority who use only user passwords or making it easier for them to shoot themselves in the feet. Either way, at the moment this process seems to work. Documenting it is sure to help someone else out there who has the same needs as me.
To unlock a disk that is encrypted with OS X’s FileVault feature one needs to type in the password that belongs to any user on the machine who is allowed to unlock the disk. The system then boots and helpfully logs you in as that user. In general that is probably a convenient little feature, but for me it just makes things awkward – I want to use different passwords for unlocking the disk and logging into my user account. To make that work I have to create a second account dedicated to unlocking the disk, get logged into that one when the system boots, then immediately log back out so I can log in as the user I actually want to use.
Or do I?
The system that powers FileVault, Core Storage, combines full disk encryption and some logical volume management features in a manner similar to LVM and LUKS on Linux. As a dedicated user of those features on my Linux-based machines, I jumped at the chance to read more about OS X’s version only to discover next to no official documentation whatsoever. On the bright side, after searching some more and then playing around with it for a while I finally figured out how to make it do everything I wanted it to do, including using a disk password. You just have to boot into recovery (or, in my case, the OS X 10.9 install DVD that I threw together) and use the command line.
Create a partition
Since this is a laptop I want to put everything on one huge partition. The utility that handles nearly everything related to disk management on OS X,
diskutil, requires us to choose a type of filesystem for every partition we tell it to create, so for now we’ll just tell it to mark the partition as HFS+ and not bother to format it.
# diskutil partitiondisk disk0 1 gpt jhfs+ %noformat% 100% Started partitioning on disk0 Unmounting disk Creating the partition map Waiting for the disks to reappear Finished partitioning on disk0 /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *256.1 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_HFS 255.7 GB disk0s2
The system actually created two partitions for us. The first is a small EFI system partition, which helps the system start, and the second is the big partition for our data that spans the rest of the disk.
Or does it?
# gpt show disk0 start end index contents 0 1 PMBR 1 1 Pri GPT header 2 32 Pri GPT header 34 6 40 409600 1 GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B 409640 499446368 2 GPT part - 48465300-0000-11AA-AA11-00306543ECAC 499856008 262151 500118159 32 Sec GPT table 500118191 1 Sec GPT header
It seems to have left a little empty space in between the last partition and the boilerplate bits at the end of the disk. More on that later.
Create a volume group
The next step is quite familiar to LVM users. Before we can add encryption we need to create a logical volume group that combines one or more partitions (physical volumes) into a single virtual “disk” that we can slice up.
Why more than one disk? That’s how Fusion Drive works.
# diskutil cs create vg_sodium disk0s2 Started CoreStorage operation Touching partition type on disk0s2 Adding disk0s2 to Logical Volume Group Creating Core Storage Logical Volume Group Switching disk0s2 to Core Storage Waiting for Logical Volume Group to appear Discovered new Logical Volume Group "A642DBC3-644C-4C23-8337-ADBCDD9C85F2" Core Storage LVG UUID: A642DBC3-644C-4C23-8337-ADBCDD9C85F2 Finished CoreStorage operation # diskutil cs list CoreStorage logical volume groups (1 found) | +-- Logical Volume Group A642DBC3-644C-4C23-8337-ADBCDD9C85F2 ========================================================= Name: vg_sodium Status: Online Size: 255716540416 B (255.7 GB) Free Space: 255380987904 B (255.4 GB) | +-< Physical Volume A39FA7E9-F52F-4FFA-9A70-F07304111115 ---------------------------------------------------- Index: 0 Disk: disk0s2 Status: Online Size: 255716540416 B (255.7 GB) # diskutil list disk0 /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *256.1 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_CoreStorage 255.7 GB disk0s2 3: Apple_Boot Boot OS X 134.2 MB disk0s3
This changed the type of the second partition and constructed a volume group out of it, but it also created a third partition on which it can put whatever minimal data are needed to allow the system to boot from a Core Storage volume. With a quick look at the partition table we can see that it carved this out of the space it reserved at the end of the disk earlier:
# gpt show disk0 start end index contents 0 1 PMBR 1 1 Pri GPT header 2 32 Pri GPT header 34 6 40 409600 1 GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B 409640 499446368 2 GPT part - 48465300-0000-11AA-AA11-00306543ECAC 499856008 262144 3 GPT part - 426F6F74-0000-11AA-AA11-00306543ECAC 500118152 7 500118159 32 Sec GPT table 500118191 1 Sec GPT header
Create a logical volume
LVM has three layers: physical volumes, volume groups, and logical volumes. Since Core Storage includes encryption it adds a fourth layer, the logical volume family, between the volume group and logical volume levels. When you boot a FileVault-enabled system it’s the volume family that your password unlocks. The final step before we can install OS X is to create an encrypted volume family and the logical volume that we will actually install onto.
# diskutil cs createvolume vg_sodium jhfs+ 'Macintosh HD' 100% -passphrase Passphrase for new volume: Confirm new passphrase: Started CoreStorage operation Waiting for Logical Volume to appear Formatting file system for Logical Volume Initialized /dev/rdisk13 as a 238 GB case-insensitive HFS Plus volume with a 24576k journal Mounting disk Core Storage LV UUID: 46A6CA83-9CDC-4978-ADF2-E4DC3F203DBD Core Storage disk: disk13 Finished CoreStorage operation # diskutil cs list CoreStorage logical volume groups (1 found) | +-- Logical Volume Group A642DBC3-644C-4C23-8337-ADBCDD9C85F2 ========================================================= Name: vg_sodium Status: Online Size: 255716540416 B (255.7 GB) Free Space: 0 B (0 B) | +-< Physical Volume A39FA7E9-F52F-4FFA-9A70-F07304111115 | ---------------------------------------------------- | Index: 0 | Disk: disk0s2 | Status: Online | Size: 255716540416 B (255.7 GB) | +-> Logical Volume Family AC7B483C-0524-4ACF-8083-9EFD963F81A5 ---------------------------------------------------------- Encryption Status: Unlocked Encryption Type: AES-XTS Conversion Status: Complete Conversion Direction: -none- Has Encrypted Extents: Yes Fully Secure: Yes Passphrase Required: Yes | +-> Logical Volume 46A6CA83-9CDC-4978-ADF2-E4DC3F203DBD --------------------------------------------------- Disk: disk13 Status: Online Size (Total): 255380987904 B (255.4 GB) Conversion Progress: -none- Revertable: No LV Name: Macintosh HD Volume Name: Macintosh HD Content Hint: Apple_HFS
Now we have a disk called “Macintosh HD” that is encrypted with its own non-user-specific password, formatted, and ready to go. Just switch back to the OS X installer and let it run.
Create a recovery key
After the installer finishes and the system reboots we see the familiar FileVault login screen with just one option: “Disk Password.” Success! Now we just enter that, run through the usual first-time boot stuff, and finally open up a terminal to create a recovery key:
$ sudo fdesetup changerecovery -personal Enter a password for '/': New recovery key = 'XPO6-E4OL-XQG6-TGV9-GFOZ-GB8M'
Add more users
Since I generally don’t log in with an administrative account I created a second, regular user, but then the next time I rebooted I discovered a problem: the FileVault password screen asked for the disk password or the new user’s password. Thankfully, removing that user from the list of choices is simple:
$ sudo fdesetup remove -user gholms
Now that I have gone through all this my machine finally seems to be working exactly the way I want it to, but a few unanswered questions still remain in the back of my mind:
- How am I supposed to do this on a newer Mac that ships with neither an install DVD nor an upgrade application that I can turn into one?
- How do I make OS X stop automatically adding new users to FileVault’s password list?
- Where is the official Core Storage documentation?
Do know the answers to any of these? Leave a comment!