Arch linux installation script to be reviewed for any leakage of personal / security info

While I have been teaching myself a little about linux, it's boot processes and service configuration I have been using arch linux in virtualbox for my experimentation.

Eventually after much wiling an gnashing of teeth I managed to get a fully functional minimal arch system to the point where I can build upon it as I would in most other distributions (boots, presents a console, has a functional package manager etc).

Since an arch install involves a lot of typing (when you fail at it many many times), I created a simple script on my bootable system (sdb disk) to make my life easier. This appears to work well but I am not familiar with the details of what is really going on. Before I pass on the script or any images I have derived from it's output, please could this script be reviewed for:

• Any personal info or security keys etc being exported from my running arch distro into the new image

• Any unpredictability in the scripts behaviour which might be dangerous

The use of a named target drive (sda) and the pathetic default root password is deliberate.

DO NOT RUN THIS IF YOU DO NOT UNDERSTAND EXACTLY WHAT IT WILL DO

#!/bin/sh

# Setting keymap
echo -- Setting keymap
sleep 2

# Checking internet connectivity and synchronizing to network time
echo -- Checking internet connectivity and synchronizing to network time
ping -c 4 archlinux.org
timedatectl set-ntp true
sleep 2

# Wiping out whatever is on sda and creating GPT partitions
#     4MB (BIOS BOOT) grub2 partition
#     4GB (Linux filesystem) swap partition
#     256MB (Linux filesystem) boot partition
#     rest (Linux filesystem) lvm2 physical volume
echo -- Wiping out whatever is on sda and creating GPT partitions
fdisk -l
echo "
p
g
n

+4M
t
4
n

+4G
Y
n

+256M
Y
n

Y
p
w
" | fdisk /dev/sda
fdisk -1
sleep 2

# Creating the lvm2 volumes
#     Make a volume group vdisk from sda4
#     Make a "main" logical volume of 5GB from the vdisk
echo -- Creating the lvm2 volumes
pvdisplay
vgcreate vdisk /dev/sda4
pvdisplay
vgdisplay
lvcreate -L 5g vdisk -n main -y
vgdisplay
lvdisplay
ls /dev/mapper
sleep 2

# Formatting disks as swap/ext4
echo -- Formatting disks as swap/ext4
mkswap /dev/sda2
echo "y" | mkfs.ext4 /dev/sda3
echo "y" | mkfs.ext4 /dev/mapper/vdisk-main
sleep 2

# Mounting the swap and filesystems in position for installation
echo -- Mounting the swap and filesystems in position for installation
swapon /dev/sda2
mount /dev/mapper/vdisk-main /mnt
mkdir /mnt/boot
mount /dev/sda3 /mnt/boot
sleep 2

# Install arch linux packages to the new filesystems
echo -- Install arch linux packages to the new filesystems
pacstrap /mnt base lvm2 grub net-tools
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
sleep 2

# chrooting into the installed base
echo -- chrooting into the installed base
echo '
# Set the time
echo -- Set the time
ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime
hwclock --systohc
sleep 2

# Create locales
echo -- Create locales
sed -i s/#en_US.UTF-8/en_US.UTF-8/g /etc/locale.gen
sed -i s/#en_GB.UTF-8/en_GB.UTF-8/g /etc/locale.gen
cat /etc/locale.gen
echo LANG=en_GB.UTF-8 > /etc/locale.conf
cat etc/locale.conf
locale-gen
sleep 2

# Persist keymap
echo -- Persist keymap
echo KEYMAP=uk > /etc/vconsole.conf
cat /etc/vconsole.conf
sleep 2

# Set network configuration
echo -- Set network configuration
echo archbase > /etc/hostname
cat /etc/hostname
echo "127.0.0.1   localhost
::1         localhost
127.0.1.1   archbase.localdomain   archbase" >> /etc/hosts
cat /etc/hosts
cp /etc/netctl/examples/ethernet-dhcp /etc/netctl/enp0s3
sed -i s/eth0/enp0s3/g /etc/netctl/enp0s3
cat /etc/netctl/enp0s3
netctl enable enp0s3
sleep 2

# Create the initramfs
echo -- Create the initramfs
echo "MODULES=()
BINARIES=()
FILES=()
HOOKS=(base udev autodetect modconf block lvm2 filesystems keyboard fsck)
" > /etc/mkinitcpio.conf
mkinitcpio -p linux
echo "      root
root" | passwd
sleep 2

echo -- Install the grub bootloader
echo "
" >> /etc/default/grub
grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
sleep 2

# done
echo -- done
exit
' | arch-chroot /mnt

# Manually remove any other boot media and reboot system
echo -- Manually remove any other boot media and reboot system

• The warning posted is a good one. It will prevent anyone who is completely unaware of linux systems from running it just-because. Anyone with the least awareness of linux system internals will see the Wiping out whatever is on sda and creating GPT partitions and be suitably cautious. I'm comfortable that the warning is appropriate, and adequate. Note that scripts performing these types of actions cannot have user-input confirmations. – rolfl Apr 18 '18 at 20:32

Some notes:

• This script is really very brittle. It'll break if any of the tools change in any significant way, if your disk layout changes (see below), or if the sequence of steps for whatever reason is not right in future versions of Arch Linux. It's a nice exercise to make sure you've understood the installation process, but in my experience these scripts are basically used once and then have to be tweaked for every future version of anything.
• On a related note, once you have a working Arch Linux VM the beauty of this rolling distro is that keeping the VM up to date is mostly trivial. Keep an eye out for anything that has to be manually updated and the VM should be usable and secure for the foreseeable future. Which means you probably won't need the script again for a very long time. Which again, unfortunately, means that it will probably break in weird ways next time you actually need it.
• Use disk UUIDs instead of /dev/sdX names to avoid clobbering the wrong disk if you rearrange things in BIOS.
• It looks like the sleeps are in order to check that the state looks sane during install. For this I would instead write a small function that would wait for a sleep 1m or something but which can be dismissed with a keypress (read -n 1) once the user has inspected the results. That way it can be used interactively but will also work automatically with a finite delay. Personally I'd get rid of the sleeps but log to a file, and either make sure the file is persisted or that I don't reboot before inspecting it.
• There's no need to loadkeys in a script like this - the setting will be gone once you reboot the new system.
• You only need ping -c 1 […] to check Internet connectivity.
• The canonical way to answer "y" to any prompts is yes | [your command].
• The biggest unpredictability here is how bad things can get if any one command fails but the script continues. Make sure to set -o errexit -o pipefail within the main script and the stuff you pass to arch-chroot to make sure the script stops as soon as anything fails.
• The canonical way to pass multiline strings to standard input is with a here document:

my_command <<EOF
[input]
EOF

• There is no way to prove a negative, but I don't see any way that secrets would leak from your host to the new OS. The Arch Linux installation is really very simple in terms of how much gets executed, and anything you do as part of it does what it says on the tin, nothing more. If you're worried about specific secrets leaking, why not inspect the resulting system for traces of those secrets specifically? (Making sure not to actually search for secrets in such a way as to make them appear in ~/.bash_history or something.)

Your echo "multi-line input" | fdisk /dev/sda command is horrendous to read and maintain. The Arch Linux wiki page about partitioning states:

Clearly, you should be using sfdisk instead of fdisk — both of which are part of the same util-linux package.

sfdisk -X gpt /dev/sda <<PARTITION_TABLE
,4M,21686148-6449-6E6F-744E-656564454649
,4G,S
,256M
,,E6D6D379-F507-44C2-A23C-238F2A3DF928
PARTITION_TABLE


Note that 21686148-6449-6E6F-744E-656564454649 is the GPT partition type GUID for GRUB BIOS, and E6D6D379-F507-44C2-A23C-238F2A3DF928 is the code for LVM.

I recommend using this <<HERE_DOC syntax for the arch-chroot /mnt command as well, instead of piping from an echo command.

• Does specifying the E6D6D3.... LVM partition code with sfdisk make modify what is done with vgcreate or in any way cause a different final result? – RidiculousRichard May 11 '18 at 22:03
• Does it matter that I am using LVM2; I am aware it is backwards compatible ( kerneltalks.com/linux/difference-lvm-and-lvm2-linux-interview ) but is LVM2 limited or constrained in any way by the LVM partition type? – RidiculousRichard May 11 '18 at 22:05
• I note you are using S (as a 'shortcut' for the swap 0657FD... identifier); was it significant that you didn't use L (linux 0FC63D...) or V (LVM E6D6D3...) rather than an arbitrary choice? – RidiculousRichard May 11 '18 at 22:20
• NB: Although the arch wiki links to documentation that says you can use or V for LVM E6D6D3..., the current sfdisk package doesn't support it. – RidiculousRichard May 11 '18 at 22:34

To augment IObO's answer, it should be noted that pacstrap does copy your mirror list and keyring to the new install to facilitate future updating, but this can leave personally identifying information in the new image.