#!/bin/sh # ============================================================================ # # ██╗ █████╗ ███████╗██╗ ██╗██╗ ██╗██████╗ ██╗███████╗ Z # ██║ ██╔══██╗╚══███╔╝╚██╗ ██╔╝██║ ██╔╝██╔══██╗██║██╔════╝ Z # ██║ ███████║ ███╔╝ ╚████╔╝ █████╔╝ ██████╔╝██║███████╗ z # ██║ ██╔══██║ ███╔╝ ╚██╔╝ ██╔═██╗ ██╔══██╗██║╚════██║ z # ███████╗██║ ██║███████╗ ██║ ██║ ██╗██║ ██║██║███████║ # ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝ # # sdeploy - Kris's Auto Rice Bootstrapping Scripts # "The only way to do great work is to automate the boring parts." # # System: Wired (Artix OpenRC pentesting workstation) # Author: Kris Yotam # Contact: kris@krisyotam.com # License: GPL-3.0-only # Repository: https://git.sr.ht/~krisyotam/sdeploy # ============================================================================ ### OPTIONS AND VARIABLES ### dotfilesrepo="https://git.sr.ht/~krisyotam/srice" progsfile="https://git.sr.ht/~krisyotam/sdeploy/blob/main/system/sd-wired/progs.csv" aurhelper="yay" repobranch="main" blackarchstrap="https://blackarch.org/strap.sh" export TERM=ansi ### FUNCTIONS ### installpkg() { pacman --noconfirm --needed -S "$1" >/dev/null 2>&1 } error() { printf "%s\n" "$1" >&2 exit 1 } welcomemsg() { whiptail --title "Wired Deploy" \ --msgbox "This script bootstraps an Artix OpenRC pentesting workstation with dwm, srice dotfiles, and BlackArch tools.\n\n-Kris" 10 60 whiptail --title "Preflight" --yes-button "Ready" \ --no-button "Cancel" \ --yesno "Ensure:\n\n1. Running as root\n2. Pacman is synced\n3. Keyrings are current\n4. Internet is up" 12 60 } getuserandpass() { name=$(whiptail --inputbox "Enter a username for the account." 10 60 3>&1 1>&2 2>&3 3>&1) || exit 1 while ! echo "$name" | grep -q "^[a-z_][a-z0-9_-]*$"; do name=$(whiptail --nocancel --inputbox "Invalid. Lowercase letters, digits, - or _ only." 10 60 3>&1 1>&2 2>&3 3>&1) done pass1=$(whiptail --nocancel --passwordbox "Enter a password for $name." 10 60 3>&1 1>&2 2>&3 3>&1) pass2=$(whiptail --nocancel --passwordbox "Confirm password." 10 60 3>&1 1>&2 2>&3 3>&1) while [ "$pass1" != "$pass2" ]; do unset pass2 pass1=$(whiptail --nocancel --passwordbox "Mismatch. Enter password again." 10 60 3>&1 1>&2 2>&3 3>&1) pass2=$(whiptail --nocancel --passwordbox "Confirm password." 10 60 3>&1 1>&2 2>&3 3>&1) done } usercheck() { ! { id -u "$name" >/dev/null 2>&1; } || whiptail --title "WARNING" --yes-button "CONTINUE" \ --no-button "Cancel" \ --yesno "User \`$name\` already exists. Conflicting dotfiles will be overwritten. Personal files are untouched.\n\nPassword will be changed to what you entered." 12 70 } preinstallmsg() { whiptail --title "Ready" --yes-button "Go" \ --no-button "Cancel" \ --yesno "Installation is fully automated from here. This will take a while.\n\nPress to begin." 10 60 || { clear exit 1 } } adduserandpass() { whiptail --infobox "Adding user \"$name\"..." 7 50 useradd -m -g wheel -s /bin/mksh "$name" >/dev/null 2>&1 || usermod -a -G wheel "$name" && mkdir -p /home/"$name" && chown "$name":wheel /home/"$name" export repodir="/home/$name/.local/src" mkdir -p "$repodir" chown -R "$name":wheel "$(dirname "$repodir")" echo "$name:$pass1" | chpasswd unset pass1 pass2 } refreshkeys() { case "$(readlink -f /sbin/init)" in *systemd*) whiptail --infobox "Refreshing Arch keyring..." 7 40 pacman --noconfirm -S archlinux-keyring >/dev/null 2>&1 ;; *) whiptail --infobox "Enabling Arch repos for Artix..." 7 50 pacman --noconfirm --needed -S \ artix-keyring artix-archlinux-support >/dev/null 2>&1 grep -q "^\[extra\]" /etc/pacman.conf || echo "[extra] Include = /etc/pacman.d/mirrorlist-arch" >>/etc/pacman.conf pacman -Sy --noconfirm >/dev/null 2>&1 pacman-key --populate archlinux >/dev/null 2>&1 ;; esac } setupblackarch() { whiptail --infobox "Adding BlackArch repository..." 7 50 curl -Ls "$blackarchstrap" | sh >/dev/null 2>&1 pacman -Sy --noconfirm >/dev/null 2>&1 } manualinstall() { pacman -Qq "$1" && return 0 whiptail --infobox "Installing \"$1\" manually..." 7 50 sudo -u "$name" mkdir -p "$repodir/$1" sudo -u "$name" git -C "$repodir" clone --depth 1 --single-branch \ --no-tags -q "https://aur.archlinux.org/$1.git" "$repodir/$1" || { cd "$repodir/$1" || return 1 sudo -u "$name" git pull --force origin master } cd "$repodir/$1" || exit 1 sudo -u "$name" makepkg --noconfirm -si >/dev/null 2>&1 || return 1 } maininstall() { whiptail --title "Wired" --infobox "[$n/$total] $1 $2" 7 70 installpkg "$1" } aurinstall() { whiptail --title "Wired" --infobox "[$n/$total] (AUR) $1 $2" 7 70 echo "$aurinstalled" | grep -q "^$1$" && return 0 sudo -u "$name" $aurhelper -S --noconfirm "$1" >/dev/null 2>&1 } gitmakeinstall() { progname="${1##*/}" progname="${progname%.git}" dir="$repodir/$progname" whiptail --title "Wired" --infobox "[$n/$total] (git) $progname $2" 7 70 sudo -u "$name" git -C "$repodir" clone --depth 1 --single-branch \ --no-tags -q "$1" "$dir" || { cd "$dir" || return 1 sudo -u "$name" git pull --force origin master } cd "$dir" || exit 1 make >/dev/null 2>&1 make install >/dev/null 2>&1 cd /tmp || return 1 } installationloop() { ([ -f "$progsfile" ] && cp "$progsfile" /tmp/progs.csv) || curl -Ls "$progsfile" | sed '/^#/d' >/tmp/progs.csv total=$(wc -l /dev/null 2>&1 # Create user adduserandpass || error "Error creating user." [ -f /etc/sudoers.pacnew ] && cp /etc/sudoers.pacnew /etc/sudoers # Temp passwordless sudo for builds trap 'rm -f /etc/sudoers.d/wired-temp' HUP INT QUIT TERM PWR EXIT echo "%wheel ALL=(ALL) NOPASSWD: ALL Defaults:%wheel,root runcwd=*" >/etc/sudoers.d/wired-temp # Pacman tweaks grep -q "ILoveCandy" /etc/pacman.conf || sed -i "/#VerbosePkgLists/a ILoveCandy" /etc/pacman.conf sed -Ei "s/^#(ParallelDownloads).*/\1 = 5/;/^#Color$/s/#//" /etc/pacman.conf # Use all cores for compilation sed -i "s/-j2/-j$(nproc)/;/^#MAKEFLAGS/s/^#//" /etc/makepkg.conf # AUR helper manualinstall "$aurhelper" || error "Failed to install AUR helper." $aurhelper -Y --save --devel # BlackArch repo setupblackarch || error "Failed to add BlackArch repo." # Install everything from progs.csv installationloop # Deploy dotfiles putgitrepo "$dotfilesrepo" "/home/$name" # Kill the beep rmmod pcspkr 2>/dev/null echo "blacklist pcspkr" >/etc/modprobe.d/nobeep.conf # mksh as default interactive shell chsh -s /bin/mksh "$name" >/dev/null 2>&1 # Home directory scaffold for d in downloads src slipbox mail pix vids; do sudo -u "$name" mkdir -p "/home/$name/$d" done sudo -u "$name" mkdir -p "/home/$name/.config/abook" sudo -u "$name" mkdir -p "/home/$name/.config/mpd/playlists" # Clone repos whiptail --infobox "Cloning slipbox..." 7 50 sudo -u "$name" git clone --depth 1 -q \ "https://git.sr.ht/~krisyotam/slipbox" "/home/$name/slipbox" >/dev/null 2>&1 || true whiptail --infobox "Cloning ctfs..." 7 50 sudo -u "$name" git clone --depth 1 -q \ "https://git.sr.ht/~krisyotam/ctfs" "/home/$name/ctfs" >/dev/null 2>&1 || true # Dash as /bin/sh ln -sfT /bin/dash /bin/sh >/dev/null 2>&1 # dbus UUID for Artix dbus-uuidgen >/var/lib/dbus/machine-id # dbus-launch for non-systemd session [ "$(readlink -f /sbin/init)" != "/usr/lib/systemd/systemd" ] && echo "export \$(dbus-launch)" >/etc/profile.d/dbus.sh # Tap to click [ ! -f /etc/X11/xorg.conf.d/40-libinput.conf ] && printf 'Section "InputClass" Identifier "libinput touchpad catchall" MatchIsTouchpad "on" MatchDevicePath "/dev/input/event*" Driver "libinput" Option "Tapping" "on" EndSection' >/etc/X11/xorg.conf.d/40-libinput.conf # Sudoers echo "%wheel ALL=(ALL:ALL) ALL" >/etc/sudoers.d/00-wheel-can-sudo echo "%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/shutdown,/usr/bin/reboot,/usr/bin/mount,/usr/bin/umount,/usr/bin/pacman -Syu,/usr/bin/pacman -Syyu,/usr/bin/pacman -Syyu --noconfirm,/usr/bin/loadkeys,/usr/bin/pacman -Syyuw --noconfirm" >/etc/sudoers.d/01-cmds-without-password echo "Defaults editor=/usr/bin/nvim" >/etc/sudoers.d/02-visudo-editor mkdir -p /etc/sysctl.d echo "kernel.dmesg_restrict = 0" >/etc/sysctl.d/dmesg.conf # Cleanup rm -f /etc/sudoers.d/wired-temp finalize