Skip to content

Commit 0582f35

Browse files
authored
Merge pull request #17 from TimInTech/fix/remove-unused-time
fix: installer package install, resolver handling, systemd RW paths; …
2 parents 8e6df30 + 12ed064 commit 0582f35

2 files changed

Lines changed: 110 additions & 17 deletions

File tree

install.sh

Lines changed: 110 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ set -euo pipefail
99
readonly UNBOUND_PORT=5335
1010
readonly NETALERTX_PORT=20211
1111
readonly PYTHON_SUITE_PORT=8090
12+
readonly NETALERTX_IMAGE="jokobsk/netalertx:latest"
13+
readonly SUITE_API_KEY_ENV="${SUITE_API_KEY:-}"
14+
readonly SUITE_LOG_LEVEL_ENV="${SUITE_LOG_LEVEL:-INFO}"
15+
readonly INSTALL_USER=${SUDO_USER:-$(whoami)}
1216
readonly PROJECT_DIR="$(pwd)"
17+
readonly RESOLV_CONF="/etc/resolv.conf"
18+
readonly RESOLV_CONF_BACKUP="/etc/resolv.conf.pi-hole-installer.bak"
19+
readonly -a FALLBACK_RESOLVERS=("1.1.1.1" "9.9.9.9")
1320

1421
# 🎨 Colors
1522
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
@@ -22,7 +29,24 @@ error() { echo -e "${RED}[✗]${NC} $*"; }
2229
step() { echo -e "\n${YELLOW}[STEP]${NC} $*"; }
2330

2431
# 🛡️ Error handler
25-
trap 'error "Installation failed. See logs above."' ERR
32+
trap 'error "Installation failed. See logs above."; exit 1' ERR
33+
34+
# ---------------------------------------------------------------------------
35+
# 🧪 Helpers
36+
write_resolv_conf() {
37+
local file="$1"; shift
38+
: >"$file"
39+
for resolver in "$@"; do
40+
printf 'nameserver %s\n' "$resolver" >>"$file"
41+
done
42+
}
43+
44+
extract_env_value() {
45+
local key="$1" file="$2"
46+
if [[ -f "$file" ]]; then
47+
grep -E "^${key}=" "$file" | tail -n1 | cut -d= -f2-
48+
fi
49+
}
2650

2751
# ---------------------------------------------------------------------------
2852
# 🔍 System checks
@@ -34,24 +58,72 @@ check_system() {
3458
success "System checks passed"
3559
}
3660

61+
# 🧰 Ubuntu resolver handling (Port 53)
62+
handle_systemd_resolved() {
63+
step "Checking systemd-resolved on Ubuntu (port 53)"
64+
if [[ -r /etc/os-release ]]; then
65+
# shellcheck disable=SC1091
66+
. /etc/os-release
67+
if [[ "${ID:-}" == ubuntu* || "${ID_LIKE:-}" == *ubuntu* ]]; then
68+
if systemctl list-unit-files | grep -q '^systemd-resolved\.service'; then
69+
if systemctl is-active --quiet systemd-resolved; then
70+
warn "systemd-resolved is active; stopping to free port 53"
71+
systemctl stop systemd-resolved || true
72+
fi
73+
systemctl disable systemd-resolved || true
74+
if [[ -L $RESOLV_CONF ]]; then
75+
warn "$RESOLV_CONF is a symlink; replacing with static resolver"
76+
if [[ ! -e $RESOLV_CONF_BACKUP ]]; then
77+
mv -f "$RESOLV_CONF" "$RESOLV_CONF_BACKUP"
78+
else
79+
rm -f "$RESOLV_CONF"
80+
fi
81+
fi
82+
write_resolv_conf "$RESOLV_CONF" "${FALLBACK_RESOLVERS[@]}"
83+
fi
84+
fi
85+
fi
86+
success "Resolver prepared with external fallbacks"
87+
}
88+
89+
finalize_resolver_configuration() {
90+
log "Pointing system resolver to Pi-hole"
91+
local resolvers=("127.0.0.1" "${FALLBACK_RESOLVERS[@]}")
92+
write_resolv_conf "$RESOLV_CONF" "${resolvers[@]}"
93+
success "System resolver now prefers Pi-hole on 127.0.0.1"
94+
}
95+
96+
# 🔌 Port conflicts
3797
check_ports() {
3898
step "Checking ports"
3999
local ports=($UNBOUND_PORT $NETALERTX_PORT $PYTHON_SUITE_PORT 53)
40-
for port in "${ports[@]}"; do
41-
if ss -tuln | grep -q ":$port "; then
42-
warn "Port $port already in use"
43-
fi
44-
done
100+
if command -v ss >/dev/null; then
101+
for port in "${ports[@]}"; do
102+
if ss -tuln | grep -q ":$port "; then
103+
warn "Port $port already in use"
104+
fi
105+
done
106+
elif command -v netstat >/dev/null; then
107+
for port in "${ports[@]}"; do
108+
if netstat -tuln | grep -q ":$port "; then
109+
warn "Port $port already in use"
110+
fi
111+
done
112+
else
113+
warn "Neither ss nor netstat available; skipping port checks"
114+
fi
45115
}
46116

47117
# 📦 Packages
48118
install_packages() {
49119
step "Installing system packages"
50120
apt-get update -qq
51-
python3 python3-venv python3-pip git docker.io openssl systemd sqlite3
121+
apt-get install -y unbound ca-certificates curl dnsutils \
122+
python3 python3-venv python3-pip git docker.io openssl systemd sqlite3 iproute2
52123
success "System packages installed"
53124
}
54125

126+
# 🔐 Unbound config
55127
configure_unbound() {
56128
step "Configuring Unbound"
57129
install -d -m 0755 /var/lib/unbound
@@ -74,6 +146,7 @@ server:
74146
cache-max-ttl: 86400
75147
trust-anchor-file: /var/lib/unbound/root.key
76148
root-hints: /var/lib/unbound/root.hints
149+
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
77150
78151
forward-zone:
79152
name: "."
@@ -100,6 +173,7 @@ install_pihole() {
100173
sed -i "s/^PIHOLE_DNS_1=.*/PIHOLE_DNS_1=127.0.0.1#$UNBOUND_PORT/" /etc/pihole/setupVars.conf
101174
sed -i "s/^PIHOLE_DNS_2=.*/PIHOLE_DNS_2=/" /etc/pihole/setupVars.conf
102175
pihole restartdns
176+
finalize_resolver_configuration
103177
success "Pi-hole configured with Unbound"
104178
}
105179

@@ -122,12 +196,33 @@ install_netalertx() {
122196
setup_python_suite() {
123197
step "Setting up Python suite"
124198
cd "$PROJECT_DIR"
199+
# Ensure data directory exists and is writable by service user
200+
install -d -m 0755 "$PROJECT_DIR/data"
201+
chown -R "$INSTALL_USER:$INSTALL_USER" "$PROJECT_DIR/data"
202+
125203
[[ -d .venv ]] || sudo -u "$INSTALL_USER" python3 -m venv .venv
126204
sudo -u "$INSTALL_USER" .venv/bin/pip install -U pip
127205
sudo -u "$INSTALL_USER" .venv/bin/pip install -r requirements.txt
128206
sudo -u "$INSTALL_USER" .venv/bin/python scripts/bootstrap.py || true
129207

130-
cat > /etc/systemd/system/pihole-suite.service <<EOF
208+
local env_file="$PROJECT_DIR/.env"
209+
local suite_api_key="$SUITE_API_KEY_ENV"
210+
if [[ -z "$suite_api_key" ]]; then
211+
suite_api_key="$(extract_env_value "SUITE_API_KEY" "$env_file")"
212+
fi
213+
if [[ -z "$suite_api_key" ]]; then
214+
suite_api_key="$(openssl rand -hex 16)"
215+
fi
216+
217+
cat > "$env_file" <<ENV
218+
SUITE_API_KEY=$suite_api_key
219+
SUITE_PORT=$PYTHON_SUITE_PORT
220+
SUITE_DATA_DIR=$PROJECT_DIR/data
221+
SUITE_LOG_LEVEL=$SUITE_LOG_LEVEL_ENV
222+
ENV
223+
chown "$INSTALL_USER:$INSTALL_USER" "$env_file"
224+
225+
cat > /etc/systemd/system/pihole-suite.service <<SERVICE_EOF
131226
[Unit]
132227
Description=Pi-hole Suite (API + monitoring)
133228
After=network.target pihole-FTL.service
@@ -147,18 +242,16 @@ RestartSec=5
147242
NoNewPrivileges=yes
148243
ProtectSystem=strict
149244
ProtectHome=yes
245+
ProtectKernelTunables=yes
246+
ProtectKernelModules=yes
247+
ProtectControlGroups=yes
150248
PrivateTmp=yes
249+
ReadWritePaths=$PROJECT_DIR $PROJECT_DIR/data
151250
152251
[Install]
153252
WantedBy=multi-user.target
154-
EOF
253+
SERVICE_EOF
155254

156-
cat > .env <<ENV
157-
SUITE_API_KEY=$SUITE_API_KEY
158-
SUITE_PORT=$PYTHON_SUITE_PORT
159-
SUITE_DATA_DIR=$PROJECT_DIR/data
160-
SUITE_LOG_LEVEL=${SUITE_LOG_LEVEL:-INFO}
161-
ENV
162255
systemctl daemon-reload
163256
systemctl enable --now pihole-suite.service
164257
success "Python suite running on :$PYTHON_SUITE_PORT"
@@ -168,6 +261,7 @@ ENV
168261
run_health_checks() {
169262
step "Running health checks"
170263
dig +short @127.0.0.1 -p $UNBOUND_PORT example.com | grep -q "." && success "Unbound OK" || error "Unbound FAIL"
264+
pihole status | grep -iEq "blocking.+enabled|enabled" && success "Pi-hole OK" || warn "Pi-hole status unclear"
171265
docker ps | grep -q netalertx && success "NetAlertX OK" || warn "NetAlertX missing"
172266
systemctl is-active --quiet pihole-suite && success "Python suite OK" || warn "Python suite not active"
173267
}
@@ -179,7 +273,7 @@ show_summary() {
179273
echo "Pi-hole admin: http://$(hostname -I | awk '{print $1}')/admin"
180274
echo "NetAlertX: http://$(hostname -I | awk '{print $1}'):$NETALERTX_PORT"
181275
echo "Python Suite: http://127.0.0.1:$PYTHON_SUITE_PORT"
182-
echo "API Key: $SUITE_API_KEY"
276+
echo "API Key: $(extract_env_value "SUITE_API_KEY" "$PROJECT_DIR/.env")"
183277
}
184278

185279
# 🚀 Main

pyalloc/main.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import logging
44
import sqlite3
55
import threading
6-
import time
76
from typing import Optional
87

98
from .allocator import IPPool

0 commit comments

Comments
 (0)