Add tracked, idempotent firewall config script for llama-server's proxy port — previously only run as one-off live commands
This commit is contained in:
parent
3f5c8562dd
commit
012332a272
1 changed files with 104 additions and 0 deletions
104
scripts/configure-llama-firewall.sh
Executable file
104
scripts/configure-llama-firewall.sh
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/env bash
|
||||
# Built standing on the shoulders of billions of dwarves
|
||||
# Created by John A. Hoeven with the ethical assistance of Claude AI
|
||||
# Licence: The Unlicense — https://unlicense.org
|
||||
# ---------------------------------------------------------------------------
|
||||
# configure-llama-firewall.sh
|
||||
# Version: v0.0.1 | Status: DEVELOPMENT
|
||||
# Role: Orchestrator
|
||||
# ---------------------------------------------------------------------------
|
||||
# Purpose: Open the reverse-proxy HTTP port for llama-server's web UI,
|
||||
# restricted to the same two LAN ranges already used for SSH
|
||||
# (see the kickstart's own firewalld zone file). This was
|
||||
# previously only run as one-off firewall-cmd commands typed
|
||||
# directly during the Phase 5 deployment session — never
|
||||
# tracked anywhere. This script is that missing artifact.
|
||||
# Target: BigBoy — AlmaLinux 10.2, firewalld already enabled from the
|
||||
# kickstart (SSH rules already in place via a direct zone-file
|
||||
# write during install — see CLAUDE.md for why firewall-cmd
|
||||
# itself doesn't work inside a kickstart %post chroot; that
|
||||
# limitation does not apply here, since this runs against a
|
||||
# live, fully-booted system with firewalld actually running).
|
||||
# Entry: ./configure-llama-firewall.sh
|
||||
# Depends: firewalld (already enabled)
|
||||
# Note: Idempotent — firewall-cmd's --add-rich-rule is itself
|
||||
# idempotent (adding an already-present rule is a no-op, not
|
||||
# an error), so this is safe to re-run.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# No 'set -e' — every operation checked and logged explicitly (CE OS standard §1.8).
|
||||
|
||||
# ── Configuration ────────────────────────────────────────────────────────
|
||||
#
|
||||
# These ranges must match firewall_allowed_ranges in
|
||||
# ansible/group_vars/bigboy.yml — if that file is ever updated, update
|
||||
# this script too, or better, formalize this into an actual Ansible role
|
||||
# that reads the variable directly rather than duplicating the values
|
||||
# here (see ansible/README.md's "Known Deferred" section — Phase 4/5
|
||||
# aren't yet real roles, this script is the same category of gap).
|
||||
|
||||
ALLOWED_RANGES=(
|
||||
"192.168.1.0/24" # home LAN — current
|
||||
"192.168.0.0/24" # workbench bench LAN — used during initial deploy
|
||||
)
|
||||
HTTP_ZONE="public"
|
||||
|
||||
LOG_DIR="${HOME}/.local/logs/firewall-config"
|
||||
LOG_FILE="${LOG_DIR}/config-$(date '+%Y-%m-%d_%H%M%S').log"
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
_log() {
|
||||
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${1}" | tee -a "${LOG_FILE}"
|
||||
}
|
||||
|
||||
# ── Pre-flight ───────────────────────────────────────────────────────────
|
||||
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
_log "ERROR: do not run this as root directly — it invokes sudo only"
|
||||
_log "for the specific steps that need it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! systemctl is-active --quiet firewalld; then
|
||||
_log "ERROR: firewalld is not active. This script assumes it's already"
|
||||
_log "enabled (per the kickstart). Check 'systemctl status firewalld'"
|
||||
_log "before proceeding — something else is wrong if it's not running."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Confirmation ─────────────────────────────────────────────────────────
|
||||
|
||||
_log "About to open HTTP (port 80, llama-server's reverse proxy) for:"
|
||||
for range in "${ALLOWED_RANGES[@]}"; do
|
||||
_log " - ${range}"
|
||||
done
|
||||
printf 'Proceed? [y/N] '
|
||||
read -r response
|
||||
case "${response}" in
|
||||
[yY]|[yY][eE][sS]) ;;
|
||||
*) _log "Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
|
||||
# ── Apply rules ──────────────────────────────────────────────────────────
|
||||
|
||||
for range in "${ALLOWED_RANGES[@]}"; do
|
||||
_log "Adding rich rule for ${range}"
|
||||
if ! sudo firewall-cmd --permanent --zone="${HTTP_ZONE}" \
|
||||
--add-rich-rule="rule family=\"ipv4\" source address=\"${range}\" service name=\"http\" accept" \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
_log "ERROR: failed to add rich rule for ${range} — see ${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
_log "Reloading firewalld to apply changes"
|
||||
if ! sudo firewall-cmd --reload >>"${LOG_FILE}" 2>&1; then
|
||||
_log "ERROR: firewall-cmd --reload failed — see ${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_log ""
|
||||
_log "Done. Confirm with:"
|
||||
_log " sudo firewall-cmd --zone=${HTTP_ZONE} --list-rich-rules"
|
||||
_log ""
|
||||
_log "Full log: ${LOG_FILE}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue