Add fail-closed WireGuard container gateway

This commit is contained in:
Mikei386
2026-08-22 20:48:49 +02:00
parent 2f3bdde8b0
commit 0e5876f1a9
17 changed files with 365 additions and 109 deletions
+52 -6
View File
@@ -38,7 +38,7 @@ fi
# shellcheck disable=SC1090
source "$CONFIG"
required=(AI_HOSTNAME ADMIN_USER AI_BIND_ADDRESS MODEL_DIR FAST_MODEL_FILE
required=(AI_HOSTNAME ADMIN_USER MODEL_DIR FAST_MODEL_FILE
FAST_MODEL_URL FAST_MODEL_SHA256 MEDIUM_MODEL_FILE MEDIUM_MODEL_URL
MEDIUM_MODEL_SHA256 LARGE_MODEL_FILE LARGE_MODEL_URL LARGE_MODEL_SHA256
ULTRA_MODEL_FILE ULTRA_MODEL_URL ULTRA_MODEL_SHA256
@@ -47,6 +47,9 @@ required=(AI_HOSTNAME ADMIN_USER AI_BIND_ADDRESS MODEL_DIR FAST_MODEL_FILE
for name in "${required[@]}"; do
[[ -n "${!name:-}" ]] || die "Pflichtwert $name fehlt."
done
if [[ ${WIREGUARD_MODE:-container} != container ]]; then
[[ -n ${AI_BIND_ADDRESS:-} ]] || die "Pflichtwert AI_BIND_ADDRESS fehlt."
fi
source /etc/os-release
[[ ${ID:-} == debian ]] || die "Unterstützt wird Debian, gefunden: ${ID:-unbekannt}."
@@ -111,6 +114,19 @@ EOF
fi
}
setup_ssh_hardening() {
[[ ${SSH_KEY_ONLY:-true} == true ]] || return 0
log "SSH auf Schlüsselanmeldung beschränken"
install -d -m 0755 /etc/ssh/sshd_config.d
cat >/etc/ssh/sshd_config.d/20-athena-key-only.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
EOF
sshd -t
systemctl reload ssh
}
install_docker() {
log "Docker CE aus dem offiziellen Repository installieren"
install -m 0755 -d /etc/apt/keyrings
@@ -188,6 +204,7 @@ install_nvidia() {
}
setup_wireguard() {
[[ ${WIREGUARD_MODE:-container} != container ]] || return 0
[[ ${WIREGUARD_ENABLE:-false} == true ]] || return 0
for name in WG_INTERFACE WG_ADDRESS WG_HOME_SUBNET WG_PEER_PUBLIC_KEY WG_PEER_ENDPOINT; do
[[ -n "${!name:-}" && ${!name} != REPLACE_* ]] || die "WireGuard-Wert $name fehlt."
@@ -240,8 +257,9 @@ install_stack_files() {
chmod 0640 "$searx"
cat >$SECRETS_DIR/stack.env <<EOF
AI_BIND_ADDRESS=$AI_BIND_ADDRESS
AI_BIND_ADDRESS=${AI_BIND_ADDRESS:-127.0.0.1}
MODEL_DIR=$MODEL_DIR
WIREGUARD_CONFIG_FILE=${WIREGUARD_CONFIG_FILE:-/etc/mike-ai/wireguard/fritz-athena.conf}
ROUTER_API_KEY=$(<$SECRETS_DIR/router-api-key)
CONTROLLER_TOKEN=$(<$SECRETS_DIR/controller-token)
WEBUI_SECRET_KEY=$(<$SECRETS_DIR/webui-secret)
@@ -316,6 +334,18 @@ EOF
}
install_routing_guard() {
if [[ ${WIREGUARD_MODE:-container} == container ]]; then
log "Container-WireGuard-Routing installieren"
[[ -s ${WIREGUARD_CONFIG_FILE:-/etc/mike-ai/wireguard/fritz-athena.conf} ]] || \
die "Fritzbox-WireGuard-Datei fehlt: ${WIREGUARD_CONFIG_FILE:-/etc/mike-ai/wireguard/fritz-athena.conf}"
install -m 0755 "$ROOT_DIR/platform/host/mike-ai-container-vpn-guard" \
/usr/local/sbin/mike-ai-container-vpn-guard
install -m 0644 "$ROOT_DIR/platform/host/mike-ai-container-vpn-guard.service" \
/etc/systemd/system/mike-ai-container-vpn-guard.service
systemctl daemon-reload
systemctl enable mike-ai-container-vpn-guard.service
return 0
fi
[[ ${WIREGUARD_ENABLE:-false} == true ]] || return 0
log "KI-Container auf WireGuard routen und Uni-Netz als Transit sperren"
cat >/usr/local/sbin/mike-ai-network-guard <<EOF
@@ -392,6 +422,10 @@ build_and_start() {
docker compose --env-file "$SECRETS_DIR/stack.env" up -d --build \
profile-controller router open-webui
if [[ ${WIREGUARD_MODE:-container} == container ]]; then
systemctl restart mike-ai-container-vpn-guard.service
fi
log "Auf gesunden Router warten"
local deadline=$((SECONDS + 180))
until [ "$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' mike-ai-router 2>/dev/null || true)" = "healthy" ]; do
@@ -438,6 +472,7 @@ PY
hostnamectl set-hostname "$AI_HOSTNAME"
install_base_packages
setup_remote_recovery
setup_ssh_hardening
install_docker
install_nvidia
setup_wireguard
@@ -447,11 +482,22 @@ install_routing_guard
build_and_start
log "Installation abgeschlossen"
if [[ ${WIREGUARD_MODE:-container} == container ]]; then
vpn_address=$(awk -F= '
/^[[:space:]]*Address[[:space:]]*=/ {
value=$2; gsub(/[[:space:]]/, "", value); split(value, addresses, ",")
for (i in addresses) if (addresses[i] !~ /:/) { sub(/\/.*/, "", addresses[i]); print addresses[i]; exit }
}
' "${WIREGUARD_CONFIG_FILE:-/etc/mike-ai/wireguard/fritz-athena.conf}")
else
vpn_address=$AI_BIND_ADDRESS
fi
cat <<EOF
OpenWebUI: http://${AI_BIND_ADDRESS}:8080
Router-API: http://${AI_BIND_ADDRESS}:8081
OpenWebUI: http://${vpn_address}:8080
Router-API: http://${vpn_address}:8081
Die geheimen Schlüssel liegen ausschließlich unter $SECRETS_DIR (0600).
Konfiguriere auf der Heimseite für den KI-Peer mindestens die Rückroute
${WG_ADDRESS:-10.77.0.2/32}; bei Internet-Routing zusätzlich NAT/Forwarding.
Im Container-Modus stammen Peer, Adresse und Heimrouten vollständig aus dem
root-only Fritzbox-Export. Die physischen Host-Adressen veröffentlichen keine
KI-Ports.
EOF