Add fail-closed WireGuard container gateway
This commit is contained in:
+52
-6
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user