joshrosso

Arch Linux and Windows 10 (UEFI + Encrypted) Install Guide

This post details the installation process for my work and personal computers. At a high-level, my setup is a dualboot system running Windows 10 and Arch Linux. The Windows partition is encrypted with VeraCrypt and the Linux partition with LUKS. The post will detail the step-by-step. The video link below providers more context on how all the pieces fit together.

Installation Media

This section covers creating installation media for Windows and Arch Linux. You'll need 2 USB drives sized to >= 8GB. These steps cover media creation from Windows (for the Windows 10 ISO) and Linux (for the Arch Linux ISO) workstations. There are many alternative ways to create installation media. If you choose to go with an alternative, skip this section.

Windows Installation Media

As of Windows 10, Microsoft requires you to download a tool to create windows installation media. This .exe requires a Windows host to create the installation media. If you do not have a Windows host to run this installer, Microsoft offers a USB for purchase.

Windows did not historically have this restriction. For example, Windows 8. You could follow this guide using Window 8. To create installation media directly from an ISO, consider WoeUSB.

Arch Linux Installation Media

  1. Download the Arch Linux ISO.

    https://www.archlinux.org/download

  2. Insert a USB drive.

  3. List block devices and determine the device name.

    lsblk
    
    NAME                    MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    sda                       8:0    1  29.2G  0 disk
    |-sda1                    8:1    1   602M  0 part
    `-sda2                    8:2    1    64M  0 part
    nvme0n1                 259:0    0   477G  0 disk
    |-nvme0n1p1             259:1    0   512M  0 part  /boot
    `-nvme0n1p2             259:2    0 476.4G  0 part
      `-cryptroot\x5cx2callow-discards\x5cx2cheader
                            254:0    0 476.4G  0 crypt
        `-vg0-root          254:1    0 476.4G  0 lvm   /
    

    In the above example, the USB drive is sda.

  4. Write the ISO to the device using dd.

    dd bs=4M if=path/to/archlinux.iso of=/dev/sdx status=progress oflag=sync
    
    • dd: copies and converts a file based on arguments.
    • bs: amount of bytes to write at a time.
    • if: specify a file to read rather than stdin.
    • of: specify a file to write to rather than stdout.
    • status: level to log to stderr; progress shows periodic transfer stats.
    • oflag: set to sync synchronizes I/O for data and metadata.

BIOS Settings

  1. Boot into BIOS.

    Often accomplished by hitting F2 on start-up.

  2. Verify UEFI booting is enabled.

  3. Verify Secure Boot is disabled.

    Arch Linux can be installed with Secure Boot. See https://wiki.archlinux.org/index.php/Secure_Boot

Installing Windows

This section covers installing Windows. Installing it first allows reuse of the Windows-created EFI partition. Using VeraCrypt, the Windows partition will be encrypted.

  1. Insert the USB containing Windows.

  2. Power on.

  3. While booting, open the device boot menu.

    Often achieved by hitting F12 during boot.

  4. Select the USB device in UEFI mode.

    If you boot in legacy mode, the Arch UEFI installation will not work.

  5. Select the language to install and click Next.

  6. Click Install now.

  7. Enter your product key and click Next.

  8. Accept the license terms and click Next.

  9. Click Custom: Install Windows only (advanced).

  10. Delete all existing partitions.

  11. Create a new partition of the size you'd like Windows to occupy.

    Windows creates additoinal partitions including the 100.0MB System partition that will act as the EFI partition. 1. Click Next and wait for Windows to install.

    After the installation completes, the machine will reboot.

  12. After reboot, go through the Windows setup procedure.

  13. Open Control Panel.

  14. In the top right search, enter power.

  15. Click Change what the power buttons do.

  16. Clickk Change settings that are unavailable.

  17. Uncheck Turn on fast startup (recommended).

    To understand why fast startup is not recommended, see https://wiki.archlinux.org/index.php/Dual_boot_with_Windows#Fast_Start-Up

  18. Open Start > Settings > Update & Security and Check for updates.

  19. Allow all Windows updates to download and install before proceeding.

  20. Download and install VeraCrypt.

    https://www.veracrypt.fr/en/Downloads.html

  21. Launch VeraCrypt.

  22. From the menu bar, open System > Encrypt System Partition/Drive

  23. Choose Normal.

  24. Choose Encrypt the Windows system partition.

  25. Choose Single-boot.

    While you will have a multi-boot system eventually. This installation will have grub point to veracrypt that will then decrypt and point to windows. Thus, vercrypt needs to know nothing about Linux.

  26. Choose your preferred encryption algorithm and click Next.

  27. Create a strong password.

  28. Allow VeraCrypt to collect random data.

  29. If desired, create a rescue disk.

    This will require a USB drive to save to.

  30. Choose your preferred Wipe Mode.

  31. Run the System Encryption Pretest.

    This will require your machine to be restarted.

  32. Upon restart, enter your encryption password when prompted.

  33. Log back in to your Windows system.

  34. VeraCrypt will pop back up to tell you the Pretest Completed.

  35. Click Encrypt and run the encryption.

    This will encrypt the file system and take several minutes.

  36. Allow the encryption to complete.

  37. Power off the machine.

Installing Arch Linux

This section covers installing Arch Linux. Using Linux Unified Key Setup (LUKS), the root partition will be encrypted.

  1. Insert the USB containing Arch Linux.

  2. Boot the machine.

  3. While booting, open the device boot menu.

    Often a key like F12 launches the boot menu.

  4. Select the USB device.

    If legacy boot is enabled on your system, assure you're choosing to boot the USB via UEFI.

  5. At the Arch Boot Menu, hit e at the menu to edit parameters.

  6. Add nomodeset video=1280x760 to the list of commands.

    This boots the installer in lower resolution making the console easier to see.

  7. Run wifi-connect and select a wireless network.

    If plugged into ethernet, this step can be skipped.

  8. Validate connectivity.

    ping google.com   
    
    PING google.com (216.58.193.206) 56(84) bytes of data.
    64 bytes from lax02s23-in-f14.1e100.net time=809 ms
    64 bytes from lax02s23-in-f14.1e100.net time=753 ms
    

After the steps above, I always start sshd (included in the archiso) and finish the installation process from another computer. This enables me to have access to copy and paste, editors, and browsers rather than the restricted terminal on my target machine. This is optional, but the steps below may make your experience better.

  1. Set a root passwd for archiso.

    passwd
    
  2. Enable sshd.

    systemctl start sshd
    
  3. Determine your local address using ip a.

  4. From another machine, ssh in.

    ssh root@${TARGET_MACHINE_IP}
    

    From this point forward, I'm completing the installation from another Linux desktop. You can also use Windows (putty) or Mac.

Disk Partitioning

  1. List block devices to determine the name of the drive.

    lsblk
    
    NAME                                            MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    nvme0n1                                         259:0    0   477G  0 disk  
    |-nvme0n1p1                                     259:1    0   512M  0 part  /boot
    `-nvme0n1p2                                     259:2    0 476.4G  0 part  
      `-cryptroot\x5cx2callow-discards\x5cx2cheader 254:0    0 476.4G  0 crypt 
        `-vg0-root                                  254:1    0 476.4G  0 lvm   /
    

    In the above, the drive is mapped to /dev/nvme0n1.

  2. Launch cgdisk for the drive above.

    cgdisk /dev/nvme0n1
    

    cgdisk is an ncurses-based GUID partition table manipulator. Unlike the command-only fdisk approach, cgdisk provides a text-menu for writing partitions.

  3. Select the free space.

  4. Choose [ New ].

  5. Enter no value for First sector (chooses default).

    This means the Linux partition starts directly at the end of the Windows partition. Some believe it is best to leave a small amount of free space between partitions. However, I have not had issues with this.

  6. Enter 512Mib for size in sectors.

    This is the end size of the partition.

  7. Enter no value for Hex code or GUID (chooses default).

    Default is 8300, Linux filesystem. A list can be found at https://gist.github.com/gotbletu/a05afe8a76d0d0e8ec6659e9194110d2

  8. Name the partition boot.

  9. Note the partition number of the EFI System partition. This will be referenced later when configuring grub. In the screenshots above, it is partition 2.

  10. Select the free space.

  11. Choose [ New ].

  12. Enter no value for First sector (chooses default).

  13. Enter no value for size in sectors (chooses default).

    This will fill the remaining disk.

  14. Enter no value for Hex code or GUID (chooses default).

  15. Name the partition root.

  16. Choose [ Write ] and say yes.

  17. Choose [ Quit ].

Encrypting and Configuring the Root Partition

  1. Encrypt the root partition.

    cryptsetup -y --use-random luksFormat /dev/nvme0n1p6
    

    At the confirmation prompt, be sure to type YES in uppercase.

    • -y: interactively requests the passphrase twice.
    • --use-random: uses /dev/random to produce keys.
    • luksFormat: initializes a LUKS partition.
  2. Open the LUKS device

    cryptsetup luksOpen /dev/nvme0n1p6 cryptroot
    
    • luksOpen: Opens the LUKS device and creates a mapping in /dev/mapper.
  3. Run lsblk to view the new volume relationship.

  4. Format the boot partitions as an ext4 file system.

    mkfs.ext4 /dev/nvme0n1p5
    
  5. Format the cryptroot as a ext4 file system.

    mkfs.ext4 /dev/mapper/cryptroot
    

Mounting and Installing

  1. Mount cryptroot at /mnt.

    mount /dev/mapper/cryptroot /mnt
    
  2. Create a boot directory at root.

    mkdir /mnt/boot
    
  3. Mount the boot directory to the boot partition.

    mount /dev/nvme0n1p5 /mnt/boot 
    
  4. Create an efi directory in /mnt/boot.

    mkdir /mnt/boot
    
  5. Mount the Window's created EFI partition to /mnt/boot.

    mount /dev/nvme0n1p2 /mnt/boot/efi
    

    This is the partition you noted in the Disk Partitioning section.

  6. Install packages on the root file system.

    pacstrap /mnt linux linux-firmware base base-devel grub efibootmgr vim git intel-ucode networkmanager
    
  7. Generate file system table (fstab) for mounting partitions.

    genfstab -U /mnt >> /mnt/etc/fstab
    
    • -u: Use UUIDs for source identifiers.

System Configuration

This section enters the new Arch Linux system and configures the system.

  1. Enter the system root via arch-chroot.

    arch-chroot /mnt
    
  2. Set the timezone.

    ln -sf /usr/share/zoneinfo/MST /etc/localtime
    

    MST is my zone, yours may vary.

  3. Set the Hardware Clock from the System Clock, and update the timestamps in /etc/adjtime.

    hwclock --systohc
    
  4. Uncomment en_US.UTF-8 UTF-8 in /etc/locale.gen.

    #en_SG.UTF-8 UTF-8  
    #en_SG ISO-8859-1  
    en_US.UTF-8 UTF-8  
    #en_US ISO-8859-1  
    #en_ZA.UTF-8 UTF-8  
    

    Modify for your locale.

  5. Generate locale.

    locale-gen
    
  6. Set the LANG variable to the same locale in /etc/locale.conf.

    echo "LANG=en_US.UTF-8" >> /etc/locale.conf
    
  7. Set your hostname.

    echo "taco" >> /etc/hostname
    

Initial Ramdisk Configuration

The initial ramdisk is a root file system that will be booted into memory. It aids in startup. This section covers setup and generation of an mkinitcpio configuration for generating initramfs.

  1. Add encrypt to HOOKS in /etc/mkinitcpio.conf (order matters).

    HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)
    

    HOOKS are modules added to the initramfs image. Without encrypt and lvm2, systems won't contain modules necessary to decrypt LUKs.

  2. Move keyboard before modconf in HOOKS.

    HOOKS=(base udev autodetect keyboard modconf block encrypt filesystems fsck)
    
  3. Build initramfs with the linux preset.

    mkinitcpio -p linux
    

GRUB Bootloader Setup

  1. Determine the UUID of your root partition and EFI parition.

    blkid
    
  2. Edit the GRUB boot loader configuration.

    vim /etc/default/grub
    
  3. Update the GRUB_CMDLINE_LINUX to match the format cryptdevice=UUID=${ROOT_UUID}:cryptroot root=/dev/mapper/cryptroot where ${ROOT_UUID} is the UUID captured above.

    GRUB_CMDLINE_LINUX="cryptdevice=UUID=4f7301bf-a44f-4b90-ad6d-5ec10a0c2f2a:cryptroot root=/dev/mapper/cryptroot"
    
  4. Add grub menu item for Windows 10 by editing /etc/grub.d/40_custom.

    #!/bin/sh
    exec tail -n +3 $0
    # This file provides an easy way to add custom menu entries.  Simply type the
    # menu entries you want to add after this comment.  Be careful not to change
    # the 'exec tail' line above.
    if [ "${grub_platform}" == "efi" ]; then
      menuentry "Windows 10" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid
        insmod chain
        # use:
        # after --set=root, add the EFI partition's UUID
        # this can be found with either:
        #
        # a. blkid
        # - or -
        # b. grub-probe --target=fs_uuid /boot/efi/EFI/VeraCrypt/DcsBoot.efi
        #
        search --fs-uuid --set=root $FS_UUID
        chainloader /EFI/VeraCrypt/DcsBoot.efi
      }
    fi
    
  5. Replace $FS_UUID with the EFI partition's UUID, found in step 1 of this section.

    #!/bin/sh
    exec tail -n +3 $0
    # This file provides an easy way to add custom menu entries.  Simply type the
    # menu entries you want to add after this comment.  Be careful not to change
    # the 'exec tail' line above.
    if [ "${grub_platform}" == "efi" ]; then
      menuentry "Windows 10" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid
        insmod chain
        # use:
        # after --set=root, add the EFI partition's UUID
        # this can be found with either:
        #
        # a. blkid
        # - or -
        # b. grub-probe --target=fs_uuid /boot/efi/EFI/VeraCrypt/DcsBoot.efi
        #
        search --fs-uuid --set=root 8E12-69DD
        chainloader /EFI/VeraCrypt/DcsBoot.efi
      }
    fi
    
  6. Install grub.

    grub-install
    

    This assumes your efi is located in /boot/efi; additional flags are available if you used an alternative location.

  7. Generate the grub configuration.

    grub-mkconfig -o /boot/grub/grub.cfg
    

User Administration

  1. Set the root password.

    passwd
    
  2. Add a user.

    useradd -m -G wheel josh
    
    • -G adds the user to a group.
    • -m creates a home directory.
  3. Set the user's password.

    passwd josh 
    
  4. Enter visudo.

    visudo
    

    visudo edits the sudoers files at /etc/sudoers. It does this safely by acquiring a lock.

  5. Uncomment the lines that allow users of group wheel to sudo.

    ## Uncomment to allow members of group wheel to execute any command
    %wheel ALL=(ALL) ALL
    

Enable Networking

  1. Enable NetworkManager to ensure it starts after boot.

    systemctl enable NetworkManager
    

Rebooting

  1. Exit the arch-chroot

    exit
    
  2. Unmount the partitions.

    umount -R /mnt
    
  3. Reboot.

    reboot
    
  4. Using grub, login to Arch linux.

  5. Use nmtui-connect to establish internet and begin installing packages.

    From here you can install any window manager such as:

Contents