I had been having some problems with PureOS, even running a completely stock installation, so I went exploring other distros.
I decided to give Arch a try for a few reasons, and I’m glad I did. It has been incredibly stable and very fast! I have been using it for over two weeks now with the configuration provided here with zero issues so far.
With Arch being what it is, I had to do a lot of research and note taking before I felt confident enough to try it for myself. I expounded upon my notes to make them useful for others, and make them available to you now.
I did my best to be as thorough as possible, consolidating the steps relevant to the installation and configuration in one place, and clarified some topics that are otherwise explained too simply or tediously elsewhere.
Configuration:
- Librem 15v4
- Arch Linux Hardened
- Grub Bootloader
- Disabled IPv6
- LUKS Encrypted LVM
- System U2F Authentication
- OpenVPN
- H.264 Playback Enabled
- GNOME Desktop Environment (Wayland only)
- CUPS printer support
- Periodic TRIM
Install Arch:
Things to know about Arch:
- Rolling release
- Base system is just that, very basic. The first boot will be only to a command prompt
- Arch is as secure or insecure as you make it
- There are four main repos: core, extra, community, and Arch User Repository (AUR)
- core and extra are maintained by the Arch team
- community is maintained by “trusted users”, and serves as a vetting ground for packages before they move into extra
- AUR consists of packages that anyone can submit. Be careful when installing from this repo
- Take a look at the Arch Wiki for guidance on nearly all things Arch
I provide no warranty or promise of support if you choose to proceed. You should read this entire guide through at least once before beginning, and print a copy if you have only one computer with internet.
I recommend trying this install on a VM or external drive before before working on your actual machine. While an external drive is slower than VM, it is closer to the configuration of an installation on your main disk, and thus preferrable unless you are already comfortable with the command line.
If your machine has a HiDPI display (as with the Librem 15v4), be prepared with glasses, a magnifying glass, or a set of sharp eyes. The prompt is very small before getting to the desktop environment.
1. Boot ISO, Set Keyboard Layout, and Check Boot Mode
- The default keyboard layout is US
- See the Wiki for information on selecting an alternate layout
- Boot Mode: BIOS or UEFI? If it’s a Librem, it’s BIOS and you can move on to step 2
- Not using a Librem? See the Wiki for information on checking Boot Mode
- If your machine is using UEFI, review the sum of the Arch Wiki Install Guide for specific notes related to EUFI installations
2. Establish Wireless Connection
You will use this section again later, at which point you must prepend all of these commands with sudo.
Find name of wireless interface (If you’re on a Librem, likely to be wlp1s0):
$ iw dev
Take note of interface name. You can skip this first part (iw dev) when running through this section later.
Set interface status:
$ ip link set INTEFACE up
- Create /etc/wpa_supplicant/wpa_supplicant.conf
- Add the following, save, and exit:
ctrl_interface=/run/wpa_supplicant
update_config=1
Start wpa_supplicant:
$ wpa_supplicant -B -i INTERFACE -c /etc/wpa_supplicant/wpa_supplicant.conf
Run wpa_cli, scan for your network if needed, configure the network (leave the quotes below, replace what is between them), and connect (this is for WPA networks):
$ wpa_cli
$ scan
$ scan_results
$ add_network
$ set_network 0 ssid "YOUR_SSID"
$ set_network 0 psk "YOUR_PSK"
$ enable_network 0
$ save_config
$ quit
Restart dhcpcd:
$ systemctl restart dhcpcd
Verify wireless interface is up:
$ wpa_cli status
Ping something:
$ ping puri.sm
If ping fails, re-enable to network after restarting dhcpcd:
$ wpa_cli enable_network 0
3. Update System Clock
$ timedatectl set-ntp true
$ timedatectl status
Good to proceed to the next step if the clock is synced.
4. Partition Disk
We will be using fdisk for partitioning.
If you are unfamiliar with this, the basic commands we will be using are:
- “fdisk -l” to list available disks and partitions
- “fdisk /dev/DISK” to select a disk to work with
- “o” to create a new empty DOS partition table
- “n” to add a new partition, which has a sequence of promts that follow it:
- Partition type: primary or extended (we will be using primary, which is the default)
- Partition number: 1-4 (we will be using sequential numbering, which is the default)
- First sector: values vary depending on the size of your disk (we will be using the default)
- Last sector: values again vary, but the default is the maximum possible (we will be creating a 500MB boot partition, with the root partition set to use the remaining disk space)
- “a” marks a partition as bootable
- “t” changes the partition type (we will be using 8E: Linux LVM)
If you are comfortable with fdisk and this up, do what you know is best for you here.
First, identify the disk you’ll be working with:
$ fdisk -l
Take note of the disk you want to install on. On a Librem, likely to be /dev/sda or /dev/nvme0n1.
Begin partitioning the drive:
$ fdisk /dev/DISK
> o
Create boot partition:
> n
> [return]
> [return]
> [return]
> +500MB
> a
Create root partition:
> n
> [return]
> [return]
> [return]
> [return]
> t
> 2
> 8E
Write the changes:
> w
5. Setup Encryption
Here ROOTPARTITION would be something like sda2. Run lsblk first to confirm if needed.
$ cryptsetup luksFormat /dev/ROOTPARTITION
Enter desired encryption password, and confirm it.
Open encrypted partition:
$ cryptsetup open --type luks /dev/ROOTPARTITION lvm
6. Setup LVM (Logical Volume Manager)
The encryption method used here does not support multi-disk logical volumes. Do some research if you want to configure an encrypted multi-disk LVM before beginning.
To keep things simple, I named the volume group and logical volumes in these commands. You can substitute per your preference as desired:
- Volume Group: volgroup0
- Root Volume: lv_root
- Swap Volume: lv_swap
- Home Volume: lv_home
If you don’t use these names, I do recommend using some other scheme that is easily remembered, or taking careful note of what’s what.
First, initialize physical volume:
$ pvcreate --dataalignment 1m /dev/mapper/lvm
Next, create the volume group:
$ vgcreate volgroup0 /dev/mapper/lvm
Next, create system volume (where arch will be installed, adjust from 30GB to meet your preference):
$ lvcreate -L 30GB volgroup0 -n lv_root
Next, create swap volume (adjust from 16GB as needed to match your RAM is recommended):
$ lvcreate -L 16GB volgroup0 -n lv_swap
Next, create home volume (set here to use the remaining space):
$ lvcreate -l 100%FREE volgroup0 -n lv_home
Wrap up LVM setup:
$ modprobe dm_mod
$ vgscan
$ vgchange -ay
7. Format Volumes and Enable Swap
Regain your bearings:
$ lsblk
Boot partition:
$ mkfs.ext2 /dev/BOOTPARTITION
System volume:
$ mkfs.ext4 /dev/volgroup0/lv_root
Home volume:
$ mkfs.ext4 /dev/volgroup0/lv_home
Enable swap:
$ mkswap /dev/volgroup0/lv_swap
$ swapon /dev/volgroup0/lv_swap
8. Mount em-up!
$ mount /dev/volgroup0/lv_root /mnt
$ mkdir /mnt/boot
$ mount /dev/BOOTPARTITION /mnt/boot
$ mkdir /mnt/home
$ mount /dev/volgroup0/lv_home /mnt/home
9. Install Arch
Install Arch, generate fstab, and chroot into the new system:
$ pacstrap /mnt base
$ genfstab -U -p /mnt >> /mnt/etc/fstab
$ arch-chroot /mnt
10. Configure Networking
-
Edit /etc/hostname
-
Add only your hostname
- This can be anything you want in a basic home or business network setup, but it must fit on a single line and adhere to some minimal restrictions. More info on setting the hostname can be found on the Wiki.
-
Edit /etc/hosts; add:
127.0.0.1 localhost
::1 localhost
127.0.1.1 HOSTNAME.localdomain HOSTNAME
11. Clean up pacman mirrors
Edit /etc/pacman.d/mirrorlist
- Delete any mirrors that are geographically far from you, as they can slow things down
- in nano, ctrl+k deletes the currently selected line
- Save and return to the prompt
12. Set Locale
Edit /etc/locale.gen
- Uncomment the line with your locale
- “en_US.UTF-8” would be for the US
- Save and return to the prompt
$ locale-gen
13. Set Time and Sync Clock
View directory structure of /usr/share/zoneinfo to see what options are available here. When ready, proceed with:
$ ln -sf /usr/share/zoneinfo/REGION/CITY /etc/localtime
Now, sync the clock:
$ hwclock --systohc --utc
14. Pre-Boot Software Installation
Here we will install the things we will need for a smooth first boot.
First, decide if you want to choose an alternate kernerl or kernels, of which there are four pre-built choices:
- Stable: default Arch kernel, installed already by the pacstrap command above
- linux-headers
- Hardened: A security-focused Linux kernel applying a set of hardening patches to mitigate kernel and userspace exploits; it also enables more upstream kernel hardening features than Stable
- linux-hardened linux-hardened-headers
- Longterm: Long-term support (LTS) Linux kernel and modules
- linux-lts linux-lts-headers
- ZEN: Result of a collaborative effort of kernel hackers to provide the best Linux kernel possible for everyday systems
- linux-zen linux-zen-headers
You can find more info on these on the Wiki.
For performance and stability purposes, be sure to include both linux-X and linux-X-headers packages for all kernels installed.
If you install only one alternate kernel it will become the system default.
When ready, execute the below command. Add or remove kernel packages to match your selection. In this example, the Hardened kernel is being installed. Be sure to keep linux-headers in the below command, even if you are using an alternate kernel.
$ pacman -S grub-bios sudo linux-headers linux-hardened linux-hardened-headers wpa_supplicant wireless_tools networkmanager net-tools iw dialog util-linux
15. Set mkinitcpio.conf hooks
Edit /etc/mkinitcpio.conf:
- Locate the uncommented line beginning with “HOOKS=”
- In that line, place cursor between “block” and “filesystems”
- There, enter
encrypt lvm2
- It should now read:
HOOKS=(base udev autodetect modconf block encrypt lvm2 filesystems keyboard fsck)
- There, enter
- Save and retrun to the prompt
Regenerate initcpio images:
$ mkinitcpio -p linux
$ mkinitcpio -p linux-hardened
16. Enable NetworkManager service
For networking:
$ systemctl enable NetworkManager.service
17. Set Root Password
$ passwd
18. Configure user(s)
Create plugdev group:
$ groupadd -r plugdev
Create your user accounts. Repeat the commands below for each account to be created. Omit adding the “wheel” group to anyone that should not have sudo priveleges.
$ useradd -m NEWUSERNAME
$ passwd NEWUSERNAME
$ usermod -aG wheel,plugdev,audio,video,optical,storage NEWUSERNAME
Activate wheel group in sudoers (enabling sudo to work):
- Edit /etc/sudoers
- Uncomment the line
%wheel ALL=(ALL) ALL
- Save and return to prompt
19. Configure and Install Grub
First, edit /etc/default/grub:
- Find the line starting with
GRUB_CMDLINE_LINUX_DEFAULT=
- Prepend the line following the = with
cryptdevice=/dev/ROOTPARTITION:volgroup0
- To disable ipv6, append the line with
ipv6.disable=1
- The final line should look something like this:
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=/dev/sda2:volgroup0 audit=0 loglevel=3 quiet ipv6.disable=1"
- The final line should look something like this:
- Save and return to prompt
Regain your bearings:
$ lsblk
The topmost designation of the disk you are working with is to be used in the following command. On a Librem, this will likely be “sda” or “nvme0n1”.
Install Grub:
$ grub-install /dev/DISK
$ grub-mkconfig -o /boot/grub/grub.cfg
20. Exit Root, Unmount, and Reboot
$ exit
$ umount /mnt/boot
$ umount /mnt/home
$ umount /mnt
You may get a resource busy error with the above. If you do, continue with the next command anyway.
$ reboot now
21. First Boot - Enable TRIM
Decrypt your drive, log in with your new user. If you cannot do one of these, time to start over.
Enable periodic TRIM:
$ sudo systemctl enable fstrim.timer
There are other means of enabling TRIM. This method provides enough for most people. See the Wiki for more on TRIM.
22. Set Locale (again)
$ localectl set-locale LANG="YOUR_LOCALE"
Here, YOUR_LOCALE is the same one identified in step 12. Leave the quotes, replace what is between them.
23. Disable ipv6 - Failsafe #1
This probobly is not necessary, but I like having at least two off-switches for some things (the first for ipv6 is in the grub config.
Edit /etc/sysctl.d/40-ipv6.conf:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.wlp1s01.disable_ipv6 = 1
24. Reconnect to internet
Follow the same procedure as Step 2.
25. Install Software
Now install the software you want and need. (Info on available packages available on the Arch site.
A good start (for me):
- OpenVPN (needed for most VPN services):
- networkmanager-openvpn resolvconf openvpn
- Rootkit Hunter - rootkit screening application:
- rkhunter
- Firewalld - GUI firewall configuration
- firewalld
- PAM U2F and Yubikey support:
- pam-u2f yubico-pam yubikey-manager
- GNOME and Arch repo support:
- gnome gnome-packagekit gnome-software-packagekit-plugin
- Tilix, the best terminal emulator!
- tilix python-nautilus
- H.264 playback support:
- ffmpeg gstreamer gst-libav
- CUPS Printer Support (this brings support for most out there. More compatibility is available if needed. Info on Wiki.):
- cups system-config-printer
- Grub Customizer - a helpful GUI tool for editing /etc/default/grub. This is how you can easily change default kernels, among other things.
- grub-customizer
sudo pacman -S networkmanager-openvpn resolvconf openvpn rkhunter firewalld pam-u2f yubico-pam yubikey-manager gnome gnome-packagekit gnome-software-packagekit-plugin tilix python-nautilus ffmpeg gstreamer gst-libav cups system-config-printer grub-customizer
If you prefer to have only Tilix on your system, run the following command after Tilix installation is complete:
$ sudo pacman -Rsu gnome-terminal
Once that is done, pick what you’d like from gnome-extra:
$ sudo pacman -S gnome-extra
You will be prompted to accept everything in the group, or to choose which you’d like to take.
A NOTE ON FLATPAK: If you plan to use flatpak with the Hardened kernel, you must execute the following command. Be aware that this decreases the security of your system.
$ sudo sysctl -w kernel.unprivileged_userns_clone=1
26. Enable GDM and other services
If you went with something other than GNOME for your desktop environment, be sure to replace gdm with the approriate service in the below command.
$ sudo systemctl enable gdm org.cups.cupsd.socket firewalld.service [...any other services you want to run...]
$ sudo reboot now
This will boot to the GDM login screen.
27. Connect to the internet (last time!)
With GNOME loaded, you can now connect to the network via the standard means.
28. Set up PAM U2F
a. Enable Linux udev rules for U2F devices:
Note: the udev rules we will use (provided by Yubico) cover most widely available U2F keys, but it doesn’t cover all of them. If you follow this section exactly and cannot get U2F to work, it could be a udev issue, and you’ll need to go hunting for the needed rules for your device
Go to this page and copy the entire contents: https://raw.githubusercontent.com/Yubico/libu2f-host/master/70-u2f.rules
$ sudo mkdir -p /etc/udev/rules.d/
$ nano 70-u2f.rules
Paste content in, save, and return to prompt.
$ sudo mv 70-u2f.rules /etc/udev/rules.d/
$ sudo udevadm control --reload-rules && sudo udevadm trigger
b. Register your U2F device(s):
-
Primary U2F device:
-
Connect U2F device
$ mkdir u2f
$ pamu2fcfg --origin=pam://localhost > u2f/keys
Backup U2F device(s):
When setting up security like this, it is always a good idea to have at least one backup U2F device that you store somewhere safe – and almost always a bad idea to not have a spare. If you do not have a spare to configure now, you can do so later. Repeat for all backup devices.
- Connect backup U2F device.
$ pamu2fcfg -n --origin=pam://localhost >> u2f/keys
c. Move registration to /etc:
$ sudo mv u2f /etc
d. Enable U2F authentication:
As far as I have experienced so far, this method requires U2F for literally every situation in which you must enter your password. It is possible to require it for only certain situations, such as login, sudo, unlocking the screen, etc. See @lipu’s U2F guide and the other sources listed at the bottom of this U2F guide for more information on that approach.
Edit /etc/pam.d/system-auth:
Choose one of the following:
To allow a U2F key or password for authentication, add the following line as the first in the “auth” section:
auth sufficient pam_u2f.so cue no detect origin=pam://localhost authfile=/etc/u2f/keys
To require both a U2F key and password for authentication, add the following line to the bottom of the “auth” section:
auth required pam_u2f.so cue no detect origin=pam://localhost authfile=/etc/u2f/keys
Configuration options from most secure to least:
-
Omit “cue no detect” to prevent prompting of any kind. Incorrect password and absent key failures both appear to be an incorrect password to the user.
-
Leave “cue no detect” in the above line if you want to be prompted to touch the device only when it is present. An absent key appears to be an incorrect password.
-
Omit “no detect” to always be prompted to touch the device, even when the key is not present. Arguably the least secure setup, as it reveals that a second factor exists when a key is absent.
Save and return to prompt.
DO NOT CLOSE CURRENT TERMINAL WINDOW YET!
- Open new terminal window:
$ sudo echo success
- If it returns “success”, you can safely close both terminal windows and enjoy system U2F authentication.
- If you are not prompted to touch the device when expected (depends on configuration outlined above), or the device does not blink when expected, your password fails to be accepted, or authentication otherwise fails:
-
Close test terminal window (in which you ran echo), and return to the previous terminal window (in which you edited system-auth).
-
Edit /etc/pam.d/system-auth
-
Remove only the line you added above
-
Save and return to prompt
-
$ sudo rm -r /etc/u2f
-
Close terminal, and re-read this before trying again
-
29. Other things to consider:
- Review Firewalld and configure it for yourself
- Learn about laptop-mode-tools [Wiki] [AUR]
- Learn about Rootkit Hunter [Wiki]
- Learn about AppArmor [Wiki]
- ipv6 failsafe #2: choose “ignore” when configuring networks in the GUI
That’s it! Enjoy your new speedy and reasonably secure Arch Installation!
Bonus Round: Custom Boot Splash
The Purism logo at first start will stay. This will get you a graphical spash and decrypt prompt following that logo. This process does bring back the moment of screen garbage during boot that currently happens in PureOS.
To make this work you need to install a few things from the AUR. Check out the Wiki entry on this for instructions on how to use the AUR. The applications we will be using have been in the AUR for quite some time and have had no issues reported.
- grub-silent [Wiki] [AUR]
- plymouth [Wiki] [AUR]
- gdm-plymouth [AUR]
- plymouth theme of your choosing (search “plymouth-theme” in the AUR as a good starting place)
And from the PureOS GitHub:
- pureos theme (if you want the PureOS splash)
DO NOT REBOOT AT ANY POINT UNTIL ALL STEPS ARE COMPLETED
1. Back up current /etc/default/grub file
$ sudo cp /etc/default/grub ~
2. Install Grub-Silent
- Clone, build, and install grub-silent from the AUR
- Create ~/.hushlogin and reinstall grub:
$ touch ~/.hushlogin
$ sudo grub-install /dev/DISK
3. Configure Grub
- Paste contents of /etc/default/grub.silent into /etc/default/grub
- Copy the kernel parameter line from the backup copy of grub in your home folder, and integrate it with your new /etc/defaul/grub
- The line should read something like:
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=/dev/sda2:volgroup0 quiet splash vt.global_cursor_default=0 loglevel=3 video=SVIDEO-1:d rd.systemd.show_status=false rd.udev.log-priority=3 ipv6.disable=1"
- While yours may have additional parameters per your needs, all of the parameters above are required for the splash to work properly
- It is critical that cryptdevice comes first, or your machine may not boot
- Save and return to prompt
- The line should read something like:
4. Install Plymouth
- Clone, build, and install plymouth from the AUR
- Ammend initcpio hooks:
- Edit /etc/mkinitcpio.conf
- Locate the
HOOKS=
line used above, and add: - “plymouth” after “udev”
- replace “encrypt” with “plymouth-encrypt”
- It should now read:
HOOKS=(base udev plymouth autodetect modconf block plymouth-encrypt lvm2 filesystems keyboard fsck)
- Save and return to prompt
5. Install GDM-Plymouth (if using GDM)
- Clone, build, and install gdm-plymouth from the AUR
- Disable GDM and enable GDM-Plymouth:
$ sudo systemctl disable gdm.service
$ sudo systemctl enable gdm-plymouth.service
6. Install theme(s) of choosing
- Plymouth themes are stored at /usr/share/plymouth/themes
- Check out this directory and the directories in it to get an understanding of the structure
- To install new themes, copy only the theme directory to /usr/share/plymouth/themes
- Using the PureOS theme as an example, you would copy only the “pureos” directory
A note on laggy Plymouth themes:
I notcied that some themes are laggy and have delayed keystrokes when entering the LUKS password. I found that these themes have a file called “background-title.png” (a totally tranparent image in every case I’ve found). You can safely remove that file, which should resolve the lag.
7. Configure Plymouth & Update Grub Config
You must repeat this entire section every time you change the active theme.
- Check for available themes:
$ plymouth-set-default-theme -l
- Edit /etc/plymouth/plymouthd.conf to reflect your selection.
- Save and return to prompt
- Update initcpio:
$ sudo plymouth-set-default-theme -R THEMENAME
$ sudo grub-mkconfig -o /boot/grub/grub.cfg