mirror of
https://git.myvelabs.com/lab/archlinux.git
synced 2025-12-17 19:46:25 +00:00
First commit
This commit is contained in:
commit
36ad41a2fc
18 changed files with 10005 additions and 0 deletions
39
README.md
Normal file
39
README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# MyveArch
|
||||
|
||||
This repo is a compilation of installation scripts written in bash that install [Arch Linux](https://archlinux.org/) on any x86_64 EFI system. From a home server ([homelab.sh](homelab.sh)) to a laptop or desktop computer ([arch.sh](arch.sh)), these scripts are highly customizable and can be tailored to very specific needs.
|
||||
|
||||
## :: Pre-installation
|
||||
Acquire an installation ISO and burn it into a USB drive:
|
||||
```
|
||||
dd bs=4M if=${/path/to/archlinux-version-x86_64.iso} of=${/dev/disk/by-id/usb-My_flash_drive} conv=fsync oflag=direct status=progress
|
||||
```
|
||||
|
||||
## :: Usage
|
||||
Download the script of choice and execute it in the terminal:
|
||||
|
||||
```
|
||||
wget https://myvelabs.com/lab/archlinux/raw/branch/master/arch.sh
|
||||
bash arch.sh
|
||||
```
|
||||
OR
|
||||
```
|
||||
curl --fail -s -L -O https://myvelabs.com/lab/archlinux/raw/branch/master/homelab.sh
|
||||
bash homelab.sh
|
||||
```
|
||||
OR
|
||||
```
|
||||
git clone https://myvelabs.com/lab/archlinux.git
|
||||
cd archlinux/
|
||||
bash arch.sh
|
||||
```
|
||||
|
||||
## :: Installation
|
||||
The following flags are available:
|
||||
```
|
||||
-s, --ssh-key Authorized SSH public key (one entry per flag, enclosed in quotes)
|
||||
-c, --cache Pacman cache server address
|
||||
-k, --kernel Linux kernel (eg, linux, linux-lts, linux-hardened, linux-zen)
|
||||
-f, --filesystem Choice of filesystem (eg, ext4, btrfs, zfs)
|
||||
-o, --option Arch installation setup, if known
|
||||
```
|
||||
Fill out the prompts and you'll have a full-fledged Arch Linux system up and running in no time.
|
||||
728
functions/chroot
Executable file
728
functions/chroot
Executable file
|
|
@ -0,0 +1,728 @@
|
|||
#!/usr/bin/env bash
|
||||
revision=0.1a
|
||||
set -a
|
||||
set -E
|
||||
echo
|
||||
|
||||
# Environment variables
|
||||
tee -a /etc/environment >/dev/null <<- environment
|
||||
EDITOR=vim
|
||||
SUDO_EDITOR=vim
|
||||
environment
|
||||
|
||||
# Global bashrc
|
||||
tee -a /etc/skel/.bashrc >/dev/null <<- 'bashglobal'
|
||||
|
||||
# Source bash functions
|
||||
if [ -d ~/.local/functions ]
|
||||
then
|
||||
for file in $(find ~/.local/functions -type f)
|
||||
do
|
||||
. ${file}
|
||||
done
|
||||
fi
|
||||
|
||||
# Add local functions folder to path
|
||||
export PATH=${PATH}:${HOME}/.local/bin:/zfs/bin:/opt/local/bin
|
||||
export SUDO_PROMPT=$'\a'"$(tput rev)[sudo] password for %p:$(tput sgr0)"' '
|
||||
|
||||
# Colored prompts
|
||||
alias diff='diff --color=auto'
|
||||
alias ip='ip -color=auto'
|
||||
export LESS='-R --use-color -Dd+r$Du+b$'
|
||||
|
||||
# Adjust terminal upon window resize
|
||||
shopt -s checkwinsize
|
||||
|
||||
# Auto cd into directory
|
||||
shopt -s autocd
|
||||
|
||||
# Enable tab complete for sudo
|
||||
complete -c -f sudo
|
||||
|
||||
# Ignore duplicate and whitespace history entries
|
||||
export HISTCONTROL=ignoreboth
|
||||
|
||||
#
|
||||
# ~/.bash_aliases
|
||||
#
|
||||
|
||||
# ZFS/btrfs
|
||||
alias zfs='sudo zfs'
|
||||
alias zpool='sudo zpool'
|
||||
alias btrfs='sudo btrfs'
|
||||
|
||||
# Shutdown reboot
|
||||
alias poweroff='sudo poweroff'
|
||||
alias reboot='sudo reboot'
|
||||
|
||||
# Text editors
|
||||
alias v='vim'
|
||||
alias sv='sudo vim'
|
||||
|
||||
# Clear bash history
|
||||
alias clearhistory='rm ${HISTFILE}; history -c -w'
|
||||
|
||||
# Miscellanous pacman
|
||||
alias orphans='sudo pacman -Rcns $(pacman -Qtdq)'
|
||||
alias unlockpacman='sudo rm /var/lib/pacman/db.lck && sudo pacman -Syyu'
|
||||
|
||||
# Rsync
|
||||
alias rsync='rsync -v -h --progress --info=progress2 --partial --append-verify'
|
||||
# --log-file=
|
||||
# --remove-source-files
|
||||
|
||||
#
|
||||
# ~/.bash_functions
|
||||
#
|
||||
|
||||
# Pacman tools
|
||||
function installer
|
||||
{
|
||||
/opt/local/bin/cacheserver
|
||||
sudo pacman -S ${@}
|
||||
echo
|
||||
}
|
||||
|
||||
function uninstall
|
||||
{
|
||||
sudo pacman -Rcns ${@}
|
||||
echo
|
||||
}
|
||||
|
||||
function mirrors
|
||||
{
|
||||
echo
|
||||
sudo reflector --country CA,US --age 24 --latest 20 --protocol https --fastest 25 --sort rate --save /etc/pacman.d/mirrorlist
|
||||
echo
|
||||
cat /etc/pacman.d/mirrorlist
|
||||
echo
|
||||
}
|
||||
|
||||
function syur
|
||||
{
|
||||
/opt/local/bin/syu &&
|
||||
reboot
|
||||
}
|
||||
|
||||
function syup
|
||||
{
|
||||
/opt/local/bin/syu &&
|
||||
poweroff
|
||||
}
|
||||
|
||||
# Update bash
|
||||
function update-bash
|
||||
{
|
||||
vim ~/.bashrc &&
|
||||
source ~/.bashrc
|
||||
}
|
||||
bashglobal
|
||||
|
||||
# Root bashrc
|
||||
rsync -a /etc/skel/.bashrc ~/
|
||||
mkdir -p ~/.local/functions/
|
||||
cat > ~/.local/functions/bashrc <<- 'bashrc'
|
||||
#!/usr/bin/env bash
|
||||
# Root shell color
|
||||
PS1="$(tput setaf 1)[\u@\h \W \$?]\$$(tput sgr0) "
|
||||
|
||||
# Colored prompts
|
||||
alias ll='ls --color=auto -l -a -h'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
|
||||
# Disable history
|
||||
unset HISTFILE
|
||||
rm -f ${HISTFILE}
|
||||
history -c -w
|
||||
bashrc
|
||||
|
||||
# Locale
|
||||
sed '/#en_US.UTF-8 UTF-8/ s/#//' -i /etc/locale.gen
|
||||
locale-gen >/dev/null
|
||||
echo 'LANG=en_US.UTF-8' >>/etc/locale.conf
|
||||
say as heading 'Locale configured'
|
||||
|
||||
# Time zone
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
ln -s -f $(find /usr/share/zoneinfo/ | shuf -n 1) /etc/localtime
|
||||
else
|
||||
ln -s -f /usr/share/zoneinfo/UTC /etc/localtime
|
||||
fi
|
||||
hwclock --systohc --utc
|
||||
say as heading 'Time zone configured'
|
||||
|
||||
# Hostname
|
||||
echo ${hostname} >/etc/hostname
|
||||
cat >>/etc/hosts <<HOSTS
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 ${hostname}
|
||||
HOSTS
|
||||
say as heading 'Hostname configured'
|
||||
|
||||
# User and superuser
|
||||
useradd -m -g users -G wheel -s /usr/bin/bash ${username} || die 'User account creation has failed'
|
||||
printf '%s\n' "${userpass}" "${userpass}" | passwd ${username} >/dev/null 2>&1
|
||||
unset userpass userpass2
|
||||
|
||||
# Disable root account
|
||||
passwd -l root >/dev/null 2>&1
|
||||
|
||||
# Sudoers
|
||||
install -m 0440 /dev/stdin /etc/sudoers.d/01-DEFAULTS <<- DEFAULTS
|
||||
Defaults passwd_timeout=0
|
||||
Defaults timestamp_type=global
|
||||
Defaults insults
|
||||
DEFAULTS
|
||||
|
||||
install -m 0440 /dev/stdin /etc/sudoers.d/02-COMMANDS <<- COMMANDS
|
||||
Cmnd_Alias POWER = /usr/bin/poweroff, /usr/bin/reboot
|
||||
Cmnd_Alias ZFS = /usr/bin/zfs, /usr/bin/zpool
|
||||
Cmnd_Alias BTRFS = /usr/bin/btrfs, /usr/bin/timeshift, /usr/bin/timeshift-gtk, /usr/bin/timeshift-launcher
|
||||
Cmnd_Alias QEMU = /usr/bin/virsh, /usr/bin/qemu-system-x86_64, /usr/bin/virt-install
|
||||
Cmnd_Alias FAIL2BAN = /usr/bin/fail2ban-client
|
||||
Cmnd_Alias ARCHISO = /opt/local/bin/mkairgap, /opt/local/bin/mkiso
|
||||
Cmnd_Alias PACMAN = /usr/bin/pacman -Sy
|
||||
Cmnd_Alias IPTABLES = /usr/bin/iptables, /usr/bin/iptables-save
|
||||
Cmnd_Alias MISC = /usr/bin/rsync
|
||||
COMMANDS
|
||||
|
||||
install -m 0440 /dev/stdin /etc/sudoers.d/03-WHEEL <<- WHEEL
|
||||
%wheel ALL=(ALL:ALL) ALL
|
||||
%wheel ALL=(ALL:ALL) NOPASSWD: POWER, ZFS, BTRFS, QEMU, FAIL2BAN, ARCHISO, PACMAN, IPTABLES, MISC
|
||||
WHEEL
|
||||
|
||||
install -m 0440 /dev/stdin /etc/sudoers.d/.zz-NOPASSWD <<- NOPASSWD
|
||||
Defaults:${username} !authenticate
|
||||
NOPASSWD
|
||||
|
||||
case ${filesystem} in
|
||||
zfs)
|
||||
# ZFS setup
|
||||
zpool set cachefile=/etc/zfs/zpool.cache zroot
|
||||
zgenhostid $(hostid)
|
||||
|
||||
# ZFS files
|
||||
touch /zfs/snapshot-syu
|
||||
chown ${username}:users /zfs/snapshot-syu
|
||||
|
||||
# Trim zroot monthly
|
||||
cat >/etc/systemd/system/zfs-trim@.timer <<- 'TRIM'
|
||||
[Unit]
|
||||
Description=Monthly zpool trim on %i
|
||||
|
||||
[Timer]
|
||||
OnCalendar=monthly
|
||||
AccuracySec=1h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
TRIM
|
||||
cat >/etc/systemd/system/zfs-trim@.service <<- 'TRIM'
|
||||
[Unit]
|
||||
Description=zpool trim on %i
|
||||
Documentation=man:zpool-trim(8)
|
||||
Requires=zfs.target
|
||||
After=zfs.target
|
||||
ConditionACPower=true
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
Nice=19
|
||||
IOSchedulingClass=idle
|
||||
KillSignal=SIGINT
|
||||
ExecStart=/bin/sh -c '\
|
||||
if /usr/bin/zpool status %i | grep "trimming"; then\
|
||||
exec /usr/bin/zpool wait -t trim %i;\
|
||||
else exec /usr/bin/zpool trim -w %i; fi'
|
||||
ExecStop=-/bin/sh -c '/usr/bin/zpool trim -s %i 2>/dev/null || true'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
TRIM
|
||||
# Scrub zroot monthly
|
||||
cat >/etc/systemd/system/zfs-scrub@.timer <<- 'SCRUB'
|
||||
[Unit]
|
||||
Description=Monthly zpool scrub on %i
|
||||
|
||||
[Timer]
|
||||
OnCalendar=monthly
|
||||
AccuracySec=1h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SCRUB
|
||||
cat >/etc/systemd/system/zfs-scrub@.service <<- 'SCRUB'
|
||||
[Unit]
|
||||
Description=zpool scrub on %i
|
||||
|
||||
[Service]
|
||||
Nice=19
|
||||
IOSchedulingClass=idle
|
||||
KillSignal=SIGINT
|
||||
ExecStart=/usr/bin/zpool scrub %i
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SCRUB
|
||||
|
||||
# Pre and Post update backup hooks
|
||||
cat >/etc/pacman.d/hooks/00-syu_pre.hook <<- pre
|
||||
[Trigger]
|
||||
Type = Path
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Description = Creating pre zroot snapshot...
|
||||
When = PreTransaction
|
||||
Exec = /usr/bin/bash -c 'zfs snapshot zroot/ROOT@pre-\$(cat /zfs/snapshot-syu)'
|
||||
AbortOnFail
|
||||
pre
|
||||
cat >/etc/pacman.d/hooks/55-bootbackup_pre.hook <<- pre
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = rsync
|
||||
Description = Backing up pre /boot...
|
||||
When = PreTransaction
|
||||
Exec = /usr/bin/bash -c 'mount /boot; rsync -a --mkpath --delete /boot/ "/.boot/\$(cat /zfs/snapshot-syu)_pre"/'
|
||||
AbortOnFail
|
||||
pre
|
||||
cat >/etc/pacman.d/hooks/95-bootbackup_post.hook <<- post
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = rsync
|
||||
Description = Backing up post /boot...
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete /boot/ "/.boot/\$(cat /zfs/snapshot-syu)_post"/'
|
||||
post
|
||||
cat >/etc/pacman.d/hooks/zz-syu_post.hook <<- post
|
||||
[Trigger]
|
||||
Type = Path
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Description = Creating post zroot snapshot...
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/bash -c 'zfs snapshot zroot/ROOT@post-\$(cat /zfs/snapshot-syu)'
|
||||
post
|
||||
|
||||
# Custom pacman wrapper
|
||||
install /dev/stdin /opt/local/bin/syu <<- syu
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
mirrorlist=
|
||||
|
||||
# Enable or disable pacman cache server
|
||||
/opt/local/bin/cacheserver
|
||||
|
||||
# Fetch latest mirrors
|
||||
sudo curl --fail --silent \${mirrorlist} -o /etc/pacman.d/mirrorlist
|
||||
|
||||
# Record current time
|
||||
echo \$(date "+%Y-%m-%d-%H:%M:%S") >/zfs/snapshot-syu
|
||||
|
||||
# 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
|
||||
|
||||
# Check zfs-linux kernel dependency
|
||||
zfslinux=\$(pacman -Si zfs-${linux_kernel} | grep "Depends On" | sed "s|.*${linux_kernel}=||")
|
||||
linux=\$(pacman -Si ${linux_kernel} | grep "Version" | awk '{print \$3}')
|
||||
if [ \${zfslinux} != \${linux} ]
|
||||
then
|
||||
archzfs="--ignore zfs-utils,zfs-${linux_kernel},${linux_kernel}"
|
||||
fi
|
||||
|
||||
# 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 \${archzfs} --needed
|
||||
then
|
||||
echo
|
||||
sudo pacdiff
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
syu
|
||||
;;
|
||||
*)
|
||||
case ${filesystem} in
|
||||
btrfs)
|
||||
# Pre and post update backup hooks
|
||||
cat >/etc/pacman.d/hooks/00-syu_pre.hook <<- pre
|
||||
[Trigger]
|
||||
Type = Path
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = timeshift
|
||||
Description = Creating pre root snapshot...
|
||||
When = PreTransaction
|
||||
Exec = /usr/bin/bash -c 'timeshift --create --comments "pre_\$(date "+%Y-%m-%d-%H:%M:%S")" >/dev/null'
|
||||
AbortOnFail
|
||||
pre
|
||||
cat >/etc/pacman.d/hooks/55-bootbackup_pre.hook <<- pre
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = rsync
|
||||
Description = Backing up pre /boot...
|
||||
When = PreTransaction
|
||||
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete --exclude 'header.img' /boot/ "/.boot/\$(date "+%Y-%m-%d-%H:%M:%S")_pre"/'
|
||||
AbortOnFail
|
||||
pre
|
||||
cat >/etc/pacman.d/hooks/95-bootbackup_post.hook <<- post
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = rsync
|
||||
Description = Backing up post /boot...
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete --exclude 'header.img' /boot/ "/.boot/\$(date "+%Y-%m-%d-%H:%M:%S")_post"/'
|
||||
post
|
||||
cat >/etc/pacman.d/hooks/zz-syu_post.hook <<- post
|
||||
[Trigger]
|
||||
Type = Path
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
Target = usr/lib/initcpio/*
|
||||
Target = usr/lib/firmware/*
|
||||
Target = usr/src/*/dkms.conf
|
||||
|
||||
[Action]
|
||||
Depends = timeshift
|
||||
Description = Creating post root snapshot...
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/bash -c 'timeshift --create --comments "post_\$(date "+%Y-%m-%d-%H:%M:%S")" >/dev/null'
|
||||
post
|
||||
|
||||
install /dev/stdin /usr/local/bin/timeshift-gui <<- 'timeshift'
|
||||
#!/bin/sh
|
||||
pkexec env WAYLAND_DISPLAY="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" XDG_RUNTIME_DIR=/run/user/0 timeshift-launcher
|
||||
timeshift
|
||||
;;
|
||||
esac
|
||||
|
||||
# Custom pacman wrapper
|
||||
install /dev/stdin /opt/local/bin/syu <<- syu
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
mirrorlist=
|
||||
|
||||
# Enable or disable pacman cache server
|
||||
/opt/local/bin/cacheserver
|
||||
|
||||
# Fetch latest mirrors
|
||||
sudo curl --fail --silent \${mirrorlist} -o /etc/pacman.d/mirrorlist
|
||||
|
||||
# Check for new packages and continue if found
|
||||
newpkg+=(\$(checkupdates --nocolor | awk '{print \$1}'))
|
||||
if [ "\${newpkg}" ]
|
||||
then
|
||||
# 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
|
||||
;;
|
||||
esac
|
||||
echo
|
||||
|
||||
# /opt/local/bin/cacheserver
|
||||
install /dev/stdin /opt/local/bin/cacheserver <<- 'cacheserver'
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Enable cacheserver if active
|
||||
cacheserver=
|
||||
port=
|
||||
scheme=
|
||||
|
||||
if [ -z ${cacheserver} ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if nc -z -4 -w 3 ${cacheserver} ${port:-80} >/dev/null 2>&1
|
||||
then
|
||||
if grep -q "CacheServer" /etc/pacman.conf
|
||||
then
|
||||
sudo sed "/CacheServer/ s/^\(#\)*//g" -i /etc/pacman.conf
|
||||
else
|
||||
sudo sed "/^\[core\]$\|^\[extra\]$\|^\[myvezfs\]$/a CacheServer = ${scheme:-http}://${cacheserver}:${port:-80}" -i /etc/pacman.conf
|
||||
fi
|
||||
else
|
||||
sudo sed "/CacheServer/ s/^/#/g" -i /etc/pacman.conf
|
||||
fi
|
||||
cacheserver
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
sed -e "/^cacheserver=/c cacheserver=192.168.122.1" \
|
||||
-e "/^port=/c port=9090" \
|
||||
-i /opt/local/bin/cacheserver
|
||||
/opt/local/bin/cacheserver
|
||||
fi
|
||||
|
||||
# mkinitcpio
|
||||
say as heading 'Regenerating cpio image'
|
||||
mkinitcpio -P
|
||||
echo
|
||||
|
||||
# Install GRUB
|
||||
if [[ ${arch} = [3567] ]]
|
||||
then
|
||||
say as heading 'Installing GRUB'
|
||||
grub-install --target=x86_64-efi --bootloader-id="Arch Linux (${hostname})" --efi-directory=/boot/efi --recheck || die 'Grub installation failed'
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
echo
|
||||
fi
|
||||
|
||||
# Sysctl custom settings
|
||||
cat >/etc/sysctl.d/99-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
|
||||
|
||||
# SSH port
|
||||
-A INPUT -p tcp -m tcp --dport ${port:-22} -j ACCEPT -m comment --comment "SSH Port"
|
||||
|
||||
## Simple Firewall
|
||||
IPTABLES
|
||||
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules
|
||||
|
||||
# zram
|
||||
echo 'zram' >/etc/modules-load.d/zram.conf
|
||||
echo 'options zram num_devices=1' >/etc/modprobe.d/zram.conf
|
||||
echo 'KERNEL=="zram0", ATTR{comp_algorithm}="lz4", ATTR{disksize}="512M" RUN="/usr/bin/mkswap /dev/zram0", TAG+="systemd"' >/etc/udev/rules.d/99-zram.rules
|
||||
echo '/dev/zram0 none swap defaults 0 0' >>/etc/fstab
|
||||
|
||||
# Configure ssh and ssh_config.d/10-global.conf
|
||||
ssh-keygen -q \
|
||||
-t ed25519 \
|
||||
-P "" \
|
||||
-C "${USER}@${hostname}" \
|
||||
-f ~/.ssh/id_ed25519
|
||||
mkdir ~/.ssh/sockets/
|
||||
cat >/etc/ssh/sshd_config.d/10-sshd.conf <<- sshd
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
AuthenticationMethods publickey
|
||||
sshd
|
||||
cat >/etc/ssh/ssh_config.d/10-global.conf <<- 'sshconfig'
|
||||
# Preferred ciphers
|
||||
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
|
||||
|
||||
# Only use ipv4
|
||||
AddressFamily inet
|
||||
|
||||
# Multiplex
|
||||
ControlMaster auto
|
||||
ControlPath ~/.ssh/sockets/%r@%h-%p
|
||||
ControlPersist 10m
|
||||
|
||||
# Ease up on local area network devices
|
||||
Host 192.168.*
|
||||
StrictHostKeyChecking no
|
||||
UserKnownHostsFile=/dev/null
|
||||
LogLevel Error
|
||||
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
|
||||
mkdir -p /etc/systemd/journald.conf.d/
|
||||
cat >/etc/systemd/journald.conf.d/zz-journald.conf <<- eof
|
||||
[Journal]
|
||||
Storage=persistent
|
||||
eof
|
||||
|
||||
# makepkg
|
||||
mkdir -p /etc/makepkg.conf.d/
|
||||
cat >/etc/makepkg.conf.d/zz-makepkg.conf <<- makepkg
|
||||
PKGEXT=".pkg.tar"
|
||||
MAKEFLAGS="--jobs=$(nproc)"
|
||||
COMPRESSZST=(zstd -c -T0 --auto-threads=logical -)
|
||||
makepkg
|
||||
|
||||
# Virtual machine settings
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
mv /etc/sudoers.d/.zz-NOPASSWD /etc/sudoers.d/zz-NOPASSWD
|
||||
fi
|
||||
|
||||
##
|
||||
## Hooks
|
||||
##
|
||||
|
||||
# paccache
|
||||
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
|
||||
|
||||
# locale.gen.pacnew hook
|
||||
install /dev/stdin /opt/local/hooks/localegen <<- hook
|
||||
#!/usr/bin/env bash
|
||||
if [ -f /etc/locale.gen.pacnew ]
|
||||
then
|
||||
sed '/#en_US.UTF-8 UTF-8/ s/#//' -i /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
|
||||
|
||||
# iptables
|
||||
cat >/etc/pacman.d/hooks/100-iptables.rules.hook <<iptables
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = iptables-nft
|
||||
|
||||
[Action]
|
||||
Description = Fixing iptables rules
|
||||
When = PostTransaction
|
||||
Exec = /opt/local/hooks/iptables.rules
|
||||
iptables
|
||||
install /dev/stdin /opt/local/hooks/iptables.rules <<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
|
||||
rm /etc/iptables/iptables.rules.pacsave
|
||||
fi
|
||||
hook
|
||||
|
||||
su ${username} <<- "user"
|
||||
curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/user -o /tmp/user
|
||||
bash /tmp/user
|
||||
user
|
||||
670
functions/desktop
Executable file
670
functions/desktop
Executable file
|
|
@ -0,0 +1,670 @@
|
|||
#!/usr/bin/env bash
|
||||
revision='0.1f (feb 24/25)'
|
||||
set -a
|
||||
set -E
|
||||
|
||||
# Exit function
|
||||
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||
function die
|
||||
{
|
||||
if [ ${@} ]
|
||||
then
|
||||
echo
|
||||
echo -e "\e[1;31mError encountered for the following reason:\e[0m
|
||||
|
||||
\e[33m${@}\e[0m
|
||||
|
||||
\e[1;31mScript aborted...\e[0m"
|
||||
echo
|
||||
else
|
||||
echo
|
||||
echo -e '\e[1;31mError encountered, script aborted...\e[0m'
|
||||
echo
|
||||
fi
|
||||
exit 77
|
||||
}
|
||||
|
||||
# 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
|
||||
else
|
||||
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||
fi
|
||||
|
||||
totalde=21
|
||||
cat <<- menu
|
||||
$(tput setaf 5 bold)
|
||||
Select a desktop$(tput sgr0)
|
||||
$(tput smul setaf 7 dim)# none$(tput sgr0)
|
||||
0) none
|
||||
$(tput smul setaf 7 dim)# wayland$(tput sgr0)
|
||||
1) sway
|
||||
2) hyprland
|
||||
3) qtile-wayland
|
||||
4) river
|
||||
5) plasma-wayland
|
||||
6) gnome-wayland
|
||||
7) cosmic
|
||||
$(tput smul setaf 7 dim)# x11$(tput sgr0)
|
||||
8) qtile-x11
|
||||
9) bspwm
|
||||
10) awesome
|
||||
11) i3
|
||||
12) i3-plasma
|
||||
13) plasma-x11
|
||||
14) gnome-x11
|
||||
15) xfce4
|
||||
16) budgie
|
||||
17) cinnamon
|
||||
18) deepin
|
||||
19) mate
|
||||
20) pantheon
|
||||
21) cutefish
|
||||
22) lxde
|
||||
23) lxqt
|
||||
menu
|
||||
if [ ${1} ]
|
||||
then
|
||||
desktop=${1}
|
||||
else
|
||||
desktop=-1
|
||||
fi
|
||||
until [[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]]
|
||||
do
|
||||
read -p '> ' desktop
|
||||
[[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]] ||\
|
||||
echo -e "\n\n\e[1;31mInvalid selection, type an option from 0 to ${totalde}\e[0m"
|
||||
done
|
||||
|
||||
# Configure btrfs
|
||||
if findmnt / | grep -w -q btrfs
|
||||
then
|
||||
desktop_packages+=(btrfs-progs)
|
||||
if pacman -Q | grep -q "^grub"
|
||||
then
|
||||
desktop_packages+=(grub-btrfs inotify-tools)
|
||||
systemd_services+=(grub-btrfsd.service)
|
||||
fi
|
||||
|
||||
# echo -e '\n\e[1;35mConfiguring snapper\e[0m'
|
||||
# sudo pacman --sync --ask 4 snapper snap-pac
|
||||
# echo
|
||||
# sudo umount /.snapshots /home/.snapshots
|
||||
# sudo rm -r /.snapshots /home/.snapshots
|
||||
# sudo snapper -c root create-config /
|
||||
# sudo snapper -c home create-config /home
|
||||
# sudo sed -i 's/TIMELINE_LIMIT_HOURLY="10"/TIMELINE_LIMIT_HOURLY="4"/' /etc/snapper/configs/root
|
||||
# sudo sed -i 's/TIMELINE_LIMIT_DAILY="10"/TIMELINE_LIMIT_DAILY="7"/' /etc/snapper/configs/root
|
||||
# sudo sed -i 's/TIMELINE_LIMIT_MONTHLY="10"/TIMELINE_LIMIT_MONTHLY="1"/' /etc/snapper/configs/root
|
||||
# sudo sed -i 's/TIMELINE_LIMIT_YEARLY="10"/TIMELINE_LIMIT_YEARLY="0"/' /etc/snapper/configs/root
|
||||
# sudo sed -i 's/TIMELINE_CREATE="yes"/TIMELINE_CREATE="no"/' /etc/snapper/configs/home
|
||||
# sudo btrfs subvolume delete /.snapshots
|
||||
# sudo btrfs subvolume delete /home/.snapshots
|
||||
# sudo mkdir -p --mode=750 /.snapshots /home/.snapshots
|
||||
# sudo mount -a
|
||||
# sudo systemctl --quiet enable --now snapper-cleanup.timer snapper-timeline.timer
|
||||
|
||||
# # Create snapshots for fresh installation
|
||||
# sudo snapper -c root create --description "fresh install"
|
||||
# sudo snapper -c home create --description "fresh install"
|
||||
fi
|
||||
|
||||
# Assign DE variables
|
||||
case ${desktop} in
|
||||
0)
|
||||
# TTY only
|
||||
desktop_choice=none
|
||||
echo
|
||||
;;
|
||||
*)
|
||||
systemd_user_services+=(wireplumber.service pipewire-pulse.service pipewire.service)
|
||||
desktop_packages+=(ttf-dejavu pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber)
|
||||
case ${desktop} in
|
||||
[1-7])
|
||||
# Wayland
|
||||
desktop_packages+=(wayland)
|
||||
case ${desktop} in
|
||||
1)
|
||||
desktop_choice=sway
|
||||
desktop_packages+=(sway seatd swaylock swayidle swaybg bemenu bemenu-wayland i3status foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent)
|
||||
systemd_services+=(seatd.service)
|
||||
;;
|
||||
2)
|
||||
desktop_choice=hyprland
|
||||
desktop_packages+=(hyprland uwsm swaylock swayidle bemenu bemenu-wayland waybar foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools ttf-font-awesome brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent)
|
||||
systemd_user_services+=(foot-server.service)
|
||||
;;
|
||||
3)
|
||||
desktop_choice=qtile-wayland
|
||||
desktop_packages+=(qtile python-pywlroots xorg-xwayland foot)
|
||||
systemd_user_services+=(foot-server.service)
|
||||
;;
|
||||
4)
|
||||
desktop_choice=river
|
||||
desktop_packages+=(river foot)
|
||||
systemd_user_services+=(foot-server.service)
|
||||
;;
|
||||
5)
|
||||
desktop_choice=plasma-wayland
|
||||
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole foot kate dolphin kompare kcalc)
|
||||
systemd_services+=(sddm.service)
|
||||
systemd_user_services+=(foot-server.service)
|
||||
;;
|
||||
6)
|
||||
desktop_choice=gnome-wayland
|
||||
desktop_packages+=(gnome foot)
|
||||
systemd_services+=(gdm.service)
|
||||
systemd_user_services+=(foot-server.service)
|
||||
;;
|
||||
7)
|
||||
desktop_choice=cosmic
|
||||
desktop_packages+=(cosmic)
|
||||
systemd_services+=(cosmic-greeter.service)
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
desktop_packages+=(vulkan-virtio)
|
||||
elif lspci | grep VGA | grep -q NVIDIA
|
||||
then
|
||||
desktop_packages+=(nvidia-utils)
|
||||
elif lscpu | grep 'Model name:' | grep -q AMD
|
||||
then
|
||||
desktop_packages+=(amdvlk)
|
||||
elif lscpu | grep 'Model name:' | grep -q Intel
|
||||
then
|
||||
desktop_packages+=(vulkan-intel)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
# Environment
|
||||
sudo tee -a /etc/environment >/dev/null <<- environment
|
||||
QT_QPA_PLATFORM=wayland
|
||||
environment
|
||||
;;
|
||||
*)
|
||||
# Xorg
|
||||
desktop_packages+=(xorg)
|
||||
case ${desktop} in
|
||||
8)
|
||||
desktop_choice=qtile-x11
|
||||
desktop_packages+=(qtile xorg-xinit konsole)
|
||||
;;
|
||||
9)
|
||||
desktop_choice=bspwm
|
||||
desktop_packages+=(bspwm sxhkd xorg-xinit polybar konsole)
|
||||
;;
|
||||
10)
|
||||
desktop_choice=awesome
|
||||
desktop_packages+=(awesome xorg-xinit konsole)
|
||||
;;
|
||||
11)
|
||||
desktop_choice=i3
|
||||
desktop_packages+=(i3-wm i3status i3lock dmenu lightdm lightdm-gtk-greeter pavucontrol konsole kate dolphin kompare breeze-icons)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
12)
|
||||
desktop_choice=i3-plasma
|
||||
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc i3-wm i3status dmenu wmctrl feh)
|
||||
systemd_services+=(sddm.service)
|
||||
;;
|
||||
13)
|
||||
desktop_choice=plasma-x11
|
||||
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc)
|
||||
systemd_services+=(sddm.service)
|
||||
;;
|
||||
14)
|
||||
desktop_choice=gnome-x11
|
||||
desktop_packages+=(gnome)
|
||||
systemd_services+=(gdm.service)
|
||||
;;
|
||||
15)
|
||||
desktop_choice=xfce4
|
||||
desktop_packages+=(xfce4 lightdm lightdm-gtk-greeter)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
16)
|
||||
desktop_choice=budgie
|
||||
desktop_packages+=(budgie lightdm lightdm-gtk-greeter tilix)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
17)
|
||||
desktop_choice=cinnamon
|
||||
desktop_packages+=(cinnamon lightdm lightdm-gtk-greeter gnome-console)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
18)
|
||||
desktop_choice=deepin
|
||||
desktop_packages+=(deepin deepin-kwin $(pacman -Sgq deepin-extra | grep -v deepin-reader) lightdm lightdm-gtk-greeter gnome-keyring)
|
||||
systemd_services+=(lightdm.service)
|
||||
if uname -r | grep -q 'lts\|hardened\|zen'
|
||||
then
|
||||
desktop_packages+=(deepin-anything-dkms)
|
||||
else
|
||||
desktop_packages+=(deepin-anything-arch)
|
||||
fi
|
||||
;;
|
||||
19)
|
||||
desktop_choice=mate
|
||||
desktop_packages+=(mate mate-extra lightdm lightdm-gtk-greeter)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
20)
|
||||
desktop_choice=pantheon
|
||||
desktop_packages+=(pantheon lightdm-pantheon-greeter lightdm)
|
||||
systemd_services+=(lightdm.service)
|
||||
;;
|
||||
21)
|
||||
desktop_choice=cutefish
|
||||
desktop_packages+=(cutefish sddm)
|
||||
systemd_services+=(sddm.service)
|
||||
;;
|
||||
22)
|
||||
desktop_choice=lxde
|
||||
desktop_packages+=(lxde lxdm)
|
||||
systemd_services+=(lxdm.service)
|
||||
;;
|
||||
23)
|
||||
desktop_choice=lxqt
|
||||
desktop_packages+=(lxqt sddm breeze-icons)
|
||||
systemd_services+=(sddm.service)
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
echo
|
||||
echo -e "\t\e[1mYou have chosen \e[32m${desktop_choice}\e[0m\e[1m desktop\e[0m"
|
||||
echo
|
||||
echo -e '\e[1;35mInstalling base packages\e[0m'
|
||||
sudo pacman --sync --ask 4 ${desktop_packages[@]} || die 'Failed to install required packages'
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${desktop_choice} in
|
||||
plasma-wayland)
|
||||
mkdir -p ~/.config/{autostart-scripts,foot}/
|
||||
# install /dev/stdin ~/.config/autostart-scripts/foot.sh <<- foot
|
||||
# #!/bin/sh
|
||||
# foot --server
|
||||
# foot
|
||||
cat >>~/.config/kglobalshortcutsrc <<- shortcuts
|
||||
|
||||
[services][footclient.desktop]
|
||||
_launch=Alt+Return
|
||||
|
||||
[services][org.kde.konsole.desktop]
|
||||
_launch=none
|
||||
shortcuts
|
||||
;;
|
||||
gnome-wayland)
|
||||
mkdir -p ~/.config/{autostart,foot}/
|
||||
# cat > ~/.config/autostart/foot-server.desktop <<- foot
|
||||
# [Desktop Entry]
|
||||
# Type=Application
|
||||
# Name=Foot server
|
||||
# Exec=foot --server
|
||||
# foot
|
||||
gsettings set $(gsettings list-schemas | grep terminal) exec footclient
|
||||
;;
|
||||
cosmic)
|
||||
mkdir -p ~/.config/foot/
|
||||
;;
|
||||
i3|i3-plasma)
|
||||
# i3-config
|
||||
mkdir -p ~/.config/i3/
|
||||
curl --fail -s -L https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
||||
case ${desktop_choice} in
|
||||
i3-plasma)
|
||||
kwriteconfig6 --file startkderc --group General --key systemdBoot false
|
||||
sudo install /dev/stdin /opt/local/bin/plasma-i3.sh <<- EOF
|
||||
#!/usr/bin/env bash
|
||||
export KDEWM=/usr/bin/i3
|
||||
/usr/bin/startplasma-x11
|
||||
EOF
|
||||
sudo tee /usr/share/xsessions/plasma-i3.desktop >/dev/null <<- EOF
|
||||
[Desktop Entry]
|
||||
Type=XSession
|
||||
Exec=/opt/local/bin/plasma-i3.sh
|
||||
DesktopNames=KDE
|
||||
Name=Plasma (i3)
|
||||
Comment=KDE Plasma with i3 as the WM
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
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
|
||||
fi
|
||||
;;
|
||||
qtile-x11)
|
||||
echo 'exec qtile start' >~/.xinitrc
|
||||
cat >> ~/.bash_profile <<- 'autostart'
|
||||
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||
then
|
||||
exec startx
|
||||
fi
|
||||
autostart
|
||||
;;
|
||||
qtile-wayland)
|
||||
mkdir -p ~/.config/foot/
|
||||
cat >> ~/.bash_profile <<- 'autostart'
|
||||
|
||||
# Start sway on login from tty
|
||||
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||
then
|
||||
exec qtile start -b wayland
|
||||
fi
|
||||
autostart
|
||||
;;
|
||||
river)
|
||||
mkdir -p ~/.config/foot/
|
||||
cat >> ~/.bash_profile <<- 'autostart'
|
||||
|
||||
# Start sway on login from tty
|
||||
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||
then
|
||||
exec river
|
||||
fi
|
||||
autostart
|
||||
;;
|
||||
bspwm)
|
||||
cat >> ~/.bash_profile <<- 'autostart'
|
||||
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||
then
|
||||
exec startx /usr/bin/bspwm
|
||||
fi
|
||||
autostart
|
||||
mkdir -p ~/.config/{bspwm,sxhkd,polybar}/
|
||||
install -Dm755 /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc
|
||||
install -Dm644 /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc
|
||||
cp /etc/polybar/config.ini ~/.config/polybar/
|
||||
;;
|
||||
awesome)
|
||||
cat >> ~/.bash_profile <<- 'autostart'
|
||||
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||
then
|
||||
exec startx /usr/bin/awesome
|
||||
fi
|
||||
autostart
|
||||
mkdir -p ~/.config/awesome/
|
||||
sed -e '/^terminal =/c terminal = "konsole"' \
|
||||
-e '/^modkey =/c modkey = "Mod1"' /etc/xdg/awesome/rc.lua > ~/.config/awesome/
|
||||
;;
|
||||
sway)
|
||||
# Sway
|
||||
sudo gpasswd -a ${USER} seat >/dev/null
|
||||
|
||||
# Dolphin default apps
|
||||
mkdir -p ~/.config/menus/
|
||||
curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
||||
kbuildsycoca6 >/dev/null 2>&1
|
||||
|
||||
# Dolphin default terminal
|
||||
cat >> ~/.config/kdeglobals <<- foot
|
||||
[General]
|
||||
TerminalApplication=footclient
|
||||
foot
|
||||
|
||||
# Create conf directories
|
||||
mkdir -p ~/.config/{sway/config.d,foot}/
|
||||
|
||||
# Identify conf locations
|
||||
cat > ~/.config/sway/config <<- 'config'
|
||||
include /etc/sway/config.d/*
|
||||
include ~/.config/sway/config.d/*
|
||||
config
|
||||
|
||||
# Default sway config
|
||||
sed -e 's/mod Mod4/mod Mod1/' \
|
||||
-e 's/term foot/&client/' \
|
||||
-e '/set $menu/c set $menu bemenu-run -p "" --no-overlap --tb "#285577" --hb "#285577" --tf "#eeeeee" --hf "#eeeeee" --nf "#bbbbbb"' \
|
||||
/etc/sway/config > ~/.config/sway/config.d/00-config
|
||||
sed -n "/^# Status Bar:$/q;p" -i ~/.config/sway/config.d/00-config
|
||||
|
||||
# Sway config
|
||||
cat > ~/.config/sway/config.d/zz-sway <<- 'config'
|
||||
# Disable xwayland
|
||||
xwayland disable
|
||||
|
||||
# Start foot terminal server
|
||||
exec foot --server
|
||||
|
||||
# Use i3status
|
||||
bar {
|
||||
status_command i3status
|
||||
}
|
||||
|
||||
# Floating windows
|
||||
for_window [window_role="About"] floating enable
|
||||
for_window [window_role="Organizer"] floating enable
|
||||
for_window [window_role="Preferences"] floating enable
|
||||
for_window [window_role="bubble"] floating enable
|
||||
for_window [window_role="page-info"] floating enable
|
||||
for_window [window_role="pop-up"] floating enable
|
||||
for_window [window_role="task_dialog"] floating enable
|
||||
for_window [window_role="toolbox"] floating enable
|
||||
for_window [window_role="webconsole"] floating enable
|
||||
for_window [window_type="dialog"] floating enable
|
||||
for_window [window_type="menu"] floating enable
|
||||
|
||||
# Floating for KCalc
|
||||
for_window [title="KCalc"] floating enable
|
||||
|
||||
# Bind keys for brightness
|
||||
bindsym XF86MonBrightnessDown exec brightnessctl set 5%-
|
||||
bindsym XF86MonBrightnessUp exec brightnessctl set 5%+
|
||||
|
||||
# Mouse and keyboard defaults
|
||||
input type:keyboard xkb_numlock enabled
|
||||
input type:touchpad {
|
||||
tap enabled
|
||||
natural_scroll enabled
|
||||
}
|
||||
config
|
||||
|
||||
# Display config
|
||||
cat > ~/.config/sway/config.d/zz-display <<- 'display'
|
||||
# # Declare output
|
||||
# set $laptop eDP-1 (swaymsg -t get_outputs)
|
||||
|
||||
# Swayidle
|
||||
exec swayidle -w \
|
||||
timeout 300 'swaylock -e -f -c 000000' \
|
||||
timeout 315 'swaymsg "output * power off"' \
|
||||
resume 'swaymsg "output * power on"' \
|
||||
timeout 600 'systemctl suspend' \
|
||||
before-sleep 'swaylock -e -f -c 000000'
|
||||
|
||||
# Laptop lid switches
|
||||
bindswitch --reload --locked lid:on output * disable
|
||||
bindswitch --reload --locked lid:off output * enable
|
||||
|
||||
# Swaylock
|
||||
bindsym Mod4+l exec swaylock -e -f -c 000000
|
||||
|
||||
# Solid black background
|
||||
output * bg #000000 solid_color
|
||||
|
||||
# Prevent swayidle when a window is in fullscreen
|
||||
for_window [class=".*"] inhibit_idle fullscreen
|
||||
for_window [app_id=".*"] inhibit_idle fullscreen
|
||||
display
|
||||
|
||||
# Polkit
|
||||
cat > ~/.config/sway/config.d/zz-polkit <<- 'polkit'
|
||||
exec "/usr/lib/polkit-kde-authentication-agent-1"
|
||||
polkit
|
||||
|
||||
# Monitor
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
cat > ~/.config/sway/config.d/zz-virtualmonitor <<- 'monitor'
|
||||
# Virtual monitor
|
||||
output Virtual-1 {
|
||||
pos 0,0
|
||||
mode 1920x1080@60Hz
|
||||
scale 1.25
|
||||
}
|
||||
monitor
|
||||
fi
|
||||
|
||||
# TTY sway autostart
|
||||
cat >> ~/.bash_profile <<- 'sway'
|
||||
|
||||
# Start sway on login from tty
|
||||
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||
then
|
||||
exec sway
|
||||
fi
|
||||
sway
|
||||
;;
|
||||
hyprland)
|
||||
# Hyprland
|
||||
mkdir -p ~/.config/{menus,hypr/scripts,foot,waybar}/
|
||||
|
||||
# Dolphin default apps
|
||||
curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
||||
kbuildsycoca6 >/dev/null 2>&1
|
||||
|
||||
# Dolphin default terminal
|
||||
cat >> ~/.config/kdeglobals <<- foot
|
||||
[General]
|
||||
TerminalApplication=footclient
|
||||
foot
|
||||
|
||||
# Swayidle
|
||||
install /dev/stdin ~/.config/hypr/scripts/sleep.sh <<- 'swayidle'
|
||||
swayidle -w timeout 300 'swaylock -f -c 000000' \
|
||||
timeout 600 'systemctl suspend' \
|
||||
before-sleep 'swaylock -f -c 000000' &
|
||||
swayidle
|
||||
|
||||
# Config
|
||||
curl --silent --fail https://raw.githubusercontent.com/hyprwm/Hyprland/refs/heads/main/example/hyprland.conf |\
|
||||
sed -e '/Autostart/i exec-once = /usr/lib/polkit-kde-authentication-agent-1' \
|
||||
-e '/Autostart/i exec-once = waybar -c ~/.config/waybar/waybar.conf' \
|
||||
-e '/Autostart/i exec-once = ~/.config/hypr/scripts/sleep.sh' \
|
||||
-e '/^$terminal =/c $terminal = footclient' \
|
||||
-e '/gaps_in =/c gaps_in = 0' \
|
||||
-e '/gaps_out =/c gaps_out = 0' \
|
||||
-e '/^$menu =/c $menu = bemenu-run -p "" --no-overlap --tb "##285577" --hb "##285577" --tf "##eeeeee" --hf "##eeeeee" --nf "##bbbbbb"' \
|
||||
-e 's/bind = $mainMod, R, exec, $menu/bind = $mainMod, D, exec, $menu/' \
|
||||
-e 's/bind = $mainMod, Q, exec, $terminal/bind = $mainMod, RETURN, exec, $terminal/' \
|
||||
-e 's/bind = $mainMod, C, killactive/bind = $mainMod SHIFT, Q, killactive/' \
|
||||
-e '/$mainMod =/c $mainMod = ALT' \
|
||||
-e '/RETURN/a bind = SUPER, L, exec, swaylock -e -f -c 000000' \
|
||||
> ~/.config/hypr/hyprland.conf
|
||||
# -e '/Autostart/i exec-once = uwsm app -- foot --server' \
|
||||
|
||||
# QEMU monitor
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||
then
|
||||
sed -i "/^monitor/c monitor = $(hyprctl monitors all | grep "^Monitor" | awk '{print $2}'), 1920x1080@60, 0x0, 1.5" ~/.config/hypr/hyprland.conf
|
||||
fi
|
||||
|
||||
# Waybar
|
||||
sed -e 's|sway/workspaces|sway/workspaces|g' \
|
||||
-e 's|sway/mode|hyprland/submap|g' \
|
||||
-e '/position/ s|//||' \
|
||||
/etc/xdg/waybar/config.jsonc > ~/.config/waybar/waybar.conf
|
||||
|
||||
# TTY sway autostart
|
||||
cat >> ~/.bash_profile <<- 'hyprland'
|
||||
|
||||
# Start sway on login from tty
|
||||
if uwsm check may-start
|
||||
then
|
||||
exec uwsm start hyprland.desktop
|
||||
fi
|
||||
hyprland
|
||||
;;
|
||||
esac
|
||||
|
||||
# Foot terminal config (/etc/xdg/foot/foot.ini)
|
||||
if [ -d ~/.config/foot/ ]
|
||||
then
|
||||
cat > ~/.config/foot/foot.ini <<- 'foot'
|
||||
[main]
|
||||
include=/usr/share/foot/themes/kitty
|
||||
font=Source Code Pro:size=12
|
||||
workers=32
|
||||
|
||||
[scrollback]
|
||||
# lines=1000
|
||||
foot
|
||||
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
|
||||
echo
|
||||
fi
|
||||
|
||||
# iwd status function
|
||||
if pacman -Q | grep -w -q iwd
|
||||
then
|
||||
cat > ~/.local/functions/iwd-status <<- iwd
|
||||
#!/usr/bin/env bash
|
||||
# iwd connection status
|
||||
function iwd-status
|
||||
{
|
||||
iwctl station "$(iwctl station list | grep connected | awk '{print $(NF-1)}')" show
|
||||
}
|
||||
|
||||
alias iwctl='iwctl station $(iwctl station list | grep connected | awk '{print $(NF-1)}')'
|
||||
iwd
|
||||
fi
|
||||
|
||||
if [[ "${desktop_choice}" == "none" ]]
|
||||
then
|
||||
sudo rm -f ${0}
|
||||
echo -e '\e[1;34mSetup complete, press any key to continue\e[5m...\e[0m\n'
|
||||
read -n 1 -s -p ''
|
||||
elif ls /usr/share/*sessions | grep -q desktop
|
||||
then
|
||||
install /dev/stdin ~/.local/bin/startup <<- 'EOF'
|
||||
#!/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
|
||||
vim ~/.local/bin/startupscript
|
||||
~/.local/bin/startupscript
|
||||
rm -f ${0}
|
||||
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
|
||||
EOF
|
||||
|
||||
install /dev/stdin ~/.local/bin/startupscript <<- EOF
|
||||
$(curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/startup)
|
||||
EOF
|
||||
sudo rm -f ${0}
|
||||
echo -e '\e[1;34mDesktop installed, press any key to load '${desktop_choice}'\e[5m...\e[0m'
|
||||
read -n 1 -s -p ''
|
||||
echo
|
||||
else
|
||||
die 'Something does not feel right'
|
||||
fi
|
||||
|
||||
# Systemd services
|
||||
for service in ${systemd_user_services[@]}
|
||||
do
|
||||
systemctl --quiet --user enable --now ${service}
|
||||
done
|
||||
sudo systemctl --quiet enable --now ${systemd_services[@]}
|
||||
297
functions/startup
Executable file
297
functions/startup
Executable file
|
|
@ -0,0 +1,297 @@
|
|||
#!/usr/bin/env bash
|
||||
# AUR package list
|
||||
aur_list=(
|
||||
# nomachine
|
||||
# realvnc-vnc-viewer
|
||||
# jdownloader2
|
||||
# ledger-live-bin
|
||||
# czkawka-gui-bin
|
||||
)
|
||||
|
||||
# Optional packages list
|
||||
optional=(
|
||||
firefox firefox-decentraleyes firefox-ublock-origin
|
||||
ark okular shotwell mpv ffmpegthumbs
|
||||
veracrypt keepassxc
|
||||
# nextcloud-client
|
||||
# ntfs-3g exfatprogs
|
||||
# libreoffice-fresh
|
||||
# remmina libvncserver
|
||||
# torbrowser-launcher
|
||||
# thunderbird
|
||||
# filezilla
|
||||
# chromium
|
||||
# vlc
|
||||
# gnome-disk-utility
|
||||
# xdg-user-dirs
|
||||
# noto-fonts-cjk
|
||||
# noto-fonts-emoji
|
||||
)
|
||||
|
||||
function INSTALL
|
||||
{
|
||||
sudo pacman --sync ${@} --ask 4
|
||||
echo
|
||||
}
|
||||
|
||||
# VirtualBox
|
||||
until [[ ${install_virtualbox} = [yYnN] ]]
|
||||
do
|
||||
read -n 1 -p $'\n\e[1mWould you like to install Virtualbox? (y/n): \e[0m' install_virtualbox
|
||||
[[ ${install_virtualbox} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
done
|
||||
echo
|
||||
# QEMU
|
||||
until [[ ${install_qemu} = [yYnN] ]]
|
||||
do
|
||||
read -n 1 -p $'\n\e[1mWould you like to install QEMU? (y/n): \e[0m' install_qemu
|
||||
[[ ${install_qemu} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
done
|
||||
|
||||
echo
|
||||
echo
|
||||
|
||||
# Package groups installation
|
||||
INSTALL ${optional[@]}
|
||||
|
||||
# Remmina
|
||||
if [[ ${optional[@]} =~ "remmina" ]] && [ -d ~/.config/sway/config.d/ ]
|
||||
then
|
||||
# Remmina passthrough
|
||||
cat > ~/.config/sway/config.d/zz-remmina <<- 'remmina'
|
||||
# VNC passthrough
|
||||
mode remmina {
|
||||
bindsym Mod4+Shift+p mode default
|
||||
}
|
||||
bindsym Mod4+Shift+p mode remmina
|
||||
remmina
|
||||
fi
|
||||
|
||||
# Tor
|
||||
if [[ ${optional[@]} =~ "torbrowser-launcher" ]]
|
||||
then
|
||||
torbrowser-launcher
|
||||
fi
|
||||
|
||||
# Bluetooth
|
||||
if pacman -Q | grep -q bluez-utils
|
||||
then
|
||||
INSTALL bluedevil
|
||||
sudo systemctl --quiet enable --now bluetooth.service
|
||||
fi
|
||||
|
||||
# AUR packages
|
||||
if [ ${#aur_list[@]} -gt 0 ]
|
||||
then
|
||||
if ! pacman -Q | grep -q -w git
|
||||
then
|
||||
INSTALL git
|
||||
fi
|
||||
echo -e '#!/usr/bin/env bash' > ~/.local/functions/aur-packages
|
||||
for aur_package in ${aur_list[@]}
|
||||
do
|
||||
cd
|
||||
git clone https://aur.archlinux.org/${aur_package}.git
|
||||
if echo ${aur_package} | grep -q nomachine
|
||||
then
|
||||
sed -i 's/_autoservice=n/_autoservice=y/' nomachine/PKGBUILD
|
||||
sed -i 's/_autofirewall=n/_autofirewall=y/' nomachine/PKGBUILD
|
||||
fi
|
||||
cd ${aur_package}/
|
||||
makepkg -csi
|
||||
echo
|
||||
cd ..
|
||||
rm -r ${aur_package}/ -f
|
||||
cat >> ~/.local/functions/aur-packages <<- aur
|
||||
function aur-${aur_package}
|
||||
{
|
||||
cd ~/
|
||||
git clone https://aur.archlinux.org/${aur_package}.git
|
||||
cd ${aur_package}/
|
||||
makepkg -csi
|
||||
echo
|
||||
cd ~/
|
||||
rm -r ${aur_package}/ -f
|
||||
}
|
||||
|
||||
aur
|
||||
done
|
||||
fi
|
||||
|
||||
# Optional AUR extras
|
||||
# freefilesync
|
||||
# pdfsam
|
||||
# fslint pygtk
|
||||
|
||||
# Printers
|
||||
# yay -S --ask 4 print-manager cups system-config-printer skanlite && echo && sudo systemctl --quiet enable --now org.cups.cupsd && sudo gpasswd -a ${USER} sys >/dev/null
|
||||
# Webcam
|
||||
# sudo gpasswd -a ${USER} video >/dev/null
|
||||
|
||||
# i3
|
||||
if [ -f ~/.config/i3/config ]
|
||||
then
|
||||
cat >> ~/.config/i3/config <<- 'config'
|
||||
|
||||
# gaps inner 8
|
||||
# gaps outer 4
|
||||
# for_window [class="^.*"] border pixel 2
|
||||
config
|
||||
|
||||
cat > ~/.local/functions/i3-config <<- 'config'
|
||||
#!/usr/bin/env bash
|
||||
# i3 config
|
||||
function i3-config
|
||||
{
|
||||
vim ~/.config/i3/config
|
||||
}
|
||||
config
|
||||
|
||||
if [ -f /usr/share/xsessions/plasma-i3.desktop ]
|
||||
then
|
||||
tee -a ~/.config/i3/config >/dev/null <<- 'integration'
|
||||
|
||||
# >>> Plasma Integration <<<
|
||||
# Try to kill the wallpaper set by Plasma (it takes up the entire workspace and hides everything)
|
||||
exec --no-startup-id wmctrl -c Plasma
|
||||
for_window [title="Desktop — Plasma"] kill; floating enable; border none
|
||||
no_focus [class=”plasmashell”]
|
||||
|
||||
# Avoid tiling popups, dropdown windows from plasma
|
||||
for_window [class="plasmashell"] floating enable
|
||||
for_window [class="Plasma"] floating enable
|
||||
for_window [class="krunner"] floating enable
|
||||
for_window [class="Kmix"] floating enable
|
||||
for_window [class="Klipper"] floating enable
|
||||
for_window [class="Plasmoidviewer"] floating enable
|
||||
|
||||
# >>> Window Rules <<<
|
||||
# >>> Avoid tiling for non-Plasma stuff <<<
|
||||
for_window [window_role="pop-up"] floating enable
|
||||
for_window [window_role="bubble"] floating enable
|
||||
for_window [window_role="task_dialog"] floating enable
|
||||
for_window [window_role="Preferences"] floating enable
|
||||
for_window [window_role="About"] floating enable
|
||||
for_window [window_type="dialog"] floating enable
|
||||
for_window [window_type="menu"] floating enable
|
||||
integration
|
||||
|
||||
install /dev/stdin ~/.local/bin/rotate-wallpapers <<- feh
|
||||
#!/usr/bin/env bash
|
||||
sleep 1
|
||||
while true
|
||||
do
|
||||
feh --bg-max --randomize /home/${USER}/Pictures
|
||||
sleep 15
|
||||
done
|
||||
feh
|
||||
else
|
||||
if ls -l /dev/disk/* | grep -q 'VBOX'
|
||||
then
|
||||
echo 'exec VBoxClient-all' >> ~/.config/i3/config
|
||||
elif ls -l /dev/disk/* | grep -q 'virtio\|QEMU'
|
||||
then
|
||||
echo 'exec spice-vdagent' >> ~/.config/i3/config
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Sway nextcloud
|
||||
if [[ ${optional[@]} =~ "nextcloud-client" ]] && [ -f ~/.config/sway/config.d/zz-sway ]
|
||||
then
|
||||
cat > ~/.config/sway/config.d/zz-nextcloud <<- 'nextcloud'
|
||||
# Nextcloud
|
||||
exec nextcloud
|
||||
for_window [title="Nextcloud Settings"] floating enable
|
||||
nextcloud
|
||||
fi
|
||||
|
||||
# Virtualbox
|
||||
if [[ ${install_virtualbox} = [yY] ]]
|
||||
then
|
||||
echo 'Installing Virtualbox'
|
||||
|
||||
if uname -r | grep -q 'lts\|hardened\|zen'
|
||||
then
|
||||
host_modules='virtualbox-host-dkms'
|
||||
else
|
||||
host_modules='virtualbox-host-modules-arch'
|
||||
fi
|
||||
|
||||
INSTALL virtualbox ${host_modules} virtualbox-guest-iso
|
||||
echo
|
||||
|
||||
sudo gpasswd -a ${USER} vboxusers >/dev/null
|
||||
echo
|
||||
|
||||
if findmnt '/' | grep -q -w 'btrfs'
|
||||
then
|
||||
mkdir ~/VirtualBox\ VMs/
|
||||
chattr +C ~/VirtualBox\ VMs/
|
||||
fi
|
||||
fi
|
||||
|
||||
# QEMU
|
||||
if [[ ${install_qemu} = [yY] ]]
|
||||
then
|
||||
echo 'Installing QEMU'
|
||||
INSTALL qemu-desktop virt-manager edk2-ovmf \
|
||||
dnsmasq dmidecode vde2 bridge-utils
|
||||
echo
|
||||
|
||||
# Make host system a pacman cache server
|
||||
sudo tee /etc/systemd/system/local-cacheserver.service >/dev/null <<- 'CACHESERVER'
|
||||
[Unit]
|
||||
Description=Python HTTP server for Pacman Cache Server
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/python3 -m http.server --directory /var/cache/pacman/pkg/ 9090
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
CACHESERVER
|
||||
|
||||
# Host iptables rules as a pacman cache server
|
||||
sudo iptables -I INPUT -s 192.168.0.0/16 -p tcp -m tcp --dport 9090 -j ACCEPT -m comment --comment "Pacman cache server"
|
||||
sudo sed -i '/## Simple Firewall/i\
|
||||
# Pacman cache server\
|
||||
-A INPUT -s 192.168.0.0/16 -p tcp -m tcp --dport 9090 -j ACCEPT -m comment --comment "Pacman cache server"\n' \
|
||||
/etc/iptables/userinput.rules
|
||||
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules | sudo tee /etc/iptables/iptables.rules >/dev/null
|
||||
|
||||
# QEMU pacman cache service
|
||||
sudo tee /etc/systemd/system/local-update-virtpkg-cache.service >/dev/null <<- 'service'
|
||||
[Unit]
|
||||
Description=Refresh package cache twice daily
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/bash -c "/usr/bin/pacman -Syw -d --ask 4 $(curl --fail -s -L https://git.myvelabs.com/lab/archlinux/raw/branch/master/pkg/qemu)"
|
||||
service
|
||||
|
||||
# QEMU pacman cache timer
|
||||
sudo tee /etc/systemd/system/local-update-virtpkg-cache.timer >/dev/null <<- 'timer'
|
||||
[Unit]
|
||||
Description=Refresh pacman package cache
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 00/12:00:00
|
||||
RandomizedDelaySec=12h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
timer
|
||||
|
||||
# Enable services
|
||||
sudo systemctl --quiet enable --now libvirtd.service
|
||||
sudo systemctl --quiet enable local-cacheserver.service local-update-virtpkg-cache.timer
|
||||
sudo virsh -q net-start default
|
||||
sudo virsh -q net-autostart default
|
||||
sudo gpasswd -a ${USER} libvirt >/dev/null
|
||||
echo
|
||||
fi
|
||||
|
||||
rm -f ${0}
|
||||
echo -e '\e[1;32mSupplementary installer completed, reboot one last time\e[0m\n'
|
||||
110
functions/user
Executable file
110
functions/user
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env bash
|
||||
revision=0.1a
|
||||
set -a
|
||||
set -E
|
||||
|
||||
# Create local paths
|
||||
mkdir -p ~/.local/{bin,functions}
|
||||
|
||||
# Generate ssh identity
|
||||
ssh-keygen -q \
|
||||
-t ed25519 \
|
||||
-P "" \
|
||||
-C "${username}@${hostname}" \
|
||||
-f ~/.ssh/id_ed25519
|
||||
mkdir ~/.ssh/sockets/
|
||||
|
||||
# Custom bashrc
|
||||
cat > ~/.local/functions/bashrc <<- 'BASHRC'
|
||||
#!/usr/bin/env bash
|
||||
# Shell color
|
||||
PS1="$(tput setaf 6)[\u@\h \W \$?]\$ $(tput sgr0)"
|
||||
|
||||
# Colored prompts
|
||||
alias ll='ls --color=auto -l -a -h'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
BASHRC
|
||||
|
||||
# Btrfs functions
|
||||
if findmnt / | grep -w -q btrfs
|
||||
then
|
||||
cat > ~/.local/functions/btrfs <<- 'btrfs'
|
||||
#!/usr/bin/env bash
|
||||
# Btrfs check
|
||||
function btrfs-check
|
||||
{
|
||||
sudo dmesg | grep -i btrfs
|
||||
}
|
||||
# # Snapper
|
||||
# function snapshot-home
|
||||
# {
|
||||
# if [ "${*}" ]
|
||||
# then
|
||||
# sudo snapper -c home create --description "${*}"
|
||||
# else
|
||||
# sudo snapper -c home create --description "$(date)"
|
||||
# fi
|
||||
# }
|
||||
#
|
||||
# function snapshot-root
|
||||
# {
|
||||
# if [ "${*}" ]
|
||||
# then
|
||||
# sudo snapper -c root create --description "${*}"
|
||||
# else
|
||||
# sudo snapper -c root create --description "$(date)"
|
||||
# fi
|
||||
# }
|
||||
#
|
||||
# function snapshot-list
|
||||
# {
|
||||
# sudo -v
|
||||
# echo -e '\n\e[1;33mRoot snapshots:\e[0m'
|
||||
# sudo snapper -c root ls
|
||||
# echo -e '\n\e[1;33mHome snapshots:\e[0m'
|
||||
# sudo snapper -c home ls
|
||||
# echo
|
||||
# }
|
||||
#
|
||||
# function snapshot-delete
|
||||
# {
|
||||
# if ! grep -w -q 'root\|home' <<< "${1}" || [ -z "${2}" ]
|
||||
# then
|
||||
# echo -e '\n\t\e[1;31mInvalid option, use syntax: ${root,home} $snapshot\e[0m\n'
|
||||
# return 1
|
||||
# elif grep -w -q '1' <<< "${2}"
|
||||
# then
|
||||
# echo -e '\n\t\e[1;31mUnable to delete "fresh install" snapshot\e[0m\n'
|
||||
# return 1
|
||||
# fi
|
||||
#
|
||||
# if [[ "${1}" = "root" ]]
|
||||
# then
|
||||
# if ls /.snapshots | grep -q $(sed -e 's/-/\\\|/g' <<< "${2}")
|
||||
# then
|
||||
# sudo snapper -c root delete "${2}"
|
||||
# elif ! [ -d /.snapshots/"${2}" ]
|
||||
# then
|
||||
# echo -e '\n\t\e[1;31mSnapshot doesn't exist, try again\e[0m\n'
|
||||
# fi
|
||||
# elif [[ "${1}" = "home" ]]
|
||||
# then
|
||||
# if ls /home/.snapshots | grep -q $(sed -e 's/-/\\\|/g' <<< "${2}")
|
||||
# then
|
||||
# sudo snapper -c home delete "${2}"
|
||||
# elif ! [ -d /home/.snapshots/"${2}" ]
|
||||
# then
|
||||
# echo -e '\n\t\e[1;31mSnapshot doesn't exist, try again\e[0m\n'
|
||||
# fi
|
||||
# fi
|
||||
# }
|
||||
btrfs
|
||||
fi
|
||||
|
||||
if pacman -Q | grep -q yubikey
|
||||
then
|
||||
install /dev/stdin ~/yksetup.sh <<- 'yubikey'
|
||||
$(curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/yubikey)
|
||||
yubikey
|
||||
fi
|
||||
86
functions/yubikey
Executable file
86
functions/yubikey
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env bash
|
||||
echo
|
||||
|
||||
[ -d ~/.config/Yubico ] || mkdir -p ~/.config/Yubico
|
||||
|
||||
sudo pacman -S --ask 4 pam-u2f yubico-pam
|
||||
|
||||
read -n 1 -s -p $'\n\e[1;33mInsert your yubikey and press the enter key to continue \e[0m'
|
||||
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||
|
||||
pamu2fcfg > ~/.config/Yubico/u2f_keys
|
||||
|
||||
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
|
||||
until [[ "$YUBIKEY" = [nN] ]]
|
||||
do
|
||||
if [[ "$YUBIKEY" != [yYnN] ]]
|
||||
then
|
||||
echo -e '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
read -n 1 -p $'\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
elif [[ "$YUBIKEY" = [yY] ]]
|
||||
then
|
||||
read -n 1 -s -p $'\n\n\e[1;33mInsert the next yubikey and press the enter key to continue \e[0m'
|
||||
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||
|
||||
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||
|
||||
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e '\n\n\e[1;33mUpdating pam configs'
|
||||
echo -e 'Open another terminal or tty and login as sudo in case an issue comes up'
|
||||
read -n 1 -s -p $'Press the enter key once logged in as sudo in another terminal or tty \e[0m\n'
|
||||
|
||||
# System wide user authentication
|
||||
sudo sed -i '/^auth .* required .* pam_faillock.so .* authsucc/a\
|
||||
auth required pam_u2f.so' /etc/pam.d/system-auth
|
||||
|
||||
# Polkit authentication
|
||||
sudo sed -i '/^#%PAM.*/a\
|
||||
auth sufficient pam_u2f.so' /etc/pam.d/polkit-1
|
||||
|
||||
# Sudo authentication
|
||||
sudo sed -i '/^#%PAM.*/a\
|
||||
auth sufficient pam_u2f.so' /etc/pam.d/sudo
|
||||
|
||||
# KDE lockscreen authentication
|
||||
sudo sed -i '/^#%PAM.*/a\
|
||||
auth required pam_u2f.so' /etc/pam.d/kde
|
||||
|
||||
cat > ~/.local/functions/add-yubikey <<- 'ADDYUBIKEY'
|
||||
# Add a new yubikey
|
||||
function add-yubikey
|
||||
{
|
||||
read -n 1 -s -p $'\n\e[1;33mInsert your yubikey and press the enter key to continue \e[0m'
|
||||
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||
|
||||
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||
|
||||
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
until [[ "$YUBIKEY" = [nN] ]]
|
||||
do
|
||||
if [[ "$YUBIKEY" != [yYnN] ]]
|
||||
then
|
||||
echo -e '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
read -n 1 -p $'\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
elif [[ "$YUBIKEY" = [yY] ]]
|
||||
then
|
||||
read -n 1 -s -p $'\n\n\e[1;33mInsert the next yubikey and press the enter key to continue \e[0m'
|
||||
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||
|
||||
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||
|
||||
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||
fi
|
||||
done
|
||||
echo -e '\n\n\e[1;34mYubikeys updated'
|
||||
echo -e 'Exiting...\e[0m\n'
|
||||
}
|
||||
ADDYUBIKEY
|
||||
|
||||
echo -e '\n\e[1;34mYubikey setup completed'
|
||||
echo -e 'To update your saved yubikeys, run "add-yubikey" in the terminal'
|
||||
echo -e 'Exiting...\e[0m\n'
|
||||
rm -f ${0}
|
||||
2315
homelab.sh
Executable file
2315
homelab.sh
Executable file
File diff suppressed because it is too large
Load diff
67
installer.sh
Executable file
67
installer.sh
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env bash
|
||||
download_url=git.myvelabs.com/lab/archlinux/raw/branch/master
|
||||
|
||||
# Detect network connectivity
|
||||
if ! nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || ! nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||
then
|
||||
echo -e '\n\t\e[31mNo internet connection detected\e[0m\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to list available script options
|
||||
function listScripts
|
||||
{
|
||||
echo -e '\n\e[1;36mSelect a script to run\e[0m
|
||||
1) Arch Linux
|
||||
2) Arch Linux VM
|
||||
3) Arch Linux Passthrough
|
||||
4) Arch Linux Server
|
||||
5) Recovery'
|
||||
|
||||
while true
|
||||
do
|
||||
read -n 1 -p '> ' script_selection
|
||||
case ${script_selection} in
|
||||
1) script=arch
|
||||
break;;
|
||||
2) script=virtual-machine
|
||||
break;;
|
||||
3) script=passthrough
|
||||
break;;
|
||||
4) script=homelab
|
||||
break;;
|
||||
5) script=recover
|
||||
break;;
|
||||
*) echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 5\e[0m'
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
# Detect script choice
|
||||
case ${1} in
|
||||
arch)
|
||||
script=arch ;;
|
||||
vm|virtual-machine)
|
||||
script=virtual-machine ;;
|
||||
passthrough)
|
||||
script=passthrough ;;
|
||||
server|homelab)
|
||||
script=homelab ;;
|
||||
recover)
|
||||
script=recover ;;
|
||||
*)
|
||||
listScripts ;;
|
||||
esac
|
||||
|
||||
# Run script if successful, abort installer otherwise
|
||||
if curl --fail -s -L https://${download_url}/${script}.sh -o ./arch
|
||||
then
|
||||
/usr/bin/bash ./arch "${@:2}"
|
||||
exit 0
|
||||
else
|
||||
echo -e '\e[31mInvalid script or server may be offline, make another selection or try again later\e[0m\n'
|
||||
exit 1
|
||||
fi
|
||||
1582
notes/archvps.sh
Executable file
1582
notes/archvps.sh
Executable file
File diff suppressed because it is too large
Load diff
12
notes/sshkeys.pub
Normal file
12
notes/sshkeys.pub
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGQ2rLYB6U2i3dyb1+Fn8fKSsfsTno87Vf++yFQkD2k user@zenbook
|
||||
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPJnaY1RtJ+JdfAEJfUcO99yrSGuH0UQit0itzrpgeI user@dotfiles
|
||||
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA5Zwmxt3kTIZT9fsQW+NCcTRYFz97Qp+hXbj7AcJXi6 root@mini
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIES0RiFcV2yoLwNrK6iB3xU3OlQ85vAWgxjoNaG3iuMp root@phone
|
||||
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUz2KdC9MWYLwYgGfjdxPGd0XZbdRLUJog4IbWp9EZl user@myvelabs
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGlaVV3oZo/IAGXF3F9qdaiSRTQLzc2aJ50h3MNdLUmI root@myvelabs
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIAnDy15V5hT9+TX/gZeEpStamJOJNpruKdx3PXpcIX6 user@docker
|
||||
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDmgC/c0Rjyk6sL+PXhuxOfaBVw/sPTrWfX5GBGwqq/g user@desktop
|
||||
48
notes/ubuntu-nginx
Normal file
48
notes/ubuntu-nginx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Ubuntu - nginx-mainline
|
||||
# https://nginx.org/en/linux_packages.html
|
||||
|
||||
# Install the prerequisites:
|
||||
|
||||
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y
|
||||
|
||||
# Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:
|
||||
|
||||
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
|
||||
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
|
||||
|
||||
# Verify that the downloaded file contains the proper key:
|
||||
|
||||
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
|
||||
| grep -q 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 || exit 1
|
||||
|
||||
# The output should contain the full fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 as follows:
|
||||
#
|
||||
# pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24]
|
||||
# 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
|
||||
# uid nginx signing key <signing-key@nginx.com>
|
||||
|
||||
# Note that the output can contain other keys used to sign the packages.
|
||||
|
||||
# # To set up the apt repository for stable nginx packages, run the following command:
|
||||
#
|
||||
# echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||
# http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||
# | sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
|
||||
# If you would like to use mainline nginx packages, run the following command instead:
|
||||
|
||||
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
|
||||
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
|
||||
# Set up repository pinning to prefer our packages over distribution-provided ones:
|
||||
|
||||
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
|
||||
| sudo tee /etc/apt/preferences.d/99nginx
|
||||
|
||||
# To install nginx, run the following commands:
|
||||
|
||||
sudo apt update
|
||||
sudo apt install nginx -y
|
||||
73
notes/wireguard
Normal file
73
notes/wireguard
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
############
|
||||
# Key generation
|
||||
############
|
||||
for peer in {0..9}
|
||||
do
|
||||
wg genkey | (umask 0077 && tee peer${peer}.key) | wg pubkey > peer${peer}.pub
|
||||
done
|
||||
|
||||
############
|
||||
# Server configuration
|
||||
############
|
||||
/etc/wireguard/wg0.conf
|
||||
############
|
||||
[Interface]
|
||||
Address = 10.200.200.1/24
|
||||
ListenPort = 51820
|
||||
PrivateKey = SERVER_PRIVATE_KEY
|
||||
|
||||
# substitute eth0 in the following lines to match the Internet-facing interface
|
||||
# the FORWARD rules will always be needed since traffic needs to be forwarded between the WireGuard
|
||||
# interface and the other interfaces on the server.
|
||||
# if the server is behind a router and receives traffic via NAT, specify static routing back to the
|
||||
# 10.200.200.0/24 subnet, the NAT iptables rules are not needed but the FORWARD rules are needed.
|
||||
# if the server is behind a router and receives traffic via NAT but one cannot specify static routing back to
|
||||
# 10.200.200.0/24 subnet, both the NAT and FORWARD iptables rules are needed.
|
||||
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
[Peer]
|
||||
# foo
|
||||
PublicKey = PEER_FOO_PUBLIC_KEY
|
||||
PresharedKey = PRE-SHARED_KEY
|
||||
AllowedIPs = 10.200.200.2/32
|
||||
|
||||
[Peer]
|
||||
# bar
|
||||
PublicKey = PEER_BAR_PUBLIC_KEY
|
||||
PresharedKey = PRE-SHARED_KEY
|
||||
AllowedIPs = 10.200.200.3/32
|
||||
|
||||
###
|
||||
# The interface may be brought up using wg-quick up wg0 respectively by starting and potentially enabling the interface via wg-quick@interface.service, e.g. wg-quick@wg0.service. To close the interface use wg-quick down wg0 respectively stop wg-quick@interface.service.
|
||||
###
|
||||
|
||||
############
|
||||
# Client configuration
|
||||
############
|
||||
foo.conf
|
||||
[Interface]
|
||||
Address = 10.200.200.2/32
|
||||
PrivateKey = PEER_FOO_PRIVATE_KEY
|
||||
DNS = 10.200.200.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = SERVER_PUBLICKEY
|
||||
PresharedKey = PRE-SHARED_KEY
|
||||
Endpoint = my.ddns.example.com:51820
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
bar.conf
|
||||
[Interface]
|
||||
Address = 10.200.200.3/32
|
||||
PrivateKey = PEER_BAR_PRIVATE_KEY
|
||||
DNS = 10.200.200.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = SERVER_PUBLICKEY
|
||||
PresharedKey = PRE-SHARED KEY
|
||||
Endpoint = my.ddns.example.com:51820
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
|
||||
###
|
||||
# Note: Users of NetworkManager, may need to enable the NetworkManager-wait-online.service and users of systemd-networkd may need to enable the systemd-networkd-wait-online.service to wait until devices are network-ready before attempting a WireGuard connection.
|
||||
###
|
||||
782
passthrough.sh
Executable file
782
passthrough.sh
Executable file
|
|
@ -0,0 +1,782 @@
|
|||
#!/usr/bin/env bash
|
||||
set -a
|
||||
set -E
|
||||
|
||||
# SSH public keys
|
||||
sshkeys=''
|
||||
|
||||
## 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
|
||||
}
|
||||
|
||||
# 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
|
||||
else
|
||||
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||
fi
|
||||
|
||||
function returnUUID
|
||||
{
|
||||
for partuuid in \
|
||||
$(blkid -s UUID -o value ${1}) \
|
||||
$(lsblk -d -n -o uuid ${1}) \
|
||||
$(ls -l -a /dev/disk/by-uuid | grep "$(echo ${1} | sed 's\/dev\\')" | awk '{print $9}')
|
||||
do
|
||||
if [ ${partuuid} ]
|
||||
then
|
||||
echo ${partuuid}
|
||||
break
|
||||
else
|
||||
unset partuuid
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z ${partuuid} ]
|
||||
then
|
||||
die 'Unable to determine partition UUID'
|
||||
fi
|
||||
}
|
||||
|
||||
clear
|
||||
|
||||
cat <<title
|
||||
${black}${bold}## rev ${revision}${reset}
|
||||
${blue}${bold}
|
||||
Arch Passthrough
|
||||
${reset}${bold}
|
||||
Press any key when ready...${reset}
|
||||
title
|
||||
read -n 1 -s
|
||||
echo
|
||||
|
||||
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
|
||||
|
||||
# Hostname
|
||||
say "Create a name for your computer" blue
|
||||
until [ ${hostname} ]
|
||||
do
|
||||
read -r -p 'Hostname: ' hostname
|
||||
echo
|
||||
[ ${hostname} ] || say "Hostname cannot be empty, try again" red
|
||||
done
|
||||
|
||||
# User password
|
||||
say "Set a password for user" blue
|
||||
while true
|
||||
do
|
||||
read -s -r -p 'User password: ' userpass
|
||||
echo
|
||||
|
||||
read -s -r -p 'Verify user password: ' userpass2
|
||||
echo
|
||||
echo
|
||||
|
||||
if [ -z ${userpass} ] || [ "${userpass}" = "${userpass2}" ]
|
||||
then
|
||||
break
|
||||
else
|
||||
say "Passwords did not match, try again" red
|
||||
fi
|
||||
done
|
||||
say "user@${hostname}'s password has been saved" green
|
||||
echo
|
||||
|
||||
# Superuser password
|
||||
say "Create a root superuser password" blue
|
||||
while true
|
||||
do
|
||||
read -s -r -p 'Superuser password: ' rootpass
|
||||
echo
|
||||
|
||||
read -s -r -p $'Verify superuser password: ' rootpass2
|
||||
echo
|
||||
echo
|
||||
|
||||
if [ -z ${rootpass} ] || [ "${rootpass}" = "${rootpass2}" ]
|
||||
then
|
||||
break
|
||||
else
|
||||
say "Passwords did not match, try again" red
|
||||
fi
|
||||
done
|
||||
say "Root superuser password has been saved" green
|
||||
echo
|
||||
|
||||
# Assign system drive
|
||||
say "Identify the system drive from the list of available devices below" blue
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
say '## SSD and HDD device format begins with "sd" or "hd" (sda, sdb, sd[*])
|
||||
## NVME and PCI device format is "nvme[*]n1" (nvme0n1, nvme1n1, nvme[*]n1)' black bold
|
||||
lsblk -o name | grep -q -w ${installation_disk} ||
|
||||
while true
|
||||
do
|
||||
read -r -p 'Installation device: ' installation_disk
|
||||
|
||||
if [ ${installation_disk} ] && lsblk -o name | grep -q -w ${installation_disk}
|
||||
then
|
||||
break
|
||||
else
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
if [ -z ${installation_disk} ]
|
||||
then
|
||||
echo
|
||||
say "Field cannot be empty, try again" red
|
||||
else
|
||||
echo
|
||||
say "Invalid selection or drive not available, try again" red
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo
|
||||
say "Installation drive set as ${green}${reset}/dev/${installation_disk}" reset
|
||||
|
||||
# Choose a linux kernel
|
||||
cat <<menu
|
||||
${blue}
|
||||
Select a linux kernel version${reset}
|
||||
1) linux
|
||||
2) linux-lts
|
||||
3) linux-hardened
|
||||
4) linux-zen
|
||||
menu
|
||||
|
||||
until [[ ${kernel_choice} = [1-4] ]]
|
||||
do
|
||||
read -n 1 -p '> ' kernel_choice
|
||||
echo
|
||||
if ! [[ ${kernel_choice} = [1-4] ]]
|
||||
then
|
||||
echo
|
||||
say 'Invalid selection, type an option from 1 to 4' red
|
||||
fi
|
||||
done
|
||||
case ${kernel_choice} in
|
||||
1)
|
||||
linux_kernel='linux'
|
||||
;;
|
||||
2)
|
||||
linux_kernel='linux-lts'
|
||||
;;
|
||||
3)
|
||||
linux_kernel='linux-hardened'
|
||||
;;
|
||||
4)
|
||||
linux_kernel='linux-zen'
|
||||
;;
|
||||
esac
|
||||
echo
|
||||
say " You have chosen ${green}${linux_kernel}${reset} as a kernel" reset
|
||||
echo
|
||||
|
||||
# Unmount if mounted
|
||||
if findmnt '/mnt' | grep -q -w '/mnt'
|
||||
then
|
||||
umount -R /mnt
|
||||
fi
|
||||
|
||||
# Shred installation drive
|
||||
say "Partitioning /dev/${installation_disk}" yellow bold
|
||||
wipefs -f -a /dev/${installation_disk}
|
||||
blkdiscard -f /dev/${installation_disk}
|
||||
if [ -d /sys/firmware/efi/efivars ]
|
||||
then
|
||||
parted --script --align=optimal /dev/${installation_disk} \
|
||||
mklabel gpt \
|
||||
mkpart primary fat32 1MiB 100MiB \
|
||||
mkpart primary ${partition} 100MiB 100% \
|
||||
set 1 esp on
|
||||
partprobe /dev/${installation_disk}
|
||||
export {efivol,bootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*1$)
|
||||
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*2$)
|
||||
echo
|
||||
|
||||
function bootLoader
|
||||
{
|
||||
# Systemd-boot
|
||||
say "Configuring systemd-boot" yellow bold
|
||||
bootctl --path=/boot install
|
||||
echo -e 'title Arch Linux
|
||||
linux /vmlinuz-'${linux_kernel}'
|
||||
initrd /initramfs-'${linux_kernel}'.img
|
||||
options quiet root=UUID='$(returnUUID ${rootpart})' rw' > /boot/loader/entries/arch.conf
|
||||
echo -e 'default arch
|
||||
timeout 0
|
||||
console-mode max
|
||||
editor no' > /boot/loader/loader.conf
|
||||
systemdbootservice='systemd-boot-update.service'
|
||||
}
|
||||
else
|
||||
bios='syslinux'
|
||||
parted --script --align=optimal /dev/${installation_disk} \
|
||||
mklabel msdos \
|
||||
mkpart primary ${partition} 1MiB 100% \
|
||||
set 1 boot on || die 'Disk partitioning failed'
|
||||
partprobe /dev/${installation_disk}
|
||||
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*1$)
|
||||
echo
|
||||
|
||||
function bootLoader
|
||||
{
|
||||
# Syslinux
|
||||
say "Configuring syslinux" yellow bold
|
||||
syslinux-install_update -i -a -m
|
||||
sed -i 's\LINUX ../vmlinuz-linux.*\LINUX ../vmlinuz-'${linux_kernel}'\g' /boot/syslinux/syslinux.cfg
|
||||
sed -i 's/APPEND root.*/APPEND root=UUID='"$(returnUUID ${rootpart})"' rw quiet/g' /boot/syslinux/syslinux.cfg
|
||||
sed -i 's/.*PROMPT.*/PROMPT 0/g' /boot/syslinux/syslinux.cfg
|
||||
sed -i 's/.*TIMEOUT.*/TIMEOUT 0/g' /boot/syslinux/syslinux.cfg
|
||||
sed -i 's/.*UI menu.*/#UI menu/g' /boot/syslinux/syslinux.cfg
|
||||
}
|
||||
fi
|
||||
|
||||
say "Configuring volumes" yellow bold
|
||||
yes | mkfs.ext4 ${rootvol}
|
||||
mount ${rootvol} /mnt
|
||||
|
||||
if [ -d /sys/firmware/efi/efivars ]
|
||||
then
|
||||
mkdir /mnt/boot
|
||||
yes | mkfs.fat -F 32 ${efivol}
|
||||
mount ${bootvol} /mnt/boot
|
||||
findmnt '/mnt/boot' | grep -q -w "${bootvol}" || die 'Boot partition has not been mounted properly'
|
||||
echo
|
||||
fi
|
||||
|
||||
say "Installing Arch Linux base packages on /dev/${installation_disk}" yellow bold
|
||||
sed -i \
|
||||
-e '/Color/c\Color' \
|
||||
-e '/ParallelDownloads/c\ParallelDownloads = 10' \
|
||||
-e 's#^\[core\]$\|^\[extra\]$#&\
|
||||
CacheServer = http://192.168.122.1:9090#' \
|
||||
/etc/pacman.conf
|
||||
|
||||
# Temporarily disable mkinitcpio
|
||||
ln -s -f /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
|
||||
|
||||
pacstrap -K /mnt ${linux_kernel} qemu-guest-agent base mkinitcpio sudo \
|
||||
${bios} reflector openssh rsync \
|
||||
wireguard-tools systemd-resolvconf \
|
||||
pacman-contrib bash-completion vim
|
||||
|
||||
genfstab -U -p /mnt >> /mnt/etc/fstab
|
||||
grep -q 'UUID' /mnt/etc/fstab || die
|
||||
|
||||
# Make custom directories
|
||||
mkdir -p /mnt/etc/pacman.d/hooks /mnt/usr/bin/local
|
||||
|
||||
# pacman.conf hook
|
||||
install /dev/stdin /mnt/usr/bin/local/hook-pacman.conf <<hook
|
||||
#!/usr/bin/env bash
|
||||
if [ -f /etc/pacman.conf.pacnew ]
|
||||
then
|
||||
sed -i \\
|
||||
-e '/Color/c\Color' \\
|
||||
-e '/ParallelDownloads/c\ParallelDownloads = 10' \\
|
||||
-e 's#^\[core\]$\|^\[extra\]\$#&\\
|
||||
CacheServer = http://192.168.122.1:9090#' /etc/pacman.conf.pacnew
|
||||
mv /etc/pacman.conf.pacnew /etc/pacman.conf
|
||||
fi
|
||||
hook
|
||||
|
||||
cat >/mnt/etc/pacman.d/hooks/pacman.conf.hook <<pacman
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = pacman
|
||||
|
||||
[Action]
|
||||
Description = Fixing pacman.conf
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/local/hook-pacman.conf
|
||||
pacman
|
||||
sed -i \
|
||||
-e '/Color/c\Color' \
|
||||
-e '/ParallelDownloads/c\ParallelDownloads = 10' \
|
||||
-e 's#^\[core\]$\|^\[extra\]$#&\
|
||||
CacheServer = http://192.168.122.1:9090#' \
|
||||
/mnt/etc/pacman.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
|
||||
rm /mnt/usr/share/mkinitcpio/hook.preset
|
||||
rsync -a /mnt/usr/lib/modules/*/vmlinuz /mnt/boot/vmlinuz-linux
|
||||
|
||||
# mkinitcpio preset hook
|
||||
cat >/mnt/etc/pacman.d/hooks/linux.preset.hook <<preset
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = mkinitcpio
|
||||
|
||||
[Action]
|
||||
Description = Updating mkinitcpio linux preset
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/local/hook-linux.preset
|
||||
preset
|
||||
install /dev/stdin /mnt/usr/bin/local/hook-linux.preset <<'hook'
|
||||
#!/usr/bin/env bash
|
||||
if [ -f /usr/share/mkinitcpio/hook.preset ]
|
||||
then
|
||||
sed \
|
||||
-e "s|%PKGBASE%|linux|g" \
|
||||
-e "s/^fallback/#&/g" \
|
||||
-e "s/ 'fallback'//" \
|
||||
/usr/share/mkinitcpio/hook.preset >/etc/mkinitcpio.d/linux.preset
|
||||
rm /usr/share/mkinitcpio/hook.preset
|
||||
fi
|
||||
hook
|
||||
|
||||
arch-chroot /mnt mkinitcpio -P
|
||||
|
||||
# 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
|
||||
|
||||
arch-chroot /mnt /bin/bash <<"SYU"
|
||||
# Install bootloader
|
||||
echo
|
||||
bootLoader
|
||||
echo
|
||||
|
||||
# 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 /usr/share/zoneinfo/UTC /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 /bin/bash user || die
|
||||
if [ ${userpass} ]
|
||||
then
|
||||
printf '%s\n' ${userpass} ${userpass} | passwd user &>/dev/null
|
||||
echo '%wheel ALL=(ALL:ALL) ALL' > /etc/sudoers.d/wheel
|
||||
else
|
||||
echo -e '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel
|
||||
mkdir -p /etc/systemd/system/getty@tty1.service.d
|
||||
echo '[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/usr/bin/agetty --autologin user --noclear %I $TERM' > /etc/systemd/system/getty@tty1.service.d/override.conf
|
||||
fi
|
||||
if [ "$rootpass" ]
|
||||
then
|
||||
printf '%s\n' "$rootpass" "$rootpass" | passwd &>/dev/null
|
||||
fi
|
||||
say "Configured superuser and user" yellow bold
|
||||
echo
|
||||
|
||||
# Sysctl custom settings
|
||||
echo -e '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' > /etc/sysctl.d/99-sysctl.conf
|
||||
|
||||
# iptables
|
||||
install /dev/stdin /usr/bin/local/iptables.hook <<IPTABLES
|
||||
#!/usr/bin/env bash
|
||||
|
||||
iptables -N TCP
|
||||
iptables -N UDP
|
||||
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
iptables -P INPUT DROP
|
||||
|
||||
iptables -A INPUT -s 192.168.122.0/24 -j ACCEPT
|
||||
|
||||
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
|
||||
iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
|
||||
iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
|
||||
iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
|
||||
iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
|
||||
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
|
||||
iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
|
||||
|
||||
iptables-save -f \${1}
|
||||
IPTABLES
|
||||
/usr/bin/local/iptables.hook /etc/iptables/iptables.rules
|
||||
|
||||
# iptables hook
|
||||
install /dev/stdin /usr/bin/local/hook-iptables.rules <<hook
|
||||
#!/usr/bin/env bash
|
||||
if [ -f /etc/iptables/iptables.rules.pacnew ]
|
||||
then
|
||||
/usr/bin/local/iptables.hook /etc/iptables/iptables.rules.pacnew
|
||||
mv /etc/iptables/iptables.rules.pacnew /etc/iptables/iptables.rules
|
||||
fi
|
||||
hook
|
||||
cat >/etc/pacman.d/hooks/iptables.rules.hook <<iptables
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = iptables*
|
||||
|
||||
[Action]
|
||||
Description = Fixing iptables rules
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/local/hook-iptables.rules
|
||||
iptables
|
||||
|
||||
# Paccache hook
|
||||
cat >/etc/pacman.d/hooks/paccache.hook <<'paccache'
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Operation = Install
|
||||
Operation = Remove
|
||||
Type = Package
|
||||
Target = *
|
||||
|
||||
[Action]
|
||||
Description = Cleaning pacman cache...
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/paccache -r
|
||||
paccache
|
||||
|
||||
# locale.gen.pacnew hook
|
||||
install /dev/stdin /usr/bin/local/hook-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/localegen.hook <<localegen
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = glibc
|
||||
|
||||
[Action]
|
||||
Description = Fixing locale.gen
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/local/hook-localegen
|
||||
localegen
|
||||
|
||||
# ssh
|
||||
cat >/etc/ssh/sshd_config.d/10-sshd.conf <<sshd
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
AuthenticationMethods publickey
|
||||
Protocol 2
|
||||
sshd
|
||||
cat >/etc/ssh/ssh_config.d/10-global.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
|
||||
|
||||
# Custom pacman wrapper
|
||||
install /dev/stdin /usr/local/bin/syu <<syu
|
||||
#!/usr/bin/env bash
|
||||
|
||||
sudo curl --fail -s -L wdas.sh/mirrorlist -o /etc/pacman.d/mirrorlist
|
||||
|
||||
if checkupdates | grep -q 'archlinux-keyring'
|
||||
then
|
||||
sudo pacman -Sy --noconfirm archlinux-keyring
|
||||
echo
|
||||
fi
|
||||
if sudo pacman -Syu --noconfirm
|
||||
then
|
||||
echo
|
||||
sudo pacdiff
|
||||
fi
|
||||
syu
|
||||
|
||||
# System services
|
||||
systemctl -q enable systemd-networkd.service systemd-resolved.service sshd.service iptables.service qemu-guest-agent.service ${systemdbootservice}
|
||||
|
||||
su user <<"CHANGEUSER"
|
||||
# SSH
|
||||
ssh-keygen -t ed25519 -q -f ~/.ssh/id_ed25519 -P ""
|
||||
echo "${sshkeys[@]}" > ~/.ssh/authorized_keys
|
||||
|
||||
# bash
|
||||
# cp /etc/skel/.bash* ~/
|
||||
|
||||
cat >> ~/.bashrc <<'BASHRC'
|
||||
|
||||
unset HISTFILE
|
||||
|
||||
alias ll='ls -l -a -h'
|
||||
|
||||
# Grep color
|
||||
alias grep='grep --color=auto'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
|
||||
# Adjust terminal upon window resize
|
||||
shopt -s checkwinsize
|
||||
|
||||
# Auto cd into directory
|
||||
shopt -s autocd
|
||||
|
||||
# Ignore duplicate and whitespace history entries
|
||||
export HISTCONTROL=ignoreboth
|
||||
|
||||
#
|
||||
# ~/.bash_aliases
|
||||
#
|
||||
|
||||
# Reboot and poweroff
|
||||
alias poweroff='sudo poweroff'
|
||||
alias reboot='sudo reboot'
|
||||
|
||||
# Miscellanous pacman
|
||||
alias orphans='pacman -Rcns $(pacman -Qtdq)'
|
||||
alias unlockpacmandb='rm /var/lib/pacman/db.lck && pacman -Syy'
|
||||
|
||||
# Rsync
|
||||
alias rsync='rsync --progress --info=progress2 -v -h'
|
||||
|
||||
#
|
||||
# ~/.bash_functions
|
||||
#
|
||||
|
||||
# Pacman tools
|
||||
function installer
|
||||
{
|
||||
sudo pacman -S "$@"
|
||||
echo
|
||||
}
|
||||
|
||||
function uninstall
|
||||
{
|
||||
sudo pacman -Rcns "$@"
|
||||
echo
|
||||
}
|
||||
|
||||
function syur
|
||||
{
|
||||
/usr/local/bin/syu &&
|
||||
reboot
|
||||
}
|
||||
|
||||
function syup
|
||||
{
|
||||
/usr/local/bin/syu &&
|
||||
poweroff
|
||||
}
|
||||
|
||||
# Update configs
|
||||
function update-bash
|
||||
{
|
||||
vim ~/.bashrc &&
|
||||
source ~/.bashrc
|
||||
}
|
||||
|
||||
BASHRC
|
||||
CHANGEUSER
|
||||
SYU
|
||||
|
||||
# Script for installing desktop environment
|
||||
install /dev/stdin /mnt/usr/local/bin/desktop <<'DESKTOPINSTALL'
|
||||
#!/usr/bin/env bash
|
||||
set -a -E
|
||||
|
||||
# Exit function
|
||||
trap '[ "$?" -ne 77 ] || exit 77' ERR
|
||||
die()
|
||||
{
|
||||
echo -e '\e[1;31m\nError encountered, script aborted...\n\e[0m'
|
||||
exit 77
|
||||
}
|
||||
|
||||
# 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
|
||||
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'
|
||||
die
|
||||
fi
|
||||
|
||||
echo -e '\n\e[1;35mSelect a desktop\e[0m'
|
||||
echo -e '\t1) i3'
|
||||
echo -e '\t2) none'
|
||||
until [[ ${desktop} = [12] ]]
|
||||
do
|
||||
read -n 1 -p '> ' desktop
|
||||
[[ ${desktop} = [12] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 2\e[0m'
|
||||
done
|
||||
|
||||
# Assign DE variables
|
||||
case ${desktop} in
|
||||
1)
|
||||
# Install and configure x
|
||||
echo -e '\n\n\t\e[1mYou have chosen \e[32mi3\e[0m\e[1m desktop\e[0m'
|
||||
echo -e '\n\e[1;35mInstalling base packages\e[0m'
|
||||
sudo pacman -S --noconfirm spice-vdagent xf86-video-qxl xorg xorg-xinit phonon-qt5-gstreamer ttf-dejavu ttf-liberation noto-fonts noto-fonts-cjk noto-fonts-emoji firefox i3-gaps i3status i3lock dmenu lightdm lightdm-gtk-greeter pavucontrol konsole kate dolphin kompare breeze-icons
|
||||
echo
|
||||
echo 'exec i3' > ~/.xinitrc
|
||||
echo -e '\nXDG_CURRENT_DESKTOP=gnome' | sudo tee -a /etc/environment >/dev/null
|
||||
|
||||
# i3
|
||||
mkdir -p ~/.config/i3
|
||||
curl -s -L https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
||||
tee -a ~/.config/i3/config >/dev/null <<'I3CONFIG'
|
||||
|
||||
exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080
|
||||
|
||||
gaps inner 8
|
||||
gaps outer 4
|
||||
|
||||
# for_window [class="^.*"] border pixel 2
|
||||
|
||||
exec spice-vdagent
|
||||
I3CONFIG
|
||||
# i3 function
|
||||
echo -e '\n# i3 config
|
||||
function i3-config
|
||||
{
|
||||
vim ~/.config/i3/config
|
||||
}' >> ~/.bash_functions
|
||||
cat >> ~/.bashrc <<'BASHRC'
|
||||
|
||||
# Autostart i3
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||
then
|
||||
exec startx
|
||||
fi
|
||||
BASHRC
|
||||
;;
|
||||
2) echo
|
||||
;;
|
||||
esac
|
||||
|
||||
sudo rm -f ${0}
|
||||
|
||||
case ${desktop} in
|
||||
1)
|
||||
echo -e '\e[1;34mDesktop installed, press any key to load i3\e[5m...\e[0m\n'
|
||||
read -n 1 -s
|
||||
sudo systemctl -q enable --now lightdm.service
|
||||
;;
|
||||
2)
|
||||
echo -e '\e[1;34mSetup complete, press any key to continue\e[5m...\e[0m\n'
|
||||
read -n 1 -s
|
||||
;;
|
||||
*)
|
||||
die
|
||||
;;
|
||||
esac
|
||||
DESKTOPINSTALL
|
||||
|
||||
# Reboot only if script succeeded
|
||||
if /usr/bin/sh -c 'arch-chroot /mnt uname -a' | grep -q Linux
|
||||
then
|
||||
umount -R /mnt
|
||||
echo -e '\e[1;34mInstaller has completed and system drive has been unmounted'
|
||||
echo -e 'Boot into the new system, connect to a network and install a DE by running \e[35mdesktop\e[34m in the terminal'
|
||||
echo -e 'Rebooting...\n\e[0m'
|
||||
reboot
|
||||
else
|
||||
die
|
||||
fi
|
||||
139
pkg/homelab
Normal file
139
pkg/homelab
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
amd-ucode
|
||||
apache
|
||||
apcupsd
|
||||
archiso
|
||||
ark
|
||||
base
|
||||
bash-completion
|
||||
bemenu
|
||||
bemenu-wayland
|
||||
bluez
|
||||
bluez-utils
|
||||
breeze-icons
|
||||
bridge-utils
|
||||
brightnessctl
|
||||
btrfs-progs
|
||||
certbot
|
||||
certbot-nginx
|
||||
chromium
|
||||
core/linux
|
||||
dbus-broker-units
|
||||
dmenu
|
||||
dmidecode
|
||||
dnsmasq
|
||||
docker
|
||||
docker-buildx
|
||||
docker-compose
|
||||
dolphin
|
||||
dosfstools
|
||||
edk2-ovmf
|
||||
efibootmgr
|
||||
exfatprogs
|
||||
fail2ban
|
||||
fakeroot
|
||||
feh
|
||||
ffmpegthumbs
|
||||
filezilla
|
||||
firefox
|
||||
firefox-decentraleyes
|
||||
firefox-ublock-origin
|
||||
foot
|
||||
git
|
||||
gnome
|
||||
gnome-keyring
|
||||
grub
|
||||
grub-btrfs
|
||||
i3lock
|
||||
i3status
|
||||
i3-wm
|
||||
inetutils
|
||||
inotify-tools
|
||||
intel-ucode
|
||||
iptables-nft
|
||||
iwd
|
||||
jdk-openjdk
|
||||
jre-openjdk
|
||||
kate
|
||||
kcalc
|
||||
kde-cli-tools
|
||||
keepassxc
|
||||
kfind
|
||||
kompare
|
||||
konsole
|
||||
libreoffice-fresh
|
||||
libvncserver
|
||||
lightdm
|
||||
lightdm-gtk-greeter
|
||||
linux-firmware
|
||||
man-db
|
||||
mkinitcpio
|
||||
mkinitcpio-netconf
|
||||
mkinitcpio-tinyssh
|
||||
mpv
|
||||
networkmanager
|
||||
nextcloud-client
|
||||
nginx-mainline
|
||||
noto-fonts-cjk
|
||||
ntfs-3g
|
||||
nvidia-open
|
||||
nvidia-settings
|
||||
okular
|
||||
openbsd-netcat
|
||||
opendoas
|
||||
openssh
|
||||
pacman-contrib
|
||||
pam-u2f
|
||||
parted
|
||||
pavucontrol
|
||||
pipewire
|
||||
pipewire-audio
|
||||
pipewire-jack
|
||||
pipewire-pulse
|
||||
plasma
|
||||
pv
|
||||
qemu-desktop
|
||||
qemu-guest-agent
|
||||
reflector
|
||||
remmina
|
||||
rsync
|
||||
seatd
|
||||
shotwell
|
||||
smartmontools
|
||||
snap-pac
|
||||
snapper
|
||||
spice-vdagent
|
||||
sshfs
|
||||
sudo
|
||||
sudo-rs
|
||||
sway
|
||||
swaybg
|
||||
swayidle
|
||||
swaylock
|
||||
syslinux
|
||||
systemd-resolvconf
|
||||
thunderbird
|
||||
tinyssh
|
||||
torbrowser-launcher
|
||||
ttf-dejavu
|
||||
vde2
|
||||
veracrypt
|
||||
vim
|
||||
virt-manager
|
||||
virtualbox
|
||||
virtualbox-guest-iso
|
||||
virtualbox-guest-utils
|
||||
virtualbox-host-modules-arch
|
||||
wayland
|
||||
wayvnc
|
||||
wireguard-tools
|
||||
wireplumber
|
||||
wmctrl
|
||||
xf86-video-qxl
|
||||
xfce4
|
||||
xorg
|
||||
xorg-xinit
|
||||
yubico-pam
|
||||
yubikey-full-disk-encryption
|
||||
yubikey-personalization
|
||||
zfs-linux
|
||||
zfs-utils
|
||||
43
pkg/qemu
Normal file
43
pkg/qemu
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
base
|
||||
bash-completion
|
||||
breeze-icons
|
||||
btrfs-progs
|
||||
chromium
|
||||
dmenu
|
||||
dolphin
|
||||
ffmpegthumbs
|
||||
firefox
|
||||
firefox-decentraleyes
|
||||
firefox-ublock-origin
|
||||
git
|
||||
i3lock
|
||||
i3status
|
||||
i3-wm
|
||||
kate
|
||||
kfind
|
||||
kompare
|
||||
konsole
|
||||
linux
|
||||
mkinitcpio
|
||||
opendoas
|
||||
openssh
|
||||
pacman-contrib
|
||||
pavucontrol
|
||||
pipewire
|
||||
pipewire-jack
|
||||
qemu-guest-agent
|
||||
reflector
|
||||
rsync
|
||||
spice-vdagent
|
||||
sudo
|
||||
sudo-rs
|
||||
syslinux
|
||||
systemd-resolvconf
|
||||
ttf-dejavu
|
||||
vim
|
||||
virtualbox-guest-utils
|
||||
wireguard-tools
|
||||
wireplumber
|
||||
xf86-video-qxl
|
||||
xorg
|
||||
xorg-xinit
|
||||
347
recover.sh
Executable file
347
recover.sh
Executable file
|
|
@ -0,0 +1,347 @@
|
|||
#!/usr/bin/env bash
|
||||
set -a -E
|
||||
|
||||
# Exit function
|
||||
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||
function die
|
||||
{
|
||||
echo -e '\n\e[1;31mError encountered, script aborted...\e[0m\n'
|
||||
exit 77
|
||||
}
|
||||
|
||||
# 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
|
||||
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
echo -e '\e[3m## rev '${revision}'\e[0m\n'
|
||||
echo -e '\t\e[1;4;34mArch Linux Recovery\e[0m\n\n'
|
||||
echo -e '\e[1mSelect a system configuration from the options below\e[0m\n'
|
||||
echo -e '\t1) Basic'
|
||||
echo -e '\t2) Full Disk LUKS Encryption with EFISTUB'
|
||||
echo -e '\t3) Full Disk LUKS Encryption with Secured GRUB'
|
||||
echo -e '\t4) Yubikey Full Disk Encryption with EFISTUB'
|
||||
echo -e '\t5) Yubikey Full Disk Encryption with Secured GRUB'
|
||||
|
||||
if ls -l /dev/disk/* | grep -q 'virtio\|QEMU'
|
||||
then
|
||||
echo
|
||||
until [[ ${arch} = [1-5] ]]
|
||||
do
|
||||
read -n 1 -p '> ' arch
|
||||
[[ ${arch} = [1-5] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 5\e[0m'
|
||||
done
|
||||
else
|
||||
echo -e '\t6) Full Disk Encryption with Detached LUKS Header and Secured GRUB'
|
||||
echo -e '\t7) Yubikey Encrypted Detached LUKS Header with Secured GRUB\n'
|
||||
until [[ ${arch} = [1-7] ]]
|
||||
do
|
||||
read -n 1 -p '> ' arch
|
||||
[[ ${arch} = [1-7] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 7\e[0m'
|
||||
done
|
||||
fi
|
||||
|
||||
# Prevent continuing unless yubikey is detected, only applies to yubikey setups
|
||||
if [[ ${arch} = [457] ]] && ! dmesg | grep -q -i YubiKey
|
||||
then
|
||||
echo -e '\n\n\e[1mYubikey not detected'
|
||||
echo -e 'Insert one to continue\e[5m...\e[0m'
|
||||
until dmesg | grep -q -i YubiKey
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Installation drive
|
||||
echo -e '\n\n\e[1;36mIdentify the system drive from the list of available devices below\e[0m'
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
echo -e '\e[3m## SSD and HDD device format begins with "sd" or "hd" (sda, sdb, sd[*])'
|
||||
echo -e '## NVME and PCI device format is "nvme[*]n1" (nvme0n1, nvme1n1, nvme[*]n1)\e[0m'
|
||||
while true
|
||||
do
|
||||
read -r -p 'Installation device: ' installation_disk
|
||||
lsblk -o name | grep -q -w ${installation_disk} && [ ${installation_disk} ] && break
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
[ -z ${installation_disk} ] && echo -e '\e[1;31mField cannot be empty, try again\e[0m' ||
|
||||
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||
done
|
||||
echo -e '\n\e[1mInstallation drive set as \e[32m/dev/'${installation_disk}'\e[0m'
|
||||
echo
|
||||
|
||||
# Detached boot drive
|
||||
if [[ ${arch} = [67] ]]
|
||||
then
|
||||
echo -e '\e[1;34mIdentify the removable boot drive from the list of available devices below\e[0m'
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||
echo -e '\e[3m## Removable drives usually begin with "sd" (sda, sdb, sd[*])\e[0m'
|
||||
while true
|
||||
do
|
||||
read -r -p 'Removable boot device: ' external_boot_disk
|
||||
lsblk -o name | grep -v ${installation_disk} | grep -q -w ${external_boot_disk} && [ ${external_boot_disk} ] && break
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||
if [ -z ${external_boot_disk} ]
|
||||
then
|
||||
echo -e '\e[1;31mField cannot be empty, try again\e[0m'
|
||||
elif [ ${external_boot_disk} = ${installation_disk} ]
|
||||
then
|
||||
echo -e '\e[1;31mBoot drive cannot be the same as the system drive, try again\e[0m'
|
||||
else
|
||||
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||
fi
|
||||
done
|
||||
echo -e '\n\e[1mDetached boot drive set as \e[32m/dev/'${external_boot_disk}'\e[0m'
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ ${arch} = [457] ]]
|
||||
then
|
||||
until [[ ${decrypt_root} = [yYnN] ]]
|
||||
do
|
||||
read -n 1 -p $'\n\e[1mDoes the yubikey automatically decrypt root upon boot (1FA)? (y/n): \e[0m' decrypt_root
|
||||
[[ ${decrypt_root} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
done
|
||||
echo
|
||||
fi
|
||||
|
||||
# Functions
|
||||
function decryptRootLuks
|
||||
{
|
||||
while true
|
||||
do
|
||||
unset lukspass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||
until [ ${lukspass} ]
|
||||
do
|
||||
read -s -r -p 'Encryption password: ' lukspass
|
||||
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}'\e[0m'
|
||||
if printf '%s' "${lukspass}" | cryptsetup open -v ${rootpart} cryptroot ${luks_header}
|
||||
then
|
||||
unset lukspass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function decryptRootYubikey
|
||||
{
|
||||
echo
|
||||
yes | pacman -Sy &>/dev/null
|
||||
|
||||
for package in yubikey-personalization yubikey-full-disk-encryption
|
||||
do
|
||||
if ! pacman -Q | grep -q -w ${package}
|
||||
then
|
||||
missing_yubikey_req+=(${package})
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${missing_yubikey_req} ]
|
||||
then
|
||||
yes | pacman -Sy ${missing_yubikey_req[@]}
|
||||
unset missing_yubikey_req
|
||||
echo
|
||||
fi
|
||||
|
||||
# # Custom challenge slot
|
||||
# sed -i '/YKFDE_CHALLENGE_SLOT/c\YKFDE_CHALLENGE_SLOT="1"' /etc/ykfde.conf
|
||||
|
||||
while true
|
||||
do
|
||||
unset lukspass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||
until [ ${lukspass} ]
|
||||
do
|
||||
read -s -r -p 'Encryption password: ' lukspass
|
||||
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
if [[ ${decrypt_root} = [yY] ]]
|
||||
then
|
||||
sed -i '/YKFDE_CHALLENGE=/c\YKFDE_CHALLENGE="'"$(printf '%q' ${lukspass})"'"' /etc/ykfde.conf
|
||||
fi
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}' with yubikey HMAC encryption\e[0m'
|
||||
if printf '%s\n' "${lukspass}" | ykfde-open -d ${rootpart} -n cryptroot -- ${luks_header}
|
||||
then
|
||||
unset lukspass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function decryptBootLuks
|
||||
{
|
||||
while true
|
||||
do
|
||||
unset grubpass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the bootloader\e[0m'
|
||||
until [ ${grubpass} ]
|
||||
do
|
||||
read -s -r -p 'Bootloader password: ' grubpass
|
||||
[ ${grubpass} ] || echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt bootloader...\e[0m'
|
||||
if printf '%s' "${grubpass}" | cryptsetup open ${bootpart} cryptboot
|
||||
then
|
||||
unset grubpass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function configureVolumes
|
||||
{
|
||||
echo -e '\n\e[1;36mMounting volumes\e[0m'
|
||||
|
||||
case $(blkid -s TYPE -o value ${rootvol}) in
|
||||
zfs_member)
|
||||
if ! zpool list | grep -q zroot
|
||||
then
|
||||
zpool import -R /mnt zroot -N -d ${rootvol}
|
||||
fi
|
||||
zfs mount zroot/ROOT
|
||||
zfs mount -a
|
||||
;;
|
||||
btrfs)
|
||||
mount ${rootvol} /mnt
|
||||
;;
|
||||
ext4)
|
||||
mount ${rootvol} /mnt
|
||||
mount ${bootvol} /mnt/boot
|
||||
if [[ ${arch} = [3567] ]]
|
||||
then
|
||||
mount ${efivol} /mnt/boot/efi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Grab disk-id of ${drive}
|
||||
installation_disk_id=$(ls -l /dev/disk/by-id/* | grep "${installation_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX' | awk '{print $9}' | head -1)
|
||||
external_boot_disk_id=$(ls -l /dev/disk/by-id/* | grep "${external_boot_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX\|usb' | awk '{print $9}' | head -1)
|
||||
|
||||
# System configurations
|
||||
case ${arch} in
|
||||
1) # Basic
|
||||
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||
export {rootpart,rootvol}=${installation_disk_id}-part2
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
2|4) # FDE with EFISTUB
|
||||
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||
rootpart=${installation_disk_id}-part2
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
|
||||
case ${arch} in
|
||||
2)
|
||||
if [[ $(blkid -s TYPE -o value ${rootpart}) = "zfs_member" ]]
|
||||
then
|
||||
zpool import -R /mnt zroot -N -d ${rootpart}
|
||||
printf '%s' "${lukspass}" | zfs load-key zroot
|
||||
else
|
||||
decryptRootLuks
|
||||
fi
|
||||
;;
|
||||
4) decryptRootYubikey;;
|
||||
esac
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
3|5) # FDE with Secured GRUB
|
||||
efivol=${installation_disk_id}-part1
|
||||
bootpart=${installation_disk_id}-part2
|
||||
rootpart=${installation_disk_id}-part3
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
bootvol=/dev/mapper/cryptboot
|
||||
|
||||
case ${arch} in
|
||||
3) decryptRootLuks;;
|
||||
5) decryptRootYubikey;;
|
||||
esac
|
||||
|
||||
decryptBootLuks
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
6|7) # FDE with detached luks header
|
||||
efivol=${external_boot_disk_id}-part1
|
||||
bootpart=${external_boot_disk_id}-part2
|
||||
rootpart=${installation_disk_id}
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
bootvol=/dev/mapper/cryptboot
|
||||
luks_header='--header /mnt/header.img'
|
||||
|
||||
decryptBootLuks
|
||||
mount /dev/mapper/cryptboot /mnt
|
||||
case ${arch} in
|
||||
6) decryptRootLuks;;
|
||||
7) decryptRootYubikey;;
|
||||
esac
|
||||
umount /mnt
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
echo -e '\e[1;92mSystem successfully mounted...\e[0m\n'
|
||||
|
||||
if [[ $(blkid -s TYPE -o value ${rootvol}) = "btrfs" ]]
|
||||
then
|
||||
install /dev/stdin /usr/local/bin/btrfs-mount <<- BTRFSSU
|
||||
#!/usr/bin/env bash
|
||||
btrfsopts=$(awk '$2=="/"' /mnt/etc/fstab | awk '{print $4}' | sed 's/,subvol=.*//')
|
||||
umount -R /mnt
|
||||
echo
|
||||
|
||||
# Mount @root subvolume
|
||||
mount -o ${btrfsopts},subvol=@ ${rootvol} /mnt
|
||||
|
||||
# Mount all subvolumes
|
||||
arch-chroot /mnt mount --all
|
||||
lsblk
|
||||
echo -e '\n\t\e[1;92mBtrfs subvolumes successful mounted!\e[0m\n'
|
||||
BTRFSSU
|
||||
|
||||
echo -e '\e[1mRun \e[92mbtrfs-mount\e[0m\e[1m to mount all the btrfs subvolumes\e[0m\n'
|
||||
fi
|
||||
|
||||
if [[ ${arch} = [3567] ]]
|
||||
then
|
||||
install /dev/stdin /usr/local/bin/re-grub <<REGRUB
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if findmnt '/mnt/boot/efi' | grep -q "${efivol}" && findmnt '/mnt/boot' | grep -q "${bootvol}"
|
||||
then
|
||||
arch-chroot /mnt /bin/bash <<'GRUB'
|
||||
grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi --recheck
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
echo -e '\n\t\e[1;92mGrub successfuly re-installed!\e[0m\n'
|
||||
GRUB
|
||||
else
|
||||
echo -e '\n\t\e[1;31mEFI partition not mounted, try again\e[0m\n'
|
||||
fi
|
||||
REGRUB
|
||||
|
||||
echo -e '\e[1mRun \e[92mre-grub\e[0m\e[1m to regenerate grub\e[0m\n'
|
||||
fi
|
||||
912
virtual-machine.sh
Executable file
912
virtual-machine.sh
Executable file
|
|
@ -0,0 +1,912 @@
|
|||
#!/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
|
||||
curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/mirrorlist -o /etc/pacman.d/mirrorlist || die "Unable to fetch latest mirrorlist"
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue