zfs-arch.org (21716B)
1 #+TITLE: Maximal Anti-Glow-In-The-Dark Setup for Arch Linux With ZFS 2 #+AUTHOR: Ryan 3 #+EMAIL: ryan@ryanmj.xyz 4 #+OPTIONS: num:nil 5 6 7 This guide will show you how to set up an Arch Linux (the best Linux distro) install on a root filesystem formatted with ZFS (the best file system), thus making this the best possible Linux install. 8 9 Not only that, but this will also be the most /secure/ Linux install, since (nearly) everything will be encrypted, thus preventing any would-be glow-in-the-darks from accessing your data. 10 * Imperfections 11 Currently there are two problems that exist with this install (listed below). If you have solutions do not hesitate to [[mailto:ryan@ryanmj.xyz][email me]] your fix! 12 13 Firstly, we need to have separate ~/boot~ and ~/~ partitions, which is fine, but at boot time you'll need to put in ~/boot~'s password twice. This is apparently fixable (even after install) I just haven't figured it out yet. 14 15 The current fix is to just have your computer on all the time. 16 17 Secondly, there is this line from the [[https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_ZFS][Arch Wiki]] that concerns me: 18 #+BEGIN_QUOTE 19 You can also create your ROOT dataset without having to specify mountpoint to / since GRUB will mount it to / anyway. That gives you possibility to boot into some old versions of root just by cloning it and putting as menuentry of GRUB. 20 #+END_QUOTE 21 22 The article goes on to show you how to make the dataset in this fashion, but I wasn't able to get it working! When it came time to mount the ZFS datasets to install the OS I was unable to mount ~zroot/ROOT/default~ to ~/~ at all, it would just fail. This might mean that I can't boot snapshots as ~/~ from GRUB, which would suck, and I'm not sure if this is fixable after install. 23 24 I could fix the first problem by using legacy datasets (they're called /legacy/... they must be bad!), but that would make me feel like I copped out. I'd much rather use the native, modern ZFS datasets instead. 25 26 27 * The ISO 28 Unless you live in the future where ZFS has been re-released under the GPL then ZFS is not an official part of the Linux project, and so it is not included in the normal Arch Linux kernel package (or the normal install ISO). As a result, some extra install steps are necessary. 29 30 If you /don't/ run Arch Linux, you can use [[https://github.com/eoli3n/archiso-zfs][this script]] on a running Arch Linux install image and it should make it ZFS ready (I have not tried it myself though). If you /do/ run Arch, then you can set up your own Arch Linux install image, which is preferable anyway because you can include any package you want in the ISO. 31 32 To create the Arch Live ISO: 33 #+begin_src shell 34 cp -r /usr/share/archiso/configs/releng archlive 35 cd archlive 36 #+end_src 37 38 Now, add this text to the bottom of ~pacman.conf~: 39 #+begin_src conf 40 [archzfs] 41 Server = https://archzfs.com/$repo/x86_64 42 Server = https://mirror.sum7.eu/archlinux/archzfs/$repo/x86_64 43 Server = https://mirror.biocrafting.net/archlinux/archzfs/$repo/x86_64 44 SigLevel = Optional TrustAll 45 46 [archzfs-kernels] 47 Server = https://end.re/$repo/ 48 SigLevel = Optional TrustAll 49 50 #+end_src 51 52 You can also (optionally) uncomment ~Color~ and add ~ILoveCandy~. 53 54 Now you copy the ~pacman.conf~ to ~airootfs~: 55 56 #+begin_src shell 57 cp pacman.conf airootfs/etc/. 58 #+end_src 59 60 Now insert ~zfs-linux~ to the bottom of ~packages.x86_64~. Optionally, you can also insert the name of any Arch Linux package you want. I'm adding in ~joe~ and ~networkmanager~ to make the install a bit easier for me. You could even add a desktop environment, browser, etc. if you wanted to - in fact, that would make some of the later steps a bit easier, as you'd be able to copy-paste from the browser (make sure you also install a terminal emulator if you go that route... I made that mistake)! 61 62 Now, we can build the image: 63 64 #+begin_src shell 65 sudo mkarchiso -v . 66 #+end_src 67 68 Now all that's left to do with the image is to write it to a disk or a USB stick. If you're using a thumb drive like me, you need to find out which device your USB is mapped to (using ~fdisk~). It will probably be something along the lines of ~/dev/sdX~ with ~X~ being some letter. For example, mine was mapped to ~/dev/sde~. Once you find that out, write to the drive with ~dd~. 69 70 #+begin_src shell 71 sudo dd if=out/archlinux*.iso of=/dev/sde bs=1M status=progress 72 #+end_src 73 74 Alternatively, you could use BalenaEtcher to write to the drive... but we've been using the terminal the entire time, might as well get across the finish line with it (plus we won't have to install any annoying AUR packages)! 75 76 * Installing the OS 77 Now comes the scary part... having to actually write to your disk. 78 79 Once booted into the ISO you should make sure that the ZFS kernel module is loaded: 80 81 #+begin_src shell 82 lsmod | grep zfs -i 83 #+end_src 84 85 ** Setting Up the Partitions 86 */THIS IS THE POINT OF NO RETURN/* btw. 87 88 Just like with the USB stick earlier we need to find out which device your drive is mapped to. Mine was mapped to ~/dev/sda~, but make sure you adapt the following information to your device. 89 90 To signify the beginning of a new era of ZFS we will wipe the disk of its partitioning information: 91 92 #+begin_src shell 93 sgdisk --zap-all /dev/sda 94 #+end_src 95 96 From that, we will create new partitions for our system to live on. This is what the drive will look like: 97 98 | Device | Size | Type | Mountpoint | 99 |-----------+------------------+-------+------------| 100 | /dev/sda1 | 512M | fat32 | /boot/efi | 101 | /dev/sda2 | 5G | ext4 | /boot | 102 | /dev/sda3 | 4G | swap | swap | 103 | /dev/sda4 | Rest of the disk | zfs | / | 104 105 ~/dev/sda1~, ~/dev/sda2~, and ~/dev/sda4~ should all be exactly as I have configured them here. ~/dev/sda3~, however, can be any size you want it to be (it's also the only partition you don't technically need). ZFS is rather memory hungry so I would recommend a hefty swap partition for any machine with <= 8G memory. 4G is a good number for a 16G machine, so you should adjust accordingly. 106 107 To partition we will use ~gdisk~. Below is my usage of ~gdisk~ as an example. To adapt the output to your use, on every line that begins with `Last Sector', simply change the value to however large you want the partition to be (if you want a 8G swap partition, replace the `+4G' with `+8G'). For any empty lines, just press enter. 108 109 #+begin_src shell 110 gdisk /dev/sda 111 112 GPT fdisk (gdisk) version 1.0.5 113 114 Partition table scan: 115 MBR: not present 116 BSD: not present 117 APM: not present 118 GPT: not present 119 120 Creating new GPT entries in memory. 121 122 Command (? for help): n 123 Partition number (1-128, default 1): 124 First sector (34-62914526, default = 2048) or {+-}size{KMGTP}: 125 Last sector (2048-62914526, default = 62914526) or {+-}size{KM 126 Current type is 8300 (Linux filesystem) 127 Hex code or GUID (L to show codes, Enter = 8300): ef00 128 Changed type of partition to 'EFI system partition' 129 130 Command (? for help): n 131 Partition number (2-128, default 2): 132 First sector (34-62914526, default = 1050624) or {+-}size{KMGTP}: 133 Last sector (1050624-62914526, default = 62914526) or {+-}size{KMGTP}: +5G 134 Current type is 8300 (Linux filesystem) 135 Hex code or GUID (L to show codes, Enter = 8300): 136 Changed type of partition to 'Linux filesystem' 137 138 Command (? for help): n 139 Partition number (3-128, default 3): 140 First sector (34-62914526, default = 11536384) or {+-}size{KMGTP}: 141 Last sector (11536384-62914526, default = 62914526) or {+-}size{KMGTP}: +4G 142 Current type is 8300 (Linux filesystem) 143 Hex code or GUID (L to show codes, Enter = 8300): 8200 144 Changed type of partition to 'Linux swap' 145 146 Command (? for help): n 147 Partition number (4-128, default 4): 148 First sector (34-62914526, default = 19924992) or {+-}size{KMGTP}: 149 Last sector (19924992-62914526, default = 62914526) or {+-}size{KMGTP}: 150 Current type is 8300 (Linux filesystem) 151 Hex code or GUID (L to show codes, Enter = 8300): bf00 152 Changed type of partition to 'Solaris root' 153 154 Command (? for help): w 155 156 Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING 157 PARTITIONS!! 158 159 Do you want to proceed? (Y/N): Y 160 OK; writing new GUID partition table (GPT) to /dev/sda. 161 The operation has completed successfully. 162 #+end_src 163 164 You should get a disk that looks something like this (from ~fdisk~): 165 166 #+begin_src shell 167 Device Start End Sectors Size Type 168 /dev/sda1 2048 1050623 1048576 512M EFI System 169 /dev/sda2 1050624 11536383 10485760 5G Linux filesystem 170 /dev/sda3 11536384 19924991 8388608 4G Linux swap 171 /dev/sda4 19924992 62914526 42989535 20.5G Solaris root 172 #+end_src 173 174 ** Creating ~/boot~, ~/boot/efi~, and ~swap~ 175 *** ~/boot/efi~ 176 That was the hard part. The next step is to create the auxiliary filesystems (everything except ~/~). To crate the EFI system partition: 177 178 #+begin_src shell 179 mkfs.fat -F32 /dev/sda1 180 #+end_src 181 182 Note the `1' at the end of ~/dev/sda1~. 183 *** ~/boot~ 184 Now to set up the encrypted ~/boot~ partition, which needs to be a separate partition from ~/~ due to GRUB not being completely compatible with ZFS. 185 186 #+begin_src shell 187 cryptsetup luksFormat --type luks1 /dev/disk/by-id/xxx 188 #+end_src 189 190 Replace the `xxx' at the end of the command with the ID of ~/dev/sda2~ (remember, you can use tab completion on filepaths). ID's usually have a `partX' at the end which makes it easier to figure out. Put in a nice, strong password to encrypt the partition. Also, it is very imperative that the encryption type be ~luks1~, otherwise the system will not boot. 191 192 Now to bring up the newly encrypted partition and format it: 193 194 #+begin_src shell 195 cryptsetup open /dev/disk/by-id/xxx cboot 196 mkfs.ext4 /dev/mapper/cboot 197 #+end_src 198 199 Obviously, replace `xxx' with your disk ID. `cboot' at the end there is what I'm deciding to call that partition, you can give it any name you wish. 200 *** ~swap~ 201 202 #+begin_src shell 203 cryptsetup open --type plain --key-file=/dev/urandom /dev/disk/by-id/xxx cswap 204 mkswap /dev/mapper/cswap 205 swapon /dev/mapper/cswap 206 #+end_src 207 208 Now replace ~/dev/disk/by-id/xxx~ with the ID of ~/dev/sda3~. Like with the boot partition you can name the partition whatever you want, just replace `cswap' with your desired name. 209 ** ZFS root Partition, or ~/~ 210 This is what we've been waiting for... 211 *** ~zpool~ creation 212 213 First we must determine the ~ashift~ value for our ~zpool~: 214 215 #+begin_src shell 216 lsblk -S -o NAME,PHY-SEC 217 #+end_src 218 219 | Value | Ashift | 220 |-------+--------| 221 | 512 | 9 | 222 | 4k | 12 | 223 224 225 #+begin_src shell 226 zpool create -f -o ashift=12 -o autoexpand=on -R /mnt \ 227 -O acltype=posixacl \ 228 -O atime=off \ 229 -O xattr=sa \ 230 -O dnodesize=legacy \ 231 -O normalization=formD \ 232 -O mountpoint=none \ 233 -O canmount=off \ 234 -O devices=off \ 235 -O encryption=aes-256-gcm \ 236 -O keyformat=passphrase \ 237 -O keylocation=prompt \ 238 zroot /dev/disk/by-id/xxx 239 #+end_src 240 241 ~zroot~ is what I've decided to call this ~zpool~. 242 **** Customization 243 ***** ~ashift~ 244 The ashift values are for performance and your system will work if you get them 'wrong'. In fact, the Arch Wiki recommends always using ~ashift=12~ for compatibility with other ~zpools~. 245 ***** ~atime~ 246 It's almost never useful to know the access time of a file so I just disable it altogether. It serves only to slow down your computer, especially when using a CoW filesystem like ~zfs~. Some would say this messes up Mail programs such as ~mutt~, but I have a fix for this. 247 248 If you still want atimes, swap ~atime=off~ for ~atime=on~. I believe this is the equivalent to 'stricatime' on other filesystems. 249 250 You could also go for 'relatime', where an access time is only updated if the old access time is more than a day old, or if the modification time or change time are more recent. To do this, simply swap any line you have involving atime with ~relatime=on~. 251 ***** Compression 252 This is pretty useless on most people's root filesystem because most of your data is probably media, which is already compressed. This will likely only slow down your system and not save you much space. Nevertheless, if you want to have it, simply add this line: ~-O compression=lz4~. 253 254 *** ~dataset~ creation 255 #+begin_src shell 256 # General datasets 257 zfs create -o mountpoint=none zroot/data 258 zfs create -o mountpoint=none zroot/ROOT 259 zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default 260 # Home datasets 261 zfs create -o mountpoint=/home zroot/data/home 262 zfs create -o mountpoint=/root zroot/data/home/root 263 zfs create -o mountpoint=/home/ryan zroot/data/home/ryan 264 zfs create -o mountpoint=/home/ryan/.local zroot/data/home/ryan/local 265 zfs create -o mountpoint=/home/ryan/.local/share zroot/data/home/ryan/local/share 266 # If you're a degenerate who plays vidya 267 zfs create -o mountpoint=/home/ryan/.local/share/Steam zroot/data/home/ryan/local/share/Steam 268 zfs create -o mountpoint=/home/ryan/.cache zroot/data/home/ryan/cache 269 zfs create -o mountpoint=/home/ryan/.cache/yay zroot/data/home/ryan/cache/yay 270 # If you want to use mailclients such as mutt 271 zfs create -o mountpoint=/home/ryan/.Maildir zroot/data/home/ryan/mail 272 # System datasets 273 zfs create -o mountpoint=/var -o canmount=off zroot/var 274 zfs create zroot/var/log 275 zfs create -o mountpoint=/var/lib -o canmount=off zroot/var/lib 276 zfs create zroot/var/lib/libvirt 277 zfs create zroot/var/lib/docker 278 279 # Set zpool as bootable 280 zpool set bootfs=zroot/ROOT/default zroot 281 #+end_src 282 *** Mounting 283 Export the ~zpool~ (this is required), then import it (no, the ~/dev/disk/by-id~ isn't a mistake) and mount. 284 285 #+begin_src shell 286 zpool export zroot 287 zpool import -d /dev/disk/by-id -R /inst zroot 288 zfs load-key zroot 289 zfs mount zroot/ROOT/default 290 zfs mount -a 291 #+end_src 292 293 If you have errors during this step, try exporting ~zroot~ again and then reimporting it (to a new directory, i.e. replace ~/inst~) with different settings. ~ls~ the mountpoint to make sure it's empty. You can also ~df~ the mountpoint after mounting, and if the output says ~airootfs~ there has been an error, it should be ~zroot/ROOT/default~. 294 295 If all is good we need to mount the auxiliary filesystems: 296 297 #+begin_src shell 298 mkdir /inst/boot 299 mount /dev/mapper/cboot /inst/boot 300 mkdir /inst/boot/efi 301 mount /dev/sda1 /inst/boot/efi 302 #+end_src 303 304 Lastly, we need to copy the ZFS cache: 305 306 #+begin_src shell 307 cp /etc/zfs/zpool.cache /inst/etc/zfs/zpool.cache 308 #+end_src 309 310 If there is an error about the cache file not existing, then: 311 312 #+begin_src shell 313 zpool set cachefile=/etc/zfs/zpool.cache zroot 314 cp /etc/zfs/zpool.cache /inst/etc/zfs/zpool.cache 315 #+end_src 316 317 *** ~pacstrap~ 318 If you haven't already we need to set up an internet connection. If you followed my instructions to crate an Arch ISO then yours should have NetworkManager, so we can set up networking like so: 319 320 #+begin_src shell 321 systemctl start NetworkManager 322 nmcli device wifi connect "ssid" password "networkpassword" 323 #+end_src 324 325 (Obviously replace ssid with your ssid etc. etc.) 326 327 ~pacman~ will fail to get the zfs-arch repos due to a gpg-related error. We can fix this by importing the arch-zfs gpg key like so: 328 329 #+begin_src shell 330 curl https://archzfs.com/archzfs.gpg > archzfs.gpg 331 pacman-key --add archzfs.gpg 332 #+end_src 333 334 Now we can ~pacstrap~ (make sure to replace ~intel-ucode~ with ~amd-ucode~ if you have an AMD processor)! 335 336 #+begin_src shell 337 pacstrap -i /inst base base-devel zfs-linux linux-headers linux-firmware intel-ucode zsh go git python cmake networkmanager joe emacs 338 cp /etc/pacman.conf /inst/etc/. 339 #+end_src 340 341 *** ~fstab~ and ~crypttab~ 342 To generate the fstab file: 343 344 #+begin_src shell 345 genfstab -U -p /inst >> /inst/etc/fstab 346 #+end_src 347 348 Edit the ~/inst/etc/fstab~ file and remove any entries related to ZFS (we will mount them the ZFS way). Also, replace the UUID's of the ~cswap~ and ~cboot~ partitions with ~/dev/mapper/cswap~ and ~/dev/mapper/cboot~ respectively. 349 350 Sample fstab: 351 #+begin_src 352 # Static information about the filesystems. 353 # See fstab(5) for details. 354 355 # <file system> <dir> <type> <options> <dump> <pass> 356 # /dev/mapper/cboot 357 /dev/mapper/cboot /boot ext4 rw,relatime 0 2 358 359 # /dev/sda1 360 UUID=CE42-9249 /boot/efi vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 2 361 362 # /dev/mapper/cswap 363 /dev/mapper/cswap none swap defaults 0 0 364 365 #+end_src 366 367 Lastly, edit ~/inst/etc/crypttab~ and add this line to the bottom: 368 369 #+begin_src 370 cswap /dev/disk-by-id/xxx /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256 371 #+end_src 372 373 You will need to insert the id of your swap partition manually. 374 375 Insert a new line at the very bottom of the file (or just make sure it ends with an empty line) and save. 376 377 *** Configuring the System 378 To begin configuration of the system we need to ~arch-chroot /inst~. 379 380 **** Set Up the Kernel 381 Edit the file ~/etc/mkinitcpio.conf~, delete the line that begins with `HOOKS=' and replace it with 382 383 #+begin_src 384 HOOKS=(base udev autodetect modconf block keyboard zfs encrypt filesystems) 385 #+end_src 386 387 Then run: 388 389 #+begin_src shell 390 mkinitcpio -P 391 #+end_src 392 393 394 **** GRUB 395 Edit the file ~/etc/default/grub~ and replace `GRUB_CMDLINE_LINUX' with: 396 397 #+begin_src 398 GRUB_CMDLINE_LINUX="zfs=zroot/ROOT/default rw cryptdevice=/dev/sda2:cboot" 399 #+end_src 400 401 Uncomment ~GRUB_ENABLE_CRYPTODISK=y~ and save the file. To install GRUB: 402 403 #+begin_src shell 404 grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB 405 ZPOOL_VDEV_NAME_PATH=1 grub-mkconfig -o /boot/grub/grub.cfg 406 #+end_src 407 408 **** Misc 409 Remember to: 410 - Set the hostname in ~/etc/hostname~ 411 - Generate locales 412 - Create a user and set the password 413 - Set the root password 414 - Set up your timezone and enable ~ntpd~ 415 - Change your shell to ZSH (THIS IS REQUIRED) 416 - Install ~X~ and ~pulseaudio~ (make sure you have the right ~X~ drivers [I made that mistake...]) 417 - Set up a ~yay~/~AUR~ managers 418 - enable systemd services (NM, sshd, etc.) 419 420 421 **** Configure ZFS 422 423 The last bit of required ZFS configuration is to set it up for automounting and autoconfiguring. 424 425 #+begin_src shell 426 # Set the hostid 427 zgenhostid $(hostid) 428 # Set up the cachefile and auto-import it 429 zpool set cachefile=/etc/zfs/zpool.cache zroot 430 systemctl enable zfs-import-cache 431 systemctl enable zfs-import.target 432 # Set up zed 433 mkdir /etc/zfs/zfs-list.cache/ 434 touch /etc/zfs/zfs-list.cache/zroot 435 ln -s /usr/lib/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d 436 systemctl enable zfs-zed.service 437 systemctl enable zfs.target 438 #+end_src 439 440 Now start ~zed~ through the command line, and ~cat~ ~/etc/zfs/zfs-list.cache/zroot~. It should be empty, to populate it, make a change to the filesystem: 441 442 #+begin_src shell 443 zfs set atime=on zroot/data/home/ryan/mail 444 #+end_src 445 446 ~cat~ the same file again and now it should be full. If you don't have the mail dataset, just make that same change to any other dataset, then just undo it by setting ~atime=off~ again. 447 448 **** Restart 449 */DO NOT SKIP THIS/* 450 Double check everything first! 451 #+begin_src shell 452 exit # the arch-chroot 453 umount /inst/boot -R 454 zfs umount -a 455 zpool export zroot 456 swapoff -a 457 #+end_src 458 459 *NOW* you may reboot. 460 461 * Post-Install Configuration 462 NOTE: All of the following commands new to run as root. 463 #+begin_src conf 464 ** Scrub 465 Scrub is a feature of ZFS to prevent bitrot, a phenonenon in which a drive wears out and some of the data on it slowly becomes corrupted. ZFS has the ability to scan for and prevent this from happening, a feature called 'scrub'. To preiodically scrub your zpool you will first need to set up an AUR helper, I'll be using ~yay~. Then, enable the systemd service like so: 466 467 #+begin_src shell 468 yay -Syu systemd-zpool-scrub 469 systemctl enable zpool-scrub@zroot.timer 470 #+end_src 471 ** zfs-arch gpg key 472 Having the ~SigLevel TrustAll~ at the bottom of ~pacman.conf~ is rather unsafe, so we're going to set up archzfs's pgp key. 473 The following steps include: 474 - Setting up the Arch Linux packages keyring 475 - Set up a new keyserver (if necessary) 476 - Add the archzfs pgp key and verify it 477 478 #+begin_src shell 479 pacman-key --init 480 pacman-key --populate archlinux 481 pacman-key -r DDF7DB817396A49B2A2723F7403BD972F75D9D76 482 pacman-key --lsign-key DDF7DB817396A49B2A2723F7403BD972F75D9D76 483 pacman -Syu 484 #+end_src 485 486 If the third step fails then you can append the following line to ~/etc/pacman.d/gnupg/gpg.conf~: 487 488 #+begin_src 489 keyserver hkp://ipv4.pool.sks-keyservers.net:11371 490 #+end_src 491 492 You should also delete any other line that starts with 'keyserver'. If that fails too, look up other trusted keyservers to try. 493 494 * Fin 495 At this point your ZFS-on-root operating system is fully configured and ready to go. Make sure you know how ZFS works if you're going to continue using it and to make full use of the filesystem's features. I recommend reading the articles below for more information. Now have fun with your future-proofed system! 496 497 * Sources 498 Most of the information in this comes from other sources online rather than myself. Here are the ones that were the most helpful (in no particular order): 499 500 - [[https://artnoi.com/blog/zfsarch.html][Artnoi's Arch ZFS on Root]] 501 - [[https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_ZFS][Arch Wiki's ZFS Install Guide]] 502 - [[https://wiki.archlinux.org/index.php/User:Altercation/Bullet_Proof_Arch_Install][Arch Wiki's User Guide to Installing Btrfs]] 503 - [[https://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/][Pavel Kogan's Article on Full Disk Encryption]] 504 - [[https://wiki.archlinux.org/index.php/ZFS][Arch Wiki's Article on ZFS]] 505 - [[https://wiki.archlinux.org/index.php/Archiso][Arch Wiki's Guide on Arch ISOs]] 506 - [[https://wiki.archlinux.org/index.php/Pacman/Package_signing][Arch Wiki's Article on GPG Keys In ~pacman~]]