#!/bin/bash # Stage 1 base config + hardening, end to end, for a single fresh PVE host. # Runs the individual scripts in order. Idempotent - safe to re-run. # # If ADMIN_USER and ADMIN_SSH_KEY are set, a Linux system user is created # with SSH key access and sudo before SSH hardening runs - so key-based # login is in place before password auth is disabled. If they are not set, # a reminder is printed at the end to run setup-linux-admin-user.sh manually # (but do this BEFORE disconnecting, since password auth will be disabled). # # Usage: # MGMT_CIDR=192.168.2.0/24 ./bootstrap.sh # MGMT_CIDR=192.168.2.0/24 ADMIN_USER=wayne ADMIN_SSH_KEY="ssh-ed25519 ..." ./bootstrap.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=lib/common.sh source "${SCRIPT_DIR}/lib/common.sh" require_root if [ -z "${MGMT_CIDR:-}" ]; then echo "MGMT_CIDR is not set. Example: MGMT_CIDR=192.168.2.0/24 $0" >&2 exit 1 fi STEP=0 next_step() { STEP=$((STEP + 1)); echo; echo "=== ${STEP}: $* ==="; } next_step "remove enterprise repos, switch to no-subscription" "${SCRIPT_DIR}/switch-to-no-subscription-repo.sh" # Create the Linux admin user before SSH hardening so that authorized_keys # is in place before password auth is disabled. if [ -n "${ADMIN_USER:-}" ] && [ -n "${ADMIN_SSH_KEY:-}" ]; then next_step "Linux admin user '${ADMIN_USER}' + SSH key + sudo group" "${SCRIPT_DIR}/setup-linux-admin-user.sh" "$ADMIN_USER" "$ADMIN_SSH_KEY" next_step "passwordless sudo for pvesh/qm/pct (${ADMIN_USER})" "${SCRIPT_DIR}/setup-admin-sudo.sh" "$ADMIN_USER" else echo echo "WARNING: ADMIN_USER / ADMIN_SSH_KEY not set -- skipping Linux user setup." echo " Run setup-linux-admin-user.sh and setup-admin-sudo.sh BEFORE disconnecting" echo " from this session, since the next step disables password authentication." fi next_step "SSH hardening (key-only root login + fail2ban)" "${SCRIPT_DIR}/harden-ssh.sh" next_step "unattended security upgrades" "${SCRIPT_DIR}/setup-unattended-upgrades.sh" next_step "PVE firewall (mgmt-only SSH/8006)" MGMT_CIDR="$MGMT_CIDR" "${SCRIPT_DIR}/deploy-firewall.sh" next_step "disable subscription nag (cosmetic)" "${SCRIPT_DIR}/disable-subscription-nag.sh" echo echo "=== Base hardening applied. Remaining manual/deliberate steps: ===" if [ -z "${ADMIN_USER:-}" ]; then echo " - ${SCRIPT_DIR}/setup-linux-admin-user.sh " echo " - ${SCRIPT_DIR}/setup-admin-sudo.sh (NOPASSWD for pvesh/qm/pct)" fi echo " - ${SCRIPT_DIR}/create-admin-user.sh (PVE web UI account)" echo " - Enable 2FA/TOTP for that user and root@pam via the web UI" echo " - ${SCRIPT_DIR}/audit.sh (verify everything above)"