I jump around a lot between Linux (personal, mainly servers), MacOS (personal, development and laptop/desktop) and Windows (work). I also run FreeNAS but that's black magic...
As a result I'd probably consider myself fairly well-acquainted with operating systems but started feeling as though I'd become too reliant on the trusty (no pun intended) Ubuntu / Debian combination in the world of Linux and was itching to see if I could start using my lovely Mac hardware with something a bit more OpenSource friendly in keeping with my (slowly) ongoing mission to Becoming Self-sufficient and IT Resilient in 2017.
Inspired by the guys over at /r/UnixPorn I decided to take the plunge with Arch Linux in order to get a truly customised OS that reflected the hacker and tweaker in me...
This is a placeholder workflow that I've got for installing a minimal Arch Linux base image on an encrypted disk using LUKS + LVM. Setting up and then configuring a graphical environment is a separate - and rather personal - task I'll document later.
Installation
Assuming you've grabbed the latest image from the downloads boot up into the LiveCD image in order to install the base Arch distribution. For reference I'll be using archlinux-2017.05.01-x86_64.iso
.
Localisation
Before doing anything further set the keymap using
localectl set-keymap --no-convert uk
as it drives me nuts later on when |
etc. won't work...
Update the system clock using timedatectl set-ntp true
Running pacman -Sy
will also ensure we have the most up-to-date packages
available.
Partition the drives
We are going to use the fdisk
utility to create the partitions we want.
First, confirm which disk is our install target:
fdisk -l | grep Disk
...
Disk /dev/sda: 32 GiB, 34359738368 bytes, 67108864 sectors
Disk /dev/loop0: 369.5 MiB, 387477504 bytes, 756792 sectors
As you can see, the LiveCD iso is mounted as a loopback device on /dev/loop0
whilst the main disk is /dev/sda
.
We'll now setup and partition this disk. Edit it one by one using
fdisk /dev/sdX
, replacing X
with the correct letter.
This will drop you into a separate terminal prompt that you can then issue the
following commands in:
n
# create new partition
p
# primary (default)1
# 1st partition (default)2048
# first sector start (default)+500M
# create a 500MB partition for the/boot
Created a new partition 1 of type 'Linux' and of size 500 MiB.
a
Selected partition 1 The bootable flag on partition 1 is enabled now.
n
# create new partition
p
# primary (default)2
# 2nd partition (default)- select default sector # straight after 1st partition
- select default sector # fills the remaining disk for LVM
Created a new partition 2 of type 'Linux' and of size 31.5 GiB.
t
# change partition type2
# 2nd partition (default)8e
# LVMChanged type of partition 'Linux' to 'Linux LVM'.
p
# check partition layout before writing
Device Boot Start End Sectors Size Id Type /dev/sda1 * 2048 1026047 1024000 500M 83 Linux /dev/sda2 1026048 67108863 66082816 31.5G 8e Linux LVM
w
# write to disk
We're going to format the filesystem on the boot partition now
mkfs.ext4 -L boot /dev/sda1
Create Encrypted LVM on LUKS
Now, because I've got both a tinfoil hat and a failover tinfoil hat I'll be
installing the system to an encrypted partition and using LVM to then manage the /
, /home
and swap
elements. This keeps everything in one place and unlocked via a single passphrase.
Using cryptsetup
create an encrypted container on our Linux LVM
partition.
# on a production system I'd probably also add --use-random
cryptsetup -v --cipher aes-xts-plain64 \
--key-size 512 --hash sha512 luksFormat /dev/sda2
Now open the container
cryptsetup open --type luks /dev/sda2 lvm
The decrypted container is now available at /dev/mapper/lvm
Now create the LVM:
# Create a physical volume on top of the opened LUKS container:
pvcreate /dev/mapper/lvm
# Create the volume group named vgpool, adding the previously created physical
# volume to it
vgcreate vgpool /dev/mapper/lvm
# Create all your logical volumes on the volume group
lvcreate -L 4G -n swap vgpool
lvcreate -L 8G -n root vgpool
lvcreate -l 100%FREE -n home vgpool
# Format your filesystems on each logical volume
mkswap -L swap /dev/mapper/vgpool-swap
swapon /dev/mapper/vgpool-swap
mkfs.ext4 -L root /dev/mapper/vgpool-root
mkfs.ext4 -L home /dev/mapper/vgpool-home
Run Arch installer
As we're currently still inside the LiveCD environment we need to chroot
the installation such that all further commands are run on our install target disk as opposed to being discarded on reboot...
We have the following setup:
- Primary partition for
/boot
on/dev/sda1
- Encrypted LVM partition on
/dev/sda2
for everything else. These are mounted on the host as:
/dev/vgpool/home
/dev/vgpool/root
/dev/vgpool/swap
To create the chroot we'll need to mount these within each other so the order of the below commands is important.
# mount the `/` root
mount /dev/vgpool/root /mnt
# create `/boot` directory and mount primary partition
mkdir -p /mnt/boot
mount /dev/sda1 /mnt/boot
# create `/home` directory and mount logical volume
mkdir -p /mnt/home
mount /dev/vgpool/home /mnt/home
Now we'll install the Arch system to the new location.
# This will probably take a while
pacstrap /mnt base base-devel
...
Total Download Size: 251.20 MiB
Total Installed Size: 900.41 MiB
...
(1/7) Updating linux initcpios
(2/7) Updating udev hardware database...
(3/7) Updating system user accounts...
(4/7) Creating temporary files...
(5/7) Arming ConditionNeedsUpdate...
(6/7) Updating the info directory file...
(7/7) Rebuilding certificate stores...
pacstrap /mnt base base-devel 32.47s user 11.13s system 3% cpu 19:11.28 total
[email protected] ~ #
Note: If you're doing this in a VM or container for testing now is a pretty good time to take a snapshot for subsequent rollbacks... Not that you'll make any mistakes obviously.
Create a fstab
for holding persistent mountpoints
genfstab /mnt >> /mnt/etc/fstab
Perform basic Arch Linux configuration
Switch to the newly installed system with arch-chroot /mnt /bin/bash
. We will install zsh
last as it's not there by default :-(
zsh
# Install zsh shell
pacman -Sy zsh zsh-completions
We can now switch to zsh with /bin/zsh
Localisation
# configure the system language by editing the `local.gen` file and
# uncommmenting: `en_GB.UTF-8 UTF-8`; and `en_US.UTF-8 UTF-8`
nano /etc/locale.gen
# now run the locale generation
locale-gen
# create /etc/locale.conf
nano /etc/locale.conf
...
LANG=en_US.UTF-8
# set the timezone
rm /etc/localtime
ln -s /usr/share/zoneinfo/Europe/London /etc/localtime
# now set the time standard to UTC
hwclock --systohc --utc
Users
Update the root
password with passwd
. Optionally we can disable root completely.
We'll setup a new user now for administration with zsh as the default shell.
paceman -Sy sudo # admin user will need this
# Create admin user
useradd -m -g users -G wheel,storage,power -s /bin/zsh admin
passwd admin
# Edit sudoers
pacman -Sy vim
visudo
...
:e # edit the file
...
wq! # write changes and quit
Networking
Set the hostname
nano /etc/hostname
...
archer
# now also edits the `hosts file`
nano /etc/hosts
...
127.0.1.1 archer.localdomain archer
Make Network connections persistent using systemctl enable dhcpcd
GRUB installation
We need to install the bootloader and then configure it to take into account
the encrypted LVM.
pacman -S grub os-prober
grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
Configuring the boot loader
We need to edit mkinitcpio
in order to re-generate the initial ramdisk such
that the bootloader can open the encrypted container.
nano /etc/mkinitcpio.conf
...
HOOKS="base udev autodetect keyboard keymap consolefont modconf block encrypt lvm2 filesystems fsck"
...
# Now re-generate the image
mkinitcpio -p linux
In order to unlock the encrypted root partition at boot, the following kernel parameters need to be set by the boot loader:
cryptdevice=UUID=device-UUID:lvm root=/vgpool-root
device-UUID | refers to the UUID of the raw encrypted device (e.g. /dev/sdaX) You can get this with the `blkid` command on `/dev/sda2` (you need the UUID of the LUKS partition). |
root | If the root file system is contained in a logical volume of a fully encrypted LVM, the device mapper for it will be in the general form of `root=/dev/mapper/volumegroup-logicalvolume` |
we need to edit /etc/default/grub
nano /etc/default/grub
...
GRUB_CMDLINE_LINUX="cryptdevice=UUID=ebc2d86f-aab9-494e-a545-bfbaacce075a:lvm root=/dev/mapper/vgpool-root"
...
# Now re-generate grub
grub-mkconfig -o /boot/grub/grub.cfg
Post-install tweaks
As these things tend to be fault personal and dependant upon the desktop environment you're going for I've kept the below to a minimum based on what I'd always install regardless.
Package manager
Updated mirrorlists
I'm going to use the web service provided by arch for pulling back a list of all available package mirrors for a selection of European countries. This will be filtered only for those that support https
and will be limited to ipv4
.
# Generate https mirrorlist for European countries I trust
curl -o /etc/pacman.d/mirrorlist "https://www.archlinux.org/mirrorlist/?country=FR&country=DE&country=SE&country=CH&country=GB&protocol=https&ip_version=4&use_mirror_status=on"
sed -i.bak 's/#//' /etc/pacman.d/mirrorlist # remove comments
pacman -Syy # force refresh
Enable AUR
su admin # (makepkg can't be run as root)
# Install yaourt for AUR packages
pacman -S git
cd /opt
sudo chown -R root:wheel /opt
sudo chmod -R g+rwx /opt
git clone https://aur.archlinux.org/package-query.git
cd package-query
makepkg -si
cd ..
git clone https://aur.archlinux.org/yaourt.git
cd yaourt
makepkg -si