From ad55febe23da2ed1ba56f68b226cbe33d199f00d Mon Sep 17 00:00:00 2001 From: TimInTech Date: Fri, 3 Oct 2025 11:22:31 +0200 Subject: [PATCH] fix: installer package install, resolver handling, systemd RW paths; docs cleanup --- install.sh | 110 ++++++++++++++++++++++++++++++++++++------------ pyalloc/main.py | 1 - 2 files changed, 84 insertions(+), 27 deletions(-) diff --git a/install.sh b/install.sh index 6caa955..a2ca607 100755 --- a/install.sh +++ b/install.sh @@ -10,9 +10,13 @@ readonly UNBOUND_PORT=5335 readonly NETALERTX_PORT=20211 readonly PYTHON_SUITE_PORT=8090 readonly NETALERTX_IMAGE="jokobsk/netalertx:latest" -readonly SUITE_API_KEY=${SUITE_API_KEY:-$(openssl rand -hex 16)} +readonly SUITE_API_KEY_ENV="${SUITE_API_KEY:-}" +readonly SUITE_LOG_LEVEL_ENV="${SUITE_LOG_LEVEL:-INFO}" readonly INSTALL_USER=${SUDO_USER:-$(whoami)} readonly PROJECT_DIR="$(pwd)" +readonly RESOLV_CONF="/etc/resolv.conf" +readonly RESOLV_CONF_BACKUP="/etc/resolv.conf.pi-hole-installer.bak" +readonly -a FALLBACK_RESOLVERS=("1.1.1.1" "9.9.9.9") # ๐ŸŽจ Colors RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' @@ -25,7 +29,24 @@ error() { echo -e "${RED}[โœ—]${NC} $*"; } step() { echo -e "\n${YELLOW}[STEP]${NC} $*"; } # ๐Ÿ›ก๏ธ Error handler -trap 'error "Installation failed. See logs above."' ERR +trap 'error "Installation failed. See logs above."; exit 1' ERR + +# --------------------------------------------------------------------------- +# ๐Ÿงช Helpers +write_resolv_conf() { + local file="$1"; shift + : >"$file" + for resolver in "$@"; do + printf 'nameserver %s\n' "$resolver" >>"$file" + done +} + +extract_env_value() { + local key="$1" file="$2" + if [[ -f "$file" ]]; then + grep -E "^${key}=" "$file" | tail -n1 | cut -d= -f2- + fi +} # --------------------------------------------------------------------------- # ๐Ÿ” System checks @@ -44,32 +65,53 @@ handle_systemd_resolved() { # shellcheck disable=SC1091 . /etc/os-release if [[ "${ID:-}" == ubuntu* || "${ID_LIKE:-}" == *ubuntu* ]]; then - if systemctl list-unit-files | grep -q '^systemd-resolved\.service'; then + if systemctl list-unit-files | grep -q '^systemd-resolved\\.service'; then if systemctl is-active --quiet systemd-resolved; then - warn "systemd-resolved is active; stopping and disabling to free port 53" + warn "systemd-resolved is active; stopping to free port 53" systemctl stop systemd-resolved || true fi systemctl disable systemd-resolved || true - # If resolv.conf is a symlink (typical on Ubuntu), replace it with a static file - if [[ -L /etc/resolv.conf ]]; then - warn "/etc/resolv.conf is a symlink; replacing with static resolver" - mv -f /etc/resolv.conf /etc/resolv.conf.backup 2>/dev/null || true - printf 'nameserver 127.0.0.1\n' > /etc/resolv.conf + if [[ -L $RESOLV_CONF ]]; then + warn "$RESOLV_CONF is a symlink; replacing with static resolver" + if [[ ! -e $RESOLV_CONF_BACKUP ]]; then + mv -f "$RESOLV_CONF" "$RESOLV_CONF_BACKUP" + else + rm -f "$RESOLV_CONF" + fi fi + write_resolv_conf "$RESOLV_CONF" "${FALLBACK_RESOLVERS[@]}" fi fi fi + success "Resolver prepared with external fallbacks" +} + +finalize_resolver_configuration() { + log "Pointing system resolver to Pi-hole" + local resolvers=("127.0.0.1" "${FALLBACK_RESOLVERS[@]}") + write_resolv_conf "$RESOLV_CONF" "${resolvers[@]}" + success "System resolver now prefers Pi-hole on 127.0.0.1" } # ๐Ÿ”Œ Port conflicts check_ports() { step "Checking ports" local ports=($UNBOUND_PORT $NETALERTX_PORT $PYTHON_SUITE_PORT 53) - for port in "${ports[@]}"; do - if ss -tuln | grep -q ":$port "; then - warn "Port $port already in use" - fi - done + if command -v ss >/dev/null; then + for port in "${ports[@]}"; do + if ss -tuln | grep -q ":$port "; then + warn "Port $port already in use" + fi + done + elif command -v netstat >/dev/null; then + for port in "${ports[@]}"; do + if netstat -tuln | grep -q ":$port "; then + warn "Port $port already in use" + fi + done + else + warn "Neither ss nor netstat available; skipping port checks" + fi } # ๐Ÿ“ฆ Packages @@ -77,7 +119,7 @@ install_packages() { step "Installing system packages" apt-get update -qq apt-get install -y unbound ca-certificates curl dnsutils \ - python3 python3-venv python3-pip git docker.io openssl systemd sqlite3 + python3 python3-venv python3-pip git docker.io openssl systemd sqlite3 iproute2 success "System packages installed" } @@ -87,7 +129,7 @@ configure_unbound() { install -d -m 0755 /var/lib/unbound curl -fsSL https://www.internic.net/domain/named.root -o /var/lib/unbound/root.hints - cat > /etc/unbound/unbound.conf.d/pi-hole.conf < /etc/unbound/unbound.conf.d/pi-hole.conf <<'UNBOUND_EOF' server: interface: 127.0.0.1 port: $UNBOUND_PORT @@ -112,7 +154,7 @@ forward-zone: forward-addr: 9.9.9.9@853#dns.quad9.net forward-addr: 149.112.112.112@853#dns.quad9.net # NOTE: This is DoT forwarding to Quad9 (not full recursion to the root); intended. -EOF +UNBOUND_EOF unbound-anchor -a /var/lib/unbound/root.key || true systemctl enable --now unbound @@ -131,6 +173,7 @@ install_pihole() { sed -i "s/^PIHOLE_DNS_1=.*/PIHOLE_DNS_1=127.0.0.1#$UNBOUND_PORT/" /etc/pihole/setupVars.conf sed -i "s/^PIHOLE_DNS_2=.*/PIHOLE_DNS_2=/" /etc/pihole/setupVars.conf pihole restartdns + finalize_resolver_configuration success "Pi-hole configured with Unbound" } @@ -156,12 +199,30 @@ setup_python_suite() { # Ensure data directory exists and is writable by service user install -d -m 0755 "$PROJECT_DIR/data" chown -R "$INSTALL_USER:$INSTALL_USER" "$PROJECT_DIR/data" + [[ -d .venv ]] || sudo -u "$INSTALL_USER" python3 -m venv .venv sudo -u "$INSTALL_USER" .venv/bin/pip install -U pip sudo -u "$INSTALL_USER" .venv/bin/pip install -r requirements.txt sudo -u "$INSTALL_USER" .venv/bin/python scripts/bootstrap.py || true - cat > /etc/systemd/system/pihole-suite.service < "$env_file" < /etc/systemd/system/pihole-suite.service < .env <