2025-11-22 23:15:27 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -a
|
|
|
|
|
set -E
|
|
|
|
|
revision=1.0h
|
|
|
|
|
|
|
|
|
|
## Tput codes
|
|
|
|
|
reset=$(tput sgr0)
|
|
|
|
|
|
|
|
|
|
bold=$(tput bold)
|
|
|
|
|
italic=$(tput sitm)
|
|
|
|
|
blink=$(tput blink)
|
|
|
|
|
|
|
|
|
|
black=${reset}$(tput setaf 0)
|
|
|
|
|
red=${reset}$(tput setaf 1)
|
|
|
|
|
green=${reset}$(tput setaf 2)
|
|
|
|
|
yellow=${reset}$(tput setaf 3)
|
|
|
|
|
blue=${reset}$(tput setaf 4)
|
|
|
|
|
magenta=${reset}$(tput setaf 5)
|
|
|
|
|
cyan=${reset}$(tput setaf 6)
|
|
|
|
|
white=${reset}$(tput setaf 7)
|
|
|
|
|
|
|
|
|
|
# Color codes
|
|
|
|
|
function say
|
|
|
|
|
{
|
|
|
|
|
for format in ${@:2}
|
|
|
|
|
do
|
|
|
|
|
echo -n ${!format}
|
|
|
|
|
done
|
|
|
|
|
echo -e "${1}"
|
|
|
|
|
echo -n ${reset}
|
|
|
|
|
}
|
|
|
|
|
function say_n
|
|
|
|
|
{
|
|
|
|
|
for format in ${@:2}
|
|
|
|
|
do
|
|
|
|
|
echo -n ${!format}
|
|
|
|
|
done
|
|
|
|
|
echo -e -n "${1}"
|
|
|
|
|
echo -n ${reset}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Exit function
|
|
|
|
|
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
|
|
|
|
function die
|
|
|
|
|
{
|
|
|
|
|
cat <<- abort
|
|
|
|
|
${red}
|
|
|
|
|
Error encountered for the following reason:
|
|
|
|
|
${yellow}
|
|
|
|
|
"${1}"
|
|
|
|
|
${red}
|
|
|
|
|
Script aborted...
|
|
|
|
|
${reset}
|
|
|
|
|
abort
|
|
|
|
|
exit 77
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Repeat a command until it exits with code 0
|
|
|
|
|
function repeat
|
|
|
|
|
{
|
|
|
|
|
until ${@}
|
|
|
|
|
do
|
|
|
|
|
sleep 3
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Read flags
|
|
|
|
|
rm -f sshkeys
|
|
|
|
|
while [ ${1} ]
|
|
|
|
|
do
|
|
|
|
|
case ${1} in
|
|
|
|
|
-s | --ssh-key )
|
|
|
|
|
if [ "${2}" ]
|
|
|
|
|
then
|
|
|
|
|
echo "${2}" >>sshkeys
|
|
|
|
|
if ! ssh-keygen -l -f sshkeys >/dev/null
|
|
|
|
|
then
|
|
|
|
|
die 'Invalid SSH public key detected'
|
|
|
|
|
fi
|
|
|
|
|
shift
|
|
|
|
|
fi
|
|
|
|
|
;;
|
|
|
|
|
-? | -h | --help )
|
|
|
|
|
cat <<- help
|
|
|
|
|
Parameters:
|
|
|
|
|
-s, --ssh-key Add SSH public key (enclosed in quotes)
|
|
|
|
|
-?, -h, --help This help screen
|
|
|
|
|
help
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
* ) die "Unknown flag: ${1}"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
shift
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Ensure pacman.conf settings are properly set
|
|
|
|
|
if [ ! -f /etc/pacman.conf.bkp ]
|
|
|
|
|
then
|
|
|
|
|
cp /etc/pacman.conf /etc/pacman.conf.bkp
|
|
|
|
|
fi
|
|
|
|
|
sed -e "/Color/c Color" \
|
|
|
|
|
-e "/ParallelDownloads/c ParallelDownloads = 10" \
|
|
|
|
|
-e "/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090" \
|
|
|
|
|
/etc/pacman.conf.bkp >/etc/pacman.conf
|
|
|
|
|
|
|
|
|
|
# Internet connection check
|
|
|
|
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
|
|
|
|
then
|
|
|
|
|
timedatectl set-ntp true
|
2025-12-08 05:11:32 +00:00
|
|
|
curl --fail --silent https://git.myvelabs.com/lab/mirrors/raw/branch/master/mirrorlist -o /etc/pacman.d/mirrorlist || die "Unable to fetch latest mirrorlist"
|
2025-11-22 23:15:27 +00:00
|
|
|
else
|
|
|
|
|
die 'No internet connectivity detected, try again'
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
|
|
cat <<- title
|
|
|
|
|
$(tput setaf 7 smul dim)## rev ${revision}${reset}
|
|
|
|
|
${blue}${bold}
|
|
|
|
|
Arch VM
|
|
|
|
|
${reset}
|
|
|
|
|
title
|
|
|
|
|
|
|
|
|
|
# Default systemd services
|
|
|
|
|
systemd_services=(systemd-networkd.service systemd-resolved.service sshd.service iptables.service wireguard-startup.service)
|
|
|
|
|
|
|
|
|
|
# Firmware
|
|
|
|
|
if ls -l /dev/disk/* | grep -q VBOX
|
|
|
|
|
then
|
|
|
|
|
linux_firmware+=(virtualbox-guest-utils)
|
|
|
|
|
systemd_services+=(vboxservice.service)
|
|
|
|
|
installation_disk=sda
|
|
|
|
|
else
|
|
|
|
|
linux_firmware+=(qemu-guest-agent spice-vdagent)
|
|
|
|
|
systemd_services+=(qemu-guest-agent.service)
|
|
|
|
|
if ls -l /dev/disk/* | grep -q virtio
|
|
|
|
|
then
|
|
|
|
|
installation_disk=vda
|
|
|
|
|
elif ls -l /dev/disk/* | grep -q QEMU
|
|
|
|
|
then
|
|
|
|
|
installation_disk=sda
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
if lspci | grep VGA | grep -q QXL
|
|
|
|
|
then
|
|
|
|
|
linux_firmware+=(xf86-video-qxl)
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Generate username and hostname
|
|
|
|
|
hostname=$(cat /dev/urandom | tr -d -c 'a-zA-Z' | fold -w 6 | head -n 1)
|
|
|
|
|
|
|
|
|
|
# Unmount if mounted
|
|
|
|
|
for mount in /mnt/boot /mnt
|
|
|
|
|
do
|
|
|
|
|
until ! mount | grep -q ${mount}
|
|
|
|
|
do
|
|
|
|
|
umount ${mount}
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
say "Partitioning /dev/${installation_disk}" yellow bold
|
|
|
|
|
wipefs -f -a /dev/${installation_disk}
|
|
|
|
|
echo
|
|
|
|
|
if [ -d /sys/firmware/efi/efivars/ ]
|
|
|
|
|
then
|
|
|
|
|
parted --script --align=optimal /dev/${installation_disk} \
|
|
|
|
|
mklabel gpt \
|
|
|
|
|
mkpart boot 1MiB 100MiB \
|
|
|
|
|
mkpart zroot 100MiB 100% \
|
|
|
|
|
set 1 esp on
|
|
|
|
|
partprobe /dev/${installation_disk}
|
|
|
|
|
else
|
|
|
|
|
bios=syslinux
|
|
|
|
|
parted --script --align=optimal /dev/${installation_disk} \
|
|
|
|
|
mklabel msdos \
|
|
|
|
|
mkpart primary 1MiB 100MiB \
|
|
|
|
|
mkpart primary 100MiB 100% \
|
|
|
|
|
set 1 boot on
|
|
|
|
|
partprobe /dev/${installation_disk}
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Assign partitions
|
|
|
|
|
export {efivol,bootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}.*1$")
|
|
|
|
|
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}.*2$")
|
|
|
|
|
|
|
|
|
|
say "Configuring volumes" yellow bold
|
|
|
|
|
yes | mkfs.ext4 ${rootvol}
|
|
|
|
|
mount -o noatime ${rootvol} /mnt
|
|
|
|
|
|
|
|
|
|
# Boot partition
|
|
|
|
|
yes | mkfs.fat -F 32 ${efivol}
|
|
|
|
|
mount --mkdir -o uid=0,gid=0,fmask=0077,dmask=0077 ${bootvol} /mnt/boot
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
# Temporarily disable mkinitcpio
|
|
|
|
|
ln -s -f /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
|
|
|
|
|
|
|
|
|
|
# Install Arch on new root
|
|
|
|
|
say "Installing Arch Linux on /dev/${installation_disk}" yellow bold
|
|
|
|
|
archpkgs="sudo-rs fakeroot \
|
|
|
|
|
${linux_firmware[@]} ${bios} \
|
|
|
|
|
reflector openssh vim \
|
|
|
|
|
git rsync pacman-contrib bash-completion ffmpegthumbs \
|
|
|
|
|
xorg xorg-xinit \
|
|
|
|
|
i3-wm i3status dmenu konsole kate dolphin kompare breeze-icons kde-cli-tools ttf-dejavu \
|
|
|
|
|
firefox firefox-decentraleyes firefox-ublock-origin \
|
|
|
|
|
chromium \
|
|
|
|
|
wireguard-tools systemd-resolvconf \
|
|
|
|
|
noto-fonts-cjk \
|
|
|
|
|
iptables-nft pipewire-jack \
|
|
|
|
|
openbsd-netcat debugedit"
|
|
|
|
|
|
|
|
|
|
# Pacstrap
|
|
|
|
|
repeat pacstrap -K /mnt --ask 4 \
|
|
|
|
|
linux base mkinitcpio \
|
|
|
|
|
${archpkgs}
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
# Generate fs table
|
|
|
|
|
genfstab -U -p /mnt >>/mnt/etc/fstab
|
|
|
|
|
|
|
|
|
|
# Make custom directories
|
|
|
|
|
mkdir -p /mnt/etc/{pacman.d/hooks,makepkg.conf.d,systemd/journald.conf.d}/ \
|
|
|
|
|
/mnt/opt/local/{bin,hooks}/
|
|
|
|
|
|
|
|
|
|
# makepkg
|
|
|
|
|
cat >/mnt/etc/makepkg.conf.d/zz-makepkg.conf <<- makepkg
|
|
|
|
|
PKGEXT=".pkg.tar"
|
|
|
|
|
MAKEFLAGS="--jobs=$(nproc)"
|
|
|
|
|
COMPRESSZST=(zstd -c -T0 --auto-threads=logical -)
|
|
|
|
|
makepkg
|
|
|
|
|
|
|
|
|
|
# pacman.conf hook
|
|
|
|
|
install /dev/stdin /mnt/opt/local/hooks/pacman.conf <<'hook'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
if [ -f /etc/pacman.conf.pacnew ]
|
|
|
|
|
then
|
|
|
|
|
sed -e '/ParallelDownloads/c ParallelDownloads = 10' \
|
|
|
|
|
-e '/Color/c Color' \
|
|
|
|
|
-e '/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090' \
|
|
|
|
|
/etc/pacman.conf.pacnew >/etc/pacman.conf
|
|
|
|
|
rm /etc/pacman.conf.pacnew
|
|
|
|
|
fi
|
|
|
|
|
hook
|
|
|
|
|
cat >/mnt/etc/pacman.d/hooks/100-pacman.hook <<- pacman
|
|
|
|
|
[Trigger]
|
|
|
|
|
Operation = Install
|
|
|
|
|
Operation = Upgrade
|
|
|
|
|
Type = Package
|
|
|
|
|
Target = pacman
|
|
|
|
|
|
|
|
|
|
[Action]
|
|
|
|
|
Description = Fixing pacman.conf
|
|
|
|
|
When = PostTransaction
|
|
|
|
|
Exec = /opt/local/hooks/pacman.conf
|
|
|
|
|
pacman
|
|
|
|
|
|
|
|
|
|
# Configure pacman cache server
|
|
|
|
|
sed -e '/ParallelDownloads/c ParallelDownloads = 10' \
|
|
|
|
|
-e '/Color/c Color' \
|
|
|
|
|
-e '/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090' \
|
|
|
|
|
-i /mnt/etc/pacman.conf
|
|
|
|
|
|
|
|
|
|
# Mkinitcpio decompress
|
|
|
|
|
echo 'MODULES_DECOMPRESS="yes"' >/mnt/etc/mkinitcpio.conf.d/zz-modules.conf
|
|
|
|
|
|
|
|
|
|
# Manually configure mkinitcpio
|
|
|
|
|
sed -e "s|%PKGBASE%|linux|g" \
|
|
|
|
|
-e "s/^fallback/#&/g" \
|
|
|
|
|
-e "s/ 'fallback'//" \
|
|
|
|
|
/mnt/usr/share/mkinitcpio/hook.preset >/mnt/etc/mkinitcpio.d/linux.preset
|
|
|
|
|
rsync -a /mnt/usr/lib/modules/*/vmlinuz /mnt/boot/vmlinuz-linux
|
|
|
|
|
|
|
|
|
|
# Networking
|
|
|
|
|
ln -s -f /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
|
|
|
|
|
rsync -a /etc/systemd/network/20-ethernet.network /mnt/etc/systemd/network/
|
|
|
|
|
|
|
|
|
|
if [ -d /sys/firmware/efi/efivars/ ]
|
|
|
|
|
then
|
|
|
|
|
# Systemd-boot
|
|
|
|
|
say "Configuring systemd-boot" yellow bold
|
|
|
|
|
arch-chroot -S /mnt bootctl --path=/boot/ install
|
|
|
|
|
cat >/mnt/boot/loader/entries/arch.conf <<- systemd-boot
|
|
|
|
|
title Arch Linux
|
|
|
|
|
linux /vmlinuz-linux
|
|
|
|
|
initrd /initramfs-linux.img
|
|
|
|
|
options root=${rootpart} rw quiet
|
|
|
|
|
systemd-boot
|
|
|
|
|
cat >/mnt/boot/loader/loader.conf <<- entry
|
|
|
|
|
default arch
|
|
|
|
|
timeout 0
|
|
|
|
|
console-mode max
|
|
|
|
|
editor no
|
|
|
|
|
entry
|
|
|
|
|
systemd_services+=(systemd-boot-update.service)
|
|
|
|
|
else
|
|
|
|
|
# Syslinux
|
|
|
|
|
say "Configuring syslinux" yellow bold
|
|
|
|
|
mkdir /mnt/boot/syslinux/
|
|
|
|
|
arch-chroot /mnt extlinux --install /boot/syslinux/
|
|
|
|
|
arch-chroot /mnt syslinux-install_update -i -a -m
|
|
|
|
|
cat >/mnt/boot/syslinux/syslinux.cfg <<-syslinux
|
|
|
|
|
DEFAULT arch
|
|
|
|
|
PROMPT 0
|
|
|
|
|
TIMEOUT 0
|
|
|
|
|
|
|
|
|
|
MENU TITLE Arch Linux
|
|
|
|
|
MENU COLOR border 30;44 #40ffffff #a0000000 std
|
|
|
|
|
MENU COLOR title 1;36;44 #9033ccff #a0000000 std
|
|
|
|
|
MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all
|
|
|
|
|
MENU COLOR unsel 37;44 #50ffffff #a0000000 std
|
|
|
|
|
MENU COLOR help 37;40 #c0ffffff #a0000000 std
|
|
|
|
|
MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std
|
|
|
|
|
MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std
|
|
|
|
|
MENU COLOR msg07 37;40 #90ffffff #a0000000 std
|
|
|
|
|
MENU COLOR tabmsg 31;40 #30ffffff #00000000 std
|
|
|
|
|
|
|
|
|
|
LABEL arch
|
|
|
|
|
MENU LABEL Arch Linux
|
|
|
|
|
LINUX ../vmlinuz-linux
|
|
|
|
|
APPEND root=${rootpart} rw quiet
|
|
|
|
|
INITRD ../initramfs-linux.img
|
|
|
|
|
LABEL hdt
|
|
|
|
|
MENU LABEL HDT (Hardware Detection Tool)
|
|
|
|
|
COM32 hdt.c32
|
|
|
|
|
LABEL reboot
|
|
|
|
|
MENU LABEL Reboot
|
|
|
|
|
COM32 reboot.c32
|
|
|
|
|
LABEL poweroff
|
|
|
|
|
MENU LABEL Poweroff
|
|
|
|
|
COM32 poweroff.c32
|
|
|
|
|
syslinux
|
|
|
|
|
fi
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
arch-chroot /mnt /usr/bin/bash <<- "CHROOT"
|
|
|
|
|
# Root bashrc
|
|
|
|
|
cat >> /etc/skel/.bashrc <<- 'bashrc'
|
|
|
|
|
|
|
|
|
|
# Add local functions folder to path
|
|
|
|
|
export PATH=${PATH}:/opt/local/bin
|
|
|
|
|
|
|
|
|
|
# Source bash functions
|
|
|
|
|
if [ -d ~/.local/functions ]
|
|
|
|
|
then
|
|
|
|
|
for file in $(find ~/.local/functions -type f)
|
|
|
|
|
do
|
|
|
|
|
. ${file}
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Disable history
|
|
|
|
|
unset HISTFILE
|
|
|
|
|
rm -f ${HISTFILE}
|
|
|
|
|
history -c -w
|
|
|
|
|
|
|
|
|
|
# Rsync
|
|
|
|
|
alias rsync='rsync --progress --info=progress2 -v -h'
|
|
|
|
|
bashrc
|
|
|
|
|
cp /etc/skel/.bashrc ~/
|
|
|
|
|
|
|
|
|
|
# Locale
|
|
|
|
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen
|
|
|
|
|
locale-gen >/dev/null
|
|
|
|
|
echo 'LANG=en_US.UTF-8' >>/etc/locale.conf
|
|
|
|
|
say 'Locale configured' yellow bold
|
|
|
|
|
|
|
|
|
|
# Time zone
|
|
|
|
|
ln -s -f $(find /usr/share/zoneinfo/ | shuf -n 1) /etc/localtime
|
|
|
|
|
hwclock --systohc --utc
|
|
|
|
|
say 'Time zone configured' yellow bold
|
|
|
|
|
|
|
|
|
|
# Hostname
|
|
|
|
|
echo ${hostname} >/etc/hostname
|
|
|
|
|
cat >>/etc/hosts <<- HOSTS
|
|
|
|
|
127.0.0.1 localhost
|
|
|
|
|
127.0.1.1 ${hostname}
|
|
|
|
|
HOSTS
|
|
|
|
|
say 'Hostname configured' yellow bold
|
|
|
|
|
|
|
|
|
|
# User and superuser
|
|
|
|
|
useradd -m -g users -G wheel -s /usr/bin/bash user || die 'User account creation has failed'
|
|
|
|
|
# echo -e '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' >/etc/sudoers.d/zz-NOPASSWD
|
|
|
|
|
# install -m 0440 /dev/stdin /etc/doas.conf <<- doas
|
|
|
|
|
# permit nopass :root
|
|
|
|
|
# permit nopass :wheel
|
|
|
|
|
# doas
|
|
|
|
|
# install /dev/stdin /usr/local/bin/sudo <<- 'doas'
|
|
|
|
|
# #!/usr/bin/env bash
|
|
|
|
|
# exec doas "${@/--preserve-env*/}"
|
|
|
|
|
# doas
|
|
|
|
|
cat >/etc/pam.d/sudo <<- 'sudo'
|
|
|
|
|
#%PAM-1.0
|
|
|
|
|
auth include system-auth
|
|
|
|
|
account include system-auth
|
|
|
|
|
session include system-auth
|
|
|
|
|
sudo
|
|
|
|
|
ln -s -f /etc/pam.d/sudo /etc/pam.d/sudo-i
|
|
|
|
|
install -m 0440 /dev/stdin /etc/sudoers-rs <<- 'DEFAULTS'
|
|
|
|
|
Defaults!/usr/bin/visudo env_keep += "SUDO_EDITOR EDITOR VISUAL"
|
|
|
|
|
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/bin"
|
|
|
|
|
root ALL=(ALL:ALL) ALL
|
|
|
|
|
%wheel ALL=(ALL:ALL) NOPASSWD: ALL
|
|
|
|
|
DEFAULTS
|
|
|
|
|
ln -s -f /usr/bin/sudo-rs /usr/local/bin/sudo
|
|
|
|
|
|
|
|
|
|
# Disable root account
|
|
|
|
|
passwd -dl root >/dev/null 2>&1
|
|
|
|
|
|
|
|
|
|
mkdir -p /etc/systemd/system/getty@tty1.service.d/
|
|
|
|
|
cat >/etc/systemd/system/getty@tty1.service.d/override.conf <<- 'autologin'
|
|
|
|
|
[Service]
|
|
|
|
|
ExecStart=
|
|
|
|
|
ExecStart=-/usr/bin/agetty --autologin user --noclear %I $TERM
|
|
|
|
|
autologin
|
|
|
|
|
say "Configured root user" yellow bold
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
say "Regenerating cpio image" yellow bold
|
|
|
|
|
mkinitcpio -P
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
# Paccache hook
|
|
|
|
|
cat >/etc/pacman.d/hooks/zz-paccache.hook <<paccache
|
|
|
|
|
[Trigger]
|
|
|
|
|
Operation = Upgrade
|
|
|
|
|
Operation = Install
|
|
|
|
|
Operation = Remove
|
|
|
|
|
Type = Package
|
|
|
|
|
Target = *
|
|
|
|
|
|
|
|
|
|
[Action]
|
|
|
|
|
Description = Cleaning pacman cache...
|
|
|
|
|
When = PostTransaction
|
|
|
|
|
Exec = /usr/bin/paccache --remove
|
|
|
|
|
paccache
|
|
|
|
|
|
|
|
|
|
# Sysctl custom settings
|
|
|
|
|
cat >/etc/sysctl.d/10-sysctl.conf <<- SYSCTL
|
|
|
|
|
net.core.netdev_max_backlog = 16384
|
|
|
|
|
net.core.somaxconn = 8192
|
|
|
|
|
net.core.rmem_default = 1048576
|
|
|
|
|
net.core.rmem_max = 16777216
|
|
|
|
|
net.core.wmem_default = 1048576
|
|
|
|
|
net.core.wmem_max = 16777216
|
|
|
|
|
net.core.optmem_max = 65536
|
|
|
|
|
net.ipv4.tcp_rmem = 4096 1048576 2097152
|
|
|
|
|
net.ipv4.tcp_wmem = 4096 65536 16777216
|
|
|
|
|
net.ipv4.udp_rmem_min = 8192
|
|
|
|
|
net.ipv4.udp_wmem_min = 8192
|
|
|
|
|
net.ipv4.tcp_fastopen = 3
|
|
|
|
|
net.ipv4.tcp_timestamps = 0
|
|
|
|
|
net.core.default_qdisc = cake
|
|
|
|
|
net.ipv4.tcp_congestion_control = bbr
|
|
|
|
|
vm.swappiness=10
|
|
|
|
|
vm.vfs_cache_pressure=50
|
|
|
|
|
SYSCTL
|
|
|
|
|
|
|
|
|
|
# iptables
|
|
|
|
|
cat >/etc/iptables/userinput.rules <<- IPTABLES
|
|
|
|
|
|
|
|
|
|
## User input
|
|
|
|
|
# Accept all connections from hypervisor subnet
|
|
|
|
|
-A INPUT -s 192.168.122.0/24 -j ACCEPT
|
|
|
|
|
|
|
|
|
|
## Simple Firewall
|
|
|
|
|
IPTABLES
|
|
|
|
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules
|
|
|
|
|
|
|
|
|
|
# iptables hook
|
|
|
|
|
install /dev/stdin /opt/local/hooks/iptables <<hook
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
if [ -f /etc/iptables/iptables.rules.pacsave ]
|
|
|
|
|
then
|
|
|
|
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules.pacsave
|
|
|
|
|
mv /etc/iptables/iptables.rules.pacsave /etc/iptables/iptables.rules
|
|
|
|
|
fi
|
|
|
|
|
hook
|
|
|
|
|
cat >/etc/pacman.d/hooks/100-iptables.hook <<iptables
|
|
|
|
|
[Trigger]
|
|
|
|
|
Operation = Install
|
|
|
|
|
Operation = Upgrade
|
|
|
|
|
Type = Package
|
|
|
|
|
Target = iptables-nft
|
|
|
|
|
|
|
|
|
|
[Action]
|
|
|
|
|
Description = Fixing iptables rules
|
|
|
|
|
When = PostTransaction
|
|
|
|
|
Exec = /opt/local/hooks/iptables
|
|
|
|
|
iptables
|
|
|
|
|
|
|
|
|
|
# locale.gen.pacnew hook
|
|
|
|
|
install /dev/stdin /opt/local/hooks/localegen <<hook
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
if [ -f /etc/locale.gen.pacnew ]
|
|
|
|
|
then
|
|
|
|
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen.pacnew
|
|
|
|
|
mv /etc/locale.gen.pacnew /etc/locale.gen
|
|
|
|
|
locale-gen >/dev/null
|
|
|
|
|
fi
|
|
|
|
|
hook
|
|
|
|
|
# locale.gen.pacnew hook
|
|
|
|
|
cat >/etc/pacman.d/hooks/100-localegen.hook <<localegen
|
|
|
|
|
[Trigger]
|
|
|
|
|
Operation = Install
|
|
|
|
|
Operation = Upgrade
|
|
|
|
|
Type = Package
|
|
|
|
|
Target = glibc
|
|
|
|
|
|
|
|
|
|
[Action]
|
|
|
|
|
Description = Fixing locale.gen
|
|
|
|
|
When = PostTransaction
|
|
|
|
|
Exec = /opt/local/hooks/localegen
|
|
|
|
|
localegen
|
|
|
|
|
|
|
|
|
|
# mkinitcpio conf hook
|
|
|
|
|
cat >/etc/pacman.d/hooks/85-mkinitcpio.conf.hook <<preset
|
|
|
|
|
[Trigger]
|
|
|
|
|
Operation = Install
|
|
|
|
|
Operation = Upgrade
|
|
|
|
|
Type = Package
|
|
|
|
|
Target = mkinitcpio
|
|
|
|
|
|
|
|
|
|
[Action]
|
|
|
|
|
Description = Updating mkinitcpio.conf
|
|
|
|
|
When = PostTransaction
|
|
|
|
|
Exec = /opt/local/hooks/mkinitcpio
|
|
|
|
|
preset
|
|
|
|
|
install /dev/stdin /opt/local/hooks/mkinitcpio <<'hook'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Linux preset
|
|
|
|
|
sed -e "s|%PKGBASE%|linux|g" \
|
|
|
|
|
-e "s/^fallback/#&/g" \
|
|
|
|
|
-e "s/ 'fallback'//" \
|
|
|
|
|
/usr/share/mkinitcpio/hook.preset >/etc/mkinitcpio.d/linux.preset
|
|
|
|
|
hook
|
|
|
|
|
|
|
|
|
|
# Wireguard
|
|
|
|
|
install /dev/stdin /usr/local/bin/wireguard-startup <<- 'wireguard'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
wireguard=$(ls /etc/wireguard | shuf -n 1 | sed 's/.conf//')
|
|
|
|
|
/usr/bin/wg-quick up ${wireguard}
|
|
|
|
|
/usr/bin/wg-quick down ${wireguard}
|
|
|
|
|
/usr/bin/wg-quick up ${wireguard}
|
|
|
|
|
wireguard
|
|
|
|
|
cat >/etc/systemd/system/wireguard-startup.service <<- 'wireguard'
|
|
|
|
|
[Unit]
|
|
|
|
|
Description=Start wireguard on boot
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
ExecStart=/usr/local/bin/wireguard-startup
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
wireguard
|
|
|
|
|
|
|
|
|
|
# SSH
|
|
|
|
|
cat >/etc/ssh/sshd_config.d/zz-sshd.conf <<sshd
|
|
|
|
|
PermitRootLogin no
|
|
|
|
|
PasswordAuthentication no
|
|
|
|
|
AuthenticationMethods publickey
|
|
|
|
|
sshd
|
|
|
|
|
|
|
|
|
|
cat >/etc/ssh/ssh_config.d/zz-ssh.conf <<sshconfig
|
|
|
|
|
# Preferred ciphers
|
|
|
|
|
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
|
|
|
|
|
|
|
|
|
|
# Only use ipv4
|
|
|
|
|
AddressFamily inet
|
|
|
|
|
sshconfig
|
|
|
|
|
|
|
|
|
|
# Polkit
|
|
|
|
|
mkdir -p /etc/polkit-1/rules.d/
|
|
|
|
|
cat >/etc/polkit-1/rules.d/49-nopasswd_global.rules <<'polkit'
|
|
|
|
|
/* Allow members of the wheel group to execute any actions
|
|
|
|
|
* without password authentication, similar to "sudo NOPASSWD:"
|
|
|
|
|
*/
|
|
|
|
|
polkit.addRule(function(action, subject) {
|
|
|
|
|
if (subject.isInGroup("wheel")) {
|
|
|
|
|
return polkit.Result.YES;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
polkit
|
|
|
|
|
|
|
|
|
|
# Persistent journal logging
|
|
|
|
|
cat >/etc/systemd/journald.conf.d/zz-journald.conf <<- eof
|
|
|
|
|
[Journal]
|
|
|
|
|
Storage=persistent
|
|
|
|
|
SystemMaxUse=100M
|
|
|
|
|
eof
|
|
|
|
|
|
|
|
|
|
# Default environment vars
|
|
|
|
|
tee -a /etc/environment >/dev/null <<- environment
|
|
|
|
|
EDITOR=vim
|
|
|
|
|
SUDO_EDITOR=vim
|
|
|
|
|
environment
|
|
|
|
|
|
|
|
|
|
su user <<- "CHANGEUSER"
|
|
|
|
|
# ssh identity
|
|
|
|
|
ssh-keygen -q \
|
|
|
|
|
-t ed25519 \
|
|
|
|
|
-f ~/.ssh/id_ed25519 \
|
|
|
|
|
-C "user@${hostname}" \
|
|
|
|
|
-P ""
|
|
|
|
|
|
|
|
|
|
# Config dirs
|
|
|
|
|
mkdir -p ~/.local/functions/ \
|
|
|
|
|
~/.config/{i3,menus}/ \
|
|
|
|
|
~/.local/share/konsole/
|
|
|
|
|
|
|
|
|
|
# i3-config
|
|
|
|
|
curl --fail --silent https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
|
|
|
|
cat >> ~/.config/i3/config <<- 'i3'
|
|
|
|
|
|
|
|
|
|
exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080
|
|
|
|
|
exec xrandr --dpi 192
|
|
|
|
|
|
|
|
|
|
exec spice-vdagent
|
|
|
|
|
exec VBoxClient-all
|
|
|
|
|
i3
|
|
|
|
|
|
|
|
|
|
# Konsole
|
|
|
|
|
cat > ~/.config/konsolerc <<- konsole
|
|
|
|
|
[Desktop Entry]
|
|
|
|
|
DefaultProfile=profile.profile
|
|
|
|
|
|
|
|
|
|
[General]
|
|
|
|
|
ConfigVersion=1
|
|
|
|
|
|
|
|
|
|
[UiSettings]
|
|
|
|
|
ColorScheme=
|
|
|
|
|
konsole
|
|
|
|
|
cat >~/.local/share/konsole/profile.profile <<- 'profile'
|
|
|
|
|
[Appearance]
|
|
|
|
|
Font=monospace,16,-1,2,400,0,0,0,0,0,0,0,0,0,0,1
|
|
|
|
|
|
|
|
|
|
[General]
|
|
|
|
|
Name=profile
|
|
|
|
|
Parent=FALLBACK/
|
|
|
|
|
|
|
|
|
|
[Scrolling]
|
|
|
|
|
HistoryMode=2
|
|
|
|
|
profile
|
|
|
|
|
|
|
|
|
|
# Dolphin
|
|
|
|
|
curl --fail --silent https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
|
|
|
|
kbuildsycoca6 >/dev/null 2>&1
|
|
|
|
|
|
|
|
|
|
# Autostart i3
|
|
|
|
|
cat >> ~/.bash_profile <<- 'autostart'
|
|
|
|
|
|
|
|
|
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
|
|
|
|
then
|
|
|
|
|
exec startx /usr/bin/i3
|
|
|
|
|
fi
|
|
|
|
|
autostart
|
|
|
|
|
|
|
|
|
|
cat > ~/.local/functions/i3 <<- 'i3'
|
|
|
|
|
# Edit i3 config
|
|
|
|
|
function i3-config
|
|
|
|
|
{
|
|
|
|
|
vim ~/.config/i3/config
|
|
|
|
|
}
|
|
|
|
|
i3
|
|
|
|
|
|
|
|
|
|
cat > ~/.local/functions/alias <<- 'alias'
|
|
|
|
|
#
|
|
|
|
|
# ~/.bash_aliases
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# ls
|
|
|
|
|
alias ll='ls -l -a -h'
|
|
|
|
|
|
|
|
|
|
# Grep color
|
|
|
|
|
alias grep='grep --color=auto'
|
|
|
|
|
alias egrep='egrep --color=auto'
|
|
|
|
|
alias fgrep='fgrep --color=auto'
|
|
|
|
|
|
|
|
|
|
# Ignore duplicate and whitespace history entries
|
|
|
|
|
export HISTCONTROL=ignoreboth
|
|
|
|
|
|
|
|
|
|
# Reboot and poweroff
|
|
|
|
|
alias poweroff='sudo poweroff'
|
|
|
|
|
alias reboot='sudo reboot'
|
|
|
|
|
|
|
|
|
|
# Miscellanous pacman
|
|
|
|
|
alias orphans='sudo pacman -Rcns $(pacman -Qtdq)'
|
|
|
|
|
alias unlockpacmandb='sudo rm /var/lib/pacman/db.lck && sudo pacman -Syy'
|
|
|
|
|
alias
|
|
|
|
|
|
|
|
|
|
cat > ~/.local/functions/functions <<- 'functions'
|
|
|
|
|
#
|
|
|
|
|
# ~/.bash_functions
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# Pacman tools
|
|
|
|
|
function installer
|
|
|
|
|
{
|
|
|
|
|
sudo pacman -S ${@}
|
|
|
|
|
echo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function uninstall
|
|
|
|
|
{
|
|
|
|
|
sudo pacman -Rcns "$@"
|
|
|
|
|
echo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function syur
|
|
|
|
|
{
|
|
|
|
|
/opt/local/bin/syu &&
|
|
|
|
|
reboot
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function syup
|
|
|
|
|
{
|
|
|
|
|
/opt/local/bin/syu &&
|
|
|
|
|
poweroff
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Update configs
|
|
|
|
|
function update-bash
|
|
|
|
|
{
|
|
|
|
|
vim ~/.bashrc &&
|
|
|
|
|
source ~/.bashrc
|
|
|
|
|
}
|
|
|
|
|
functions
|
|
|
|
|
|
|
|
|
|
cat > ~/.local/functions/wireguard <<- 'wg'
|
|
|
|
|
# Wireguard
|
|
|
|
|
function wglist
|
|
|
|
|
{
|
|
|
|
|
if [ ${1} ]
|
|
|
|
|
then
|
|
|
|
|
sudo ls /etc/wireguard | grep ${1}
|
|
|
|
|
else
|
|
|
|
|
sudo ls /etc/wireguard
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function wgupdate
|
|
|
|
|
{
|
|
|
|
|
if ls | grep -q ".*\.conf"
|
|
|
|
|
then
|
|
|
|
|
sudo find /etc/wireguard -type f -delete
|
|
|
|
|
sudo cp -v * /etc/wireguard
|
|
|
|
|
echo -e '\n\t\e[1;32mWireguard profiles updated\e[0m\n'
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function wd
|
|
|
|
|
{
|
|
|
|
|
for wireguard in $(sudo wg show | grep interface | awk '{print $2}')
|
|
|
|
|
do
|
|
|
|
|
sudo wg-quick down ${wireguard}
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function wu
|
|
|
|
|
{
|
|
|
|
|
wd
|
|
|
|
|
if [ ${1} ]
|
|
|
|
|
then
|
|
|
|
|
sudo wg-quick up $(sudo ls /etc/wireguard | grep ${1} | shuf -n 1 | sed -e 's/.conf//')
|
|
|
|
|
else
|
|
|
|
|
sudo wg-quick up $(sudo ls /etc/wireguard | shuf -n 1 | sed -e 's/.conf//')
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
wg
|
|
|
|
|
CHANGEUSER
|
|
|
|
|
CHROOT
|
|
|
|
|
|
|
|
|
|
# System services
|
|
|
|
|
arch-chroot /mnt systemctl enable ${systemd_services[@]} || die "Unable to start systemd services"
|
|
|
|
|
|
|
|
|
|
# SSH Authentication
|
|
|
|
|
if [ -f sshkeys ]
|
|
|
|
|
then
|
|
|
|
|
cat sshkeys >/mnt/home/user/.ssh/authorized_keys
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Custom pacman wrapper
|
|
|
|
|
install /dev/stdin /mnt/opt/local/bin/syu <<- 'syu'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
# Fetch latest mirrors
|
|
|
|
|
sudo reflector --age 24 --latest 10 --protocol https --save /etc/pacman.d/mirrorlist
|
|
|
|
|
|
|
|
|
|
# Check for new packages and continue if found
|
|
|
|
|
newpkg=($(checkupdates --nocolor | awk '{print $1}'))
|
|
|
|
|
if [ "${newpkg}" ]
|
|
|
|
|
then
|
|
|
|
|
# Sync pacman dbs
|
|
|
|
|
sudo pacman --ask 4 -Sy >/dev/null
|
|
|
|
|
|
|
|
|
|
# Update archlinux-keyring first
|
|
|
|
|
if [[ ${newpkg[@]} =~ "archlinux-keyring" ]]
|
|
|
|
|
then
|
|
|
|
|
sudo pacman --ask 4 -S archlinux-keyring
|
|
|
|
|
echo
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Perform update if dependencies are satisfied
|
|
|
|
|
if sudo pacman --ask 4 -Syu --needed
|
|
|
|
|
then
|
|
|
|
|
echo
|
|
|
|
|
sudo pacdiff
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
syu
|
|
|
|
|
|
|
|
|
|
# Script for installing desktop environment
|
|
|
|
|
install /dev/stdin /mnt/opt/local/bin/startup <<'DESKTOPINSTALL'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Internet connection check
|
|
|
|
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
|
|
|
|
then
|
|
|
|
|
sudo timedatectl set-ntp true
|
|
|
|
|
sudo vim /opt/local/bin/startupscript
|
|
|
|
|
/opt/local/bin/startupscript
|
|
|
|
|
exit 0
|
|
|
|
|
else
|
|
|
|
|
echo -e '\n\e[31mNo internet connectivity detected'
|
|
|
|
|
echo -e 'Connect to a network and try again'
|
|
|
|
|
echo -e 'Aborting installer...\e[0m\n'
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
DESKTOPINSTALL
|
|
|
|
|
install /dev/stdin /mnt/opt/local/bin/startupscript <<'DESKTOPINSTALL'
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
|
|
# AUR package list
|
|
|
|
|
aur_list=(
|
|
|
|
|
# jdownloader2
|
|
|
|
|
# instaloader
|
|
|
|
|
# czkawka-gui-bin
|
|
|
|
|
# ledger-udev ledger-live-bin
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
function enable-audio
|
|
|
|
|
{
|
|
|
|
|
sudo pacman -S --ask 4 pipewire pipewire-audio pipewire-pulse wireplumber
|
|
|
|
|
echo
|
|
|
|
|
systemctl --user --quiet enable --now wireplumber.service pipewire-pulse.service pipewire.service
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function wireguard-setup
|
|
|
|
|
{
|
|
|
|
|
if ! sudo wg show | grep -q interface
|
|
|
|
|
then
|
|
|
|
|
echo -e '\n\e[31mNo wireguard profile installed\e[0m\n'
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tor-installer
|
|
|
|
|
{
|
|
|
|
|
sudo pacman -S --ask 4 torbrowser-launcher
|
|
|
|
|
echo
|
|
|
|
|
torbrowser-launcher
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wireguard-setup
|
|
|
|
|
tor-installer
|
|
|
|
|
# enable-audio # uncomment to enable audio
|
|
|
|
|
|
|
|
|
|
# AUR packages
|
|
|
|
|
if [ ${aur_list} ]
|
|
|
|
|
then
|
|
|
|
|
for package in ${aur_list[@]}
|
|
|
|
|
do
|
|
|
|
|
cd ~/
|
|
|
|
|
git clone https://aur.archlinux.org/${package}.git
|
|
|
|
|
cd ${package}/
|
|
|
|
|
makepkg -csi
|
|
|
|
|
echo
|
|
|
|
|
cd ~
|
|
|
|
|
rm -rf ${package}/
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Add user to shared folder group if in virtualbox guest
|
|
|
|
|
if ls -l /dev/disk/* | grep -q VBOX
|
|
|
|
|
then
|
|
|
|
|
sudo gpasswd -a user vboxsf >/dev/null
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo -e '\n\e[1;32mSupplementary installer completed, reboot one last time\e[0m'
|
|
|
|
|
sudo rm -f /opt/local/bin/startup*
|
|
|
|
|
sudo systemctl reboot
|
|
|
|
|
DESKTOPINSTALL
|
|
|
|
|
|
|
|
|
|
# Reboot only if script succeeded
|
|
|
|
|
if arch-chroot /mnt uname -a | grep -q Linux
|
|
|
|
|
then
|
|
|
|
|
for mount in /mnt/boot /mnt
|
|
|
|
|
do
|
|
|
|
|
until ! mount | grep -q ${mount}
|
|
|
|
|
do
|
|
|
|
|
umount ${mount}
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
echo -e '\e[1;34mInstaller has completed and system drive has been unmounted
|
|
|
|
|
Boot into the new system, connect to a network and install a DE by running \e[35mdesktop\e[34m in the terminal
|
|
|
|
|
Rebooting...\n\e[0m'
|
|
|
|
|
reboot
|
|
|
|
|
else
|
|
|
|
|
die 'Something does not feel right'
|
|
|
|
|
fi
|