Creating a semi-secure USB-drive for Linux and macOS (and Windows)
May 7, 2020TL;DR: Format the drive with exFAT
, and use gpg
to encrypt the files.
I want a USB-drive I can store some private data on, and I want to be able to use it on both macOS and Linux (more specifically, Ubuntu).
I'm afraid the title is a bit misleading. The solution I've come up with does
not work on Ubuntu out-of-the-box. We'll need to install exfat-fuse
and
exfat-utils
to make this work on Ubuntu.
The solution I've come up with is this:
- Create two partitions on the USB-drive.
- Format the first with
ext4
so it can be easily read on Linux, and store a description of how to mount the other partition on it. - Format the second partition with
exFAT
. This will automount on macOS (and Windows), and is easily mounted on Ubuntu. - Create a tarball with the files I want to store, encrypt it with
gpg
, and store it on the second partition. - Create instructions on how to securely decrypt and handle the files, and store said instructions unencrypted on the second partition
The best solution would clearly be to use some kind of encrypted filesystem, and I'm sure it's possible to jerryrig macOS or Ubuntu to mount an encrypted filesystem the other can interactict with, but I want something simple. I'll be storing data on this drive that I won't be accessing very often, so I want it to be simple to use when I need it.
As an added bonus, exFAT works on Windows as well. I have no idea how to use GPG on Windows, but I'm sure there's a way. Especially now that you can run Linux on Windows.
The USB-drive
I will be formatting and pariotioning the drive on Ubuntu, simply because I prefer the Linux terminal.
Plug in the drive and find out which device identifier it has been assigned. You
can use lsblk
to list all your devices, and find the one you just plugged in.
On my machine, the drive was located at /dev/sda
. This is normally your
primary harddrive, so your USB-drive will probably be located elsewhere.
Partitioning the drive
Next up we need to partition the drive. I will start off by setting up GPT (GUID
Partition Table). Then I will create one small (1GB) Linux-partition where I can
store instructions on how to install exFAT
, and then I will create one larger
partition for exFAT
. The second partition will have the partition-type
"Microsoft basic data".
$ sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): g
Created a new GPT disklabel (GUID: 6E3C0041-70ED-0949-887A-BFCAE8069232).
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-60555230, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-60555230, default 60555230): +1G
Created a new partition 1 of type 'Linux filesystem' and of size 1 GiB.
Command (m for help): n
Partition number (2-128, default 2):
First sector (2099200-60555230, default 2099200):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2099200-60555230, default 60555230):
Created a new partition 2 of type 'Linux filesystem' and of size 27.9 GiB.
Command (m for help): t
Partition number (1,2, default 2): 2
Partition type (type L to list all types): 11
Changed type of partition 'Linux filesystem' to 'Microsoft basic data'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Formatting the drive
After partitioning the drive, I need to format the two partitions. The first
will be formatted with ext4
, and the second one with exFAT
.
$ sudo mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -L mntexfat /dev/sda1
I throw in the options lazy_itable_init=0
and lazy_journal_init=0
because
mkfs.et4
will, by default, write the inode-table and journal after creation,
in order to speed up the formatting. I don't want to wait for this, so I turn it
off.
$ sudo mkfs.exfat -n SECU /dev/sda2
The ext4
-partition will mount with no problems on Linux, but you need to install
exfat-utils
and exfat-fuse
to mount the exFAT
-partition. I'm making a note
of this in a text-file and saving it to the small ext4
-partition, in case I
forget it later on.
Once exfat-utils
and exfat-fuse
is installed, the exFAT
-partition can be
mounted with mount -t exfat <device> <mount-point>
.
The exFAT
-partiotion should now automagically mount on macOS.
The files
Because encryption on filesystem-level is not supported across platforms, I will
be encrypting my files using gpg
. This means I have to handle the files
unencrypted, and then encrypt them before storing them on disk (as opposed to
being able to handle the files unencrypted when an encrypted filesystem is
mounted). This means I have to store the files unencrypted on my local disk
while I handle them. If I encrypt and decrypt the files while they are on the
USB-drive, someone would be able to recover them even after they've been
deleted.
On modern Linux /tmp
is mounted as a tmpfs
, which resides in memory, which
is completely wiped when you turn off your computer. This is not the case with
macOS, however. Luckily, we can easily create a ramdisk where we can handle our files.
If you're on Windows, you're on your own.
ramdisk on macOS
We can use the following line to create a ramdisk on macOS
$ diskutil erasevolume HFS+ 'ramdisk' `hdiutil attach -nomount ram://8388608`
This will create a 4GB ramdisk (8388608 = 4096MB * 2048). It will be automounted
at /Volumes/ramdisk
.
To delete the ramdisk:
$ diskutil eject /Volumes/ramdisk
If you wish to use this, it is probably best to save a file with instructions on
how to do it on the exFAT
-partition.
GPG
For Ubuntu, just do cd $(mktemp -d)
to enter a directory you can work in.
On macOS, you need to create the ramdisk as described above, and then you can do to get a directory to work in.
$ TMP=$(mktemp -d); mv $TMP /Volumes/ramdisk && cd /Volumes/ramdisk/$(basename $TMP)
Move the files you want to store securely into this directory. You might want to create a sub-directory, maybe "secrets", to store them in. Just to make it easier to package with tar.
We need to create a tarball of our files, because gpg
expects a file, and not
a directory. tar cvf secrets.tar secrets
, and encrypt the tar-file using
gpg --output secrets.tar.gpg --symmetric secrets.tar
, or gpg -o secrets.tar.gpg -c secrets.tar
. You will be prompted for a passphrase.
Lastly, move the file over to the USB-drive.
To unencrypt your files, move the encrypted .gpg
-file to your ramdisk, and do
gpg -o secrets.tar -d secrets.tar.gpg
, and type in the passphrase when
prompted.
It is probably a good idea to store these instructions on the drive, in case you forget them.
Conclusion
This is not an ideal way to handle files securely on an external drive. But, if done correctly, it will be secure, and you will be able to use it across multiple operating systems.
Remember to never store your files unencrypted on the external drive. It might be possible to recover them.