Update install_arch_solphyr.sh
This commit is contained in:
parent
530ae7d44d
commit
f6d213900a
@ -1,6 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ────────────────────────────────────────────────────────────────
|
||||
# Solphyr Arch Linux Auto-Installer
|
||||
# Full LUKS2 encryption • systemd-boot • yay • WireGuard • Hardening
|
||||
# ────────────────────────────────────────────────────────────────
|
||||
|
||||
# Colour helpers
|
||||
b=$(tput bold); r=$(tput sgr0); g=$(tput setaf 2); y=$(tput setaf 3); c=$(tput setaf 6); e=$(tput setaf 1)
|
||||
info(){ echo "${c}==>${r} $*"; }
|
||||
@ -10,63 +15,43 @@ die(){ echo "${e}x${r} $*" >&2; exit 1; }
|
||||
NO_PROMPT=0
|
||||
[[ "${1:-}" =~ (--no-prompt|--auto) ]] && NO_PROMPT=1
|
||||
|
||||
# --- Load or create .env ---
|
||||
# ── Load or create .env ─────────────────────────────────────────
|
||||
[[ ! -f .env ]] && { warn ".env missing, creating from template"; cp .env.template .env 2>/dev/null || touch .env; }
|
||||
source .env || true
|
||||
|
||||
# --- Safe prompting helpers ---
|
||||
# ── Safe prompting helpers ─────────────────────────────────────
|
||||
prompt_var() {
|
||||
local var_name="$1"
|
||||
local prompt_text="$2"
|
||||
local default_val
|
||||
default_val="$(eval "echo \${$var_name:-}")"
|
||||
if [[ "$NO_PROMPT" == "1" ]]; then
|
||||
info "Using $var_name=$default_val"
|
||||
return
|
||||
fi
|
||||
local var_name="$1" prompt_text="$2"
|
||||
local default_val; default_val="$(eval "echo \${$var_name:-}")"
|
||||
if [[ "$NO_PROMPT" == "1" ]]; then info "Using $var_name=$default_val"; return; fi
|
||||
read -e -p "$prompt_text [${default_val}]: " input
|
||||
if [[ -n "$input" ]]; then
|
||||
eval "$var_name=\"\$input\""
|
||||
fi
|
||||
[[ -n "$input" ]] && eval "$var_name=\"\$input\""
|
||||
}
|
||||
|
||||
prompt_secret() {
|
||||
local var_name="$1"
|
||||
local prompt_text="$2"
|
||||
local default_val
|
||||
default_val="$(eval "echo \${$var_name:-}")"
|
||||
if [[ -z "$default_val" ]]; then
|
||||
read -s -p "$prompt_text: " input
|
||||
echo
|
||||
eval "$var_name=\"\$input\""
|
||||
else
|
||||
info "Using $var_name from .env"
|
||||
fi
|
||||
local var_name="$1" prompt_text="$2"
|
||||
local default_val; default_val="$(eval "echo \${$var_name:-}")"
|
||||
if [[ -z "$default_val" ]]; then read -s -p "$prompt_text: " input; echo; eval "$var_name=\"\$input\""; else info "Using $var_name from .env"; fi
|
||||
}
|
||||
|
||||
save_env() {
|
||||
local var_name="$1"
|
||||
local var_value
|
||||
var_value="$(eval "echo \${$var_name}")"
|
||||
sed -i "/^${var_name}=/d" .env
|
||||
echo "${var_name}=\"${var_value}\"" >> .env
|
||||
local var_name="$1" var_value; var_value="$(eval "echo \${$var_name}")"
|
||||
sed -i "/^${var_name}=/d" .env; echo "${var_name}=\"${var_value}\"" >> .env
|
||||
}
|
||||
|
||||
# --- Gather configuration ---
|
||||
prompt_var HOSTNAME "Hostname"; prompt_var USERNAME "Username"; prompt_var KEYMAP "Keymap"
|
||||
prompt_var TIMEZONE "Timezone"; prompt_var LOCALE "Locale"
|
||||
# ── Gather configuration ────────────────────────────────────────
|
||||
prompt_var HOSTNAME "Hostname"; prompt_var USERNAME "Username"
|
||||
prompt_var KEYMAP "Keymap"; prompt_var TIMEZONE "Timezone"; prompt_var LOCALE "Locale"
|
||||
save_env HOSTNAME; save_env USERNAME; save_env KEYMAP; save_env TIMEZONE; save_env LOCALE
|
||||
|
||||
# --- Networking ---
|
||||
# ── Networking ─────────────────────────────────────────────────
|
||||
timedatectl set-ntp true
|
||||
if [[ -z "$(ip link | grep -E 'state UP')" ]]; then
|
||||
warn "No active network found"
|
||||
prompt_var WIFI_SSID "Wi-Fi SSID"; prompt_secret WIFI_PASS "Wi-Fi password"
|
||||
iwctl station wlan0 scan || true
|
||||
iwctl station wlan0 connect "$WIFI_SSID" --passphrase "$WIFI_PASS" || die "Wi-Fi connect failed"
|
||||
iwctl station wlan0 connect "$WIFI_SSID" --passphrase "$WIFI_PASS" || die "Wi-Fi connection failed"
|
||||
else info "Network detected"; fi
|
||||
|
||||
# --- Disk selection ---
|
||||
# ── Disk selection ─────────────────────────────────────────────
|
||||
if [[ -z "${DISK:-}" ]]; then
|
||||
info "Available disks:"; lsblk -dno NAME,SIZE,MODEL | grep -v loop | nl -w2 -s'. '
|
||||
[[ $NO_PROMPT == 1 ]] && die "No DISK specified in .env"
|
||||
@ -75,24 +60,25 @@ fi; save_env DISK
|
||||
EFI="${DISK}p1"; ROOT="${DISK}p2"
|
||||
read -p "${e}${b}⚠️ Erase $DISK? ENTER to confirm${r}"
|
||||
|
||||
# --- Partition + encrypt ---
|
||||
# ── Partition + encryption ─────────────────────────────────────
|
||||
sgdisk --zap-all "$DISK"
|
||||
sgdisk -n1:0:+1G -t1:ef00 -c1:"EFI System" "$DISK"
|
||||
sgdisk -n2:0:0 -t2:8300 -c2:"Linux LUKS" "$DISK"; partprobe "$DISK"
|
||||
prompt_secret LUKS_PASSWORD "LUKS password"; save_env LUKS_PASSWORD
|
||||
echo -n "$LUKS_PASSWORD" | cryptsetup luksFormat --batch-mode --type luks2 --cipher aes-xts-plain64 --key-size 512 --hash sha512 "$ROOT" -
|
||||
echo -n "$LUKS_PASSWORD" | cryptsetup luksFormat --batch-mode --type luks2 \
|
||||
--cipher aes-xts-plain64 --key-size 512 --hash sha512 "$ROOT" -
|
||||
echo -n "$LUKS_PASSWORD" | cryptsetup open "$ROOT" cryptroot -
|
||||
mkfs.fat -F32 "$EFI"; mkfs.ext4 /dev/mapper/cryptroot
|
||||
mount /dev/mapper/cryptroot /mnt; mkdir /mnt/boot; mount "$EFI" /mnt/boot
|
||||
|
||||
# --- Mirrors + base ---
|
||||
# ── Mirrors + base system ──────────────────────────────────────
|
||||
pacman -Sy --noconfirm reflector
|
||||
reflector --country "United Kingdom" --latest 20 --sort rate --save /etc/pacman.d/mirrorlist
|
||||
pacstrap -K /mnt base linux linux-firmware vim networkmanager sudo base-devel git
|
||||
|
||||
genfstab -U /mnt >> /mnt/etc/fstab
|
||||
|
||||
# --- Chroot configuration ---
|
||||
# ── System configuration inside chroot ─────────────────────────
|
||||
arch-chroot /mnt /bin/bash <<CHROOT
|
||||
set -euo pipefail
|
||||
ln -sf /usr/share/zoneinfo/$TIMEZONE /etc/localtime
|
||||
@ -112,6 +98,12 @@ sed -i 's/\(filesystems\)/encrypt \1/' /etc/mkinitcpio.conf
|
||||
mkinitcpio -P
|
||||
|
||||
bootctl install
|
||||
# Fix insecure permissions from FAT32
|
||||
chmod 600 /boot/loader/random-seed 2>/dev/null || true
|
||||
chmod 700 /boot/loader 2>/dev/null || true
|
||||
chmod 700 /boot/EFI/systemd 2>/dev/null || true
|
||||
chown -R root:root /boot /boot/EFI || true
|
||||
|
||||
UUID=\$(blkid -s UUID -o value ${ROOT})
|
||||
cat <<EOF >/boot/loader/loader.conf
|
||||
default arch.conf
|
||||
@ -120,25 +112,24 @@ console-mode max
|
||||
editor no
|
||||
EOF
|
||||
cat <<EOF >/boot/loader/entries/arch.conf
|
||||
title Arch Linux
|
||||
linux /vmlinuz-linux
|
||||
initrd /initramfs-linux.img
|
||||
title Arch Linux
|
||||
linux /vmlinuz-linux
|
||||
initrd /initramfs-linux.img
|
||||
options cryptdevice=UUID=\${UUID}:cryptroot root=/dev/mapper/cryptroot rw
|
||||
EOF
|
||||
|
||||
echo "Set root password:"; passwd
|
||||
# Create user but skip passwords (set later outside heredoc)
|
||||
useradd -m -G wheel -s /bin/bash $USERNAME
|
||||
echo "Set password for $USERNAME:"; passwd $USERNAME
|
||||
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers
|
||||
systemctl enable NetworkManager
|
||||
|
||||
# --- Optional yay ---
|
||||
# yay (AUR helper)
|
||||
if [[ "${INSTALL_YAY,,}" == "yes" ]]; then
|
||||
pacman -Sy --noconfirm base-devel git
|
||||
su - $USERNAME -c "cd /tmp && git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -si --noconfirm && rm -rf /tmp/yay"
|
||||
fi
|
||||
|
||||
# --- Optional hardening ---
|
||||
# Hardening
|
||||
if [[ "${ENABLE_HARDENING,,}" == "yes" ]]; then
|
||||
pacman -Sy --noconfirm ufw apparmor fail2ban archlinux-keyring
|
||||
systemctl enable ufw; systemctl start ufw
|
||||
@ -160,7 +151,14 @@ EOF
|
||||
fi
|
||||
CHROOT
|
||||
|
||||
# --- Optional WireGuard setup ---
|
||||
# ── Interactive password setup (outside heredoc) ───────────────
|
||||
info "Set root password"
|
||||
until arch-chroot /mnt passwd; do echo "Try again."; done
|
||||
|
||||
info "Set password for user ${USERNAME}"
|
||||
until arch-chroot /mnt passwd "${USERNAME}"; do echo "Try again."; done
|
||||
|
||||
# ── WireGuard (optional) ────────────────────────────────────────
|
||||
if [[ "${ENABLE_WIREGUARD,,}" == "yes" && -f "${WIREGUARD_CONF_PATH}" ]]; then
|
||||
info "Installing WireGuard..."
|
||||
install -Dm600 "$WIREGUARD_CONF_PATH" "/mnt/etc/wireguard/wg0.conf"
|
||||
@ -170,7 +168,9 @@ else
|
||||
warn "WireGuard skipped (no config or disabled)."
|
||||
fi
|
||||
|
||||
umount -R /mnt; cryptsetup close cryptroot
|
||||
# ── Finish ─────────────────────────────────────────────────────
|
||||
umount -R /mnt
|
||||
cryptsetup close cryptroot
|
||||
info "Installation complete"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Loading…
Reference in New Issue
Block a user