Last active
June 6, 2024 15:13
-
-
Save altercation/58d0dd8dc8aaf1cf4380197c64c97f34 to your computer and use it in GitHub Desktop.
Bulletproof Arch - Minimal Clean Install
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
------------------------------ | |
IMPORTANT NOTE: | |
Please see @craSH's update to this. He has updated and reformatted these working notes and his version is what I recommend you start with (as of 2021 or later). | |
-Ethan | |
@craSH fork & update (also listed in the forks on this gist above): | |
https://gist.github.com/craSH/21a6321d3dcd7f5b56ec8fe28bea1444#file-bulletproof_arch-md | |
------------------------------ | |
These are working notes on the installation of Arch Linux. I've just completed this install on a notebook (Lenovo P50) | |
but the setup should work for most laptop/desktop configurations. | |
Some assumptions/notes: | |
1. This isn't a dual boot configuration. I can see some of the appeal and still work in Adobe from time to time, but given | |
the increasing complexity of EFI and the way Windows/MS manhandles the EFI partition during upgrades, I really would | |
recommend steering clear of dual boot. Just my two cents here. | |
2. We're encrypting with LUKS. I've used so-called "self encrypting drives" as well (and linux has multiple ways of dealing | |
with these keys and the encryption thereof). They are fast and as secure as you trust your UEFI bios manufacturer and | |
harddrive manufacturer. Honestly, not a bad solution and would eliminate the need for LUKS. You do need UEFI bios support for | |
these drives, though that's pretty common now. For me it feels a little too proprietery at this point and I don't trust that | |
there isn't a big ol' backdoor in the drive firmware. | |
3. We're avoiding LVM. This talk by Marc Merlins changed my views on a lot of things, including LVM: | |
Video: https://www.youtube.com/watch?v=6DplcPrQjvA | |
Slides: http://marc.merlins.org/linux/talks/2015/Btrfs-LCA2015/Btrfs.pdf | |
Besides the performance hit, there is just no need. The only benefit for us might be the swap situation, but you can do | |
either standard encrypted swap (as detailed herein) or encrypted-with-hibernate-support without LVM. LVM gets us nothing at | |
this point given that we'll be using BTRFS subvolumes as they were meant to be. | |
----------------------------------------------------------------------------------------------------------- | |
PREPARATION | |
----------------------------------------------------------------------------------------------------------- | |
BOOT ARCH USB | |
----------------------------------------------------- | |
Download and burn USB drive as per instructions on ArchLinux.org | |
PICK INSTALL DRIVE | |
----------------------------------------------------- | |
# lsblk | |
an aside: | |
If you don't already use `lsblk` a lot, you should. I love it. Here's a way to quickly list all your partitions along | |
with their partition labels, filesystem labels, mount points, and UUIDS/PARTUUIDS. | |
# lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID | |
NOTE: in the following sections, DRIVEID might be "sda", for example, while PARTID might be "sda1". I used to just append | |
partition numbers to a $DRIVE variable in my scripts, but this is no longer safe with the advent of NVMe drives, which | |
enumerate using a different format. | |
WIPE DRIVE (can skip) | |
----------------------------------------------------- | |
This is a full, secure wipe of the drive. If you aren't worried about the NSA, APTs, your mom, whatever, then you can skip | |
this, but why not have some peace of mind and do it? Note that even though we're sourcing /dev/zero for the input, it's | |
scrambled on disk due to the use of LUKS. | |
# sgdisk --zap-all /dev/DRIVEID | |
# cryptsetup open --type plain /dev/DRIVEID container --key-file /dev/random | |
# dd if=/dev/zero of=/dev/mapper/container status=progress | |
# cryptsetup close container | |
PARTITION DRIVE | |
----------------------------------------------------- | |
# DRIVE=/dev/whatever | |
# MNT=/mnt | |
Create all partitions. See http://www.rodsbooks.com/efi-bootloaders/principles.html for an explanation of why 550MiB is a | |
minimum size for the EFI partition. | |
# sgdisk --clear \ | |
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \ | |
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \ | |
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \ | |
$DRIVE | |
ENCRYPT SYSTEM PARTITION | |
----------------------------------------------------- | |
Encrypt the main partition. Use a good passphrase. Then open the partition. | |
2021 UPDATE & WARNING! | |
https://www.man7.org/linux/man-pages/man8/cryptsetup.8.html --align-payload is apparently now a scary no-no! Thanks to @craSH for noting this. Don't make life easy for the NSA :) | |
ALSO 2021 Update: xts keysize minumum should be 512 | |
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem | |
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system | |
FORMAT EFI PARTITION | |
----------------------------------------------------- | |
EFI now needs to be formatted as FAT32, as per the standard. | |
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI | |
CREATE BTRFS SUBVOLUMES | |
----------------------------------------------------- | |
Notes: | |
1. While it is possible to just create a single subvolume (the so-called "top level subvolume") and use that as root, we'd be | |
throwing away the real power of BTRFS. Our subvolume structure will in fact be this: | |
TOPLEVEL | |
| | |
|--root | |
|--home | |
`--snapshots | |
| | |
|--root_snapshot_datehere | |
|--root_snapshot_datehere | |
|--root_snapshot_datehere | |
|--home_snapshot_datehere | |
`--home_snapshot_datehere | |
The snapshots should all be made as read-only BTRFS snapshots. At any time we can boot into a shell where our root or home | |
isn't mounted and rename our "root" subvolume to something like "root_old" and then simply create a new rw snapshot from any | |
of the snapshots, naming it root and placing it under the top-level subvolume. This will be a perfect restore of the root | |
filesystem (sans /home, as we want to keep / and /home decoupled for snapshotting purposes). | |
Note that in time I may decide to make parts of /var or other branches of the filesystem separate subvolumes so that they are | |
not being snapshotted along with the rest of root. For example, any directory contain the bulk of my VM images. | |
cf https://btrfs.wiki.kernel.org/index.php/FAQ#Does_Btrfs_support_TRIM.2Fdiscard.3F | |
"-o discard" can have some negative consequences on performance on some SSDs or at least whether it adds worthwhile performance is up for debate depending on who you ask, and makes undeletion/recovery near impossible while being a security problem if you use dm-crypt underneath (see http://asalor.blogspot.com/2011/08/trim-dm-crypt-problems.html ), therefore it is not enabled by default. You are welcome to run your own benchmarks and post them here, with the caveat that they'll be very SSD firmware specific. | |
Top-level subvolume first: | |
# mkfs.btrfs --force --label system /dev/mapper/system | |
# o=defaults,x-mount.mkdir | |
# o_btrfs=$o,compress=lzo,ssd,noatime | |
Mount this temporarily so that we can create the subvolumes that will be our actual mounted volumes: | |
# mount -t btrfs LABEL=system $MOUNT | |
Subvolumes will be created, we'll unmount, then remount the subvolumes at the correct mountpoints. Specifically, this creates separate subvolumes for / (root) and /home for easier snapshot and rollback, along with a container subvolume for the snapshots themselves. | |
Create the subvolumes under the top-level subvolume: | |
# btrfs subvolume create $MOUNT/root | |
The following is either wrong or unnecessary? I think? I was using the ID before. Better to use the subvolume name. I should never be mounting without a subvolume name anyhow. So verdict is: unnecessary. | |
# btrfs subvolume set-default ${$(btrfs subvolume list $MOUNT)[(w)2]} $MOUNT | |
# btrfs subvolume create $MOUNT/home | |
# btrfs subvolume create $MOUNT/snapshots | |
Unmount everything… | |
# umount -R $MOUNT | |
Remount them at their correct locations | |
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system $MOUNT | |
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system $MOUNT/home | |
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system $MOUNT/.snapshots | |
# NOTE: mkdir $MOUNT/boot is NOT needed since we are using the x-mount.mkdir mount option which will create the directory | |
# mount -o $o LABEL=EFI $MOUNT/boot/EFI | |
Open encrypted device for swap | |
# cryptsetup open --type plain --key-file /dev/urandom \ | |
/dev/disk/by-partlabel/cryptswap swap | |
# mkswap -L swap /dev/mapper/swap | |
# swapon -L swap | |
line 86, I noticed that both the swap and crypt partitions have the same typecode, or to say more accurately, the typecode for 2nd partition is repeated, and not mentioned for the third one?
Was probably an error but be warned this code is quite out of date now :) - there’s a link to a more current forked version above though I don’t know if that author has maintained his or not.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line 86, I noticed that both the swap and crypt partitions have the same typecode, or to say more accurately, the typecode for 2nd partition is repeated, and not mentioned for the third one?