initial upload

This commit is contained in:
Ubuntu
2026-01-08 19:41:23 +00:00
commit ae4f1ad1cc
42 changed files with 1371 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
.env
certs/

View File

@@ -0,0 +1 @@
#Testcomment

View File

@@ -0,0 +1,18 @@
http:
routers:
# Route für Apps auf VM 301
to-apps-vm:
rule: HostRegexp(`^[a-z0-9-]+\.apps\.stabify\.de$`)
service: apps-vm-service
entryPoints: [ websecure ]
tls:
certResolver: le
domains:
- main: "*.apps.stabify.de"
services:
apps-vm-service:
loadBalancer:
servers:
- url: "http://vm-docker-apps-301.stabify.de:80"
passHostHeader: true

View File

@@ -0,0 +1,42 @@
api:
dashboard: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: le
domains:
- main: "stabify.de"
sans:
- "*.stabify.de"
- "*.k3s.stabify.de"
- "*.sys.stabify.de"
- "*.apps.stabify.de"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: "/etc/traefik/dynamic"
watch: true
certificatesResolvers:
le:
acme:
email: acme@infrastructure.stabify.de
storage: /certs/acme.json
caServer: https://acme-v02.api.letsencrypt.org/directory
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 10

View File

@@ -0,0 +1,30 @@
---
services:
traefik:
image: traefik:v3.6
container_name: traefik-edge
restart: unless-stopped
security_opt:
- no-new-privileges:true
environment:
- TZ=Europe/Berlin
- CF_ZONE_API_TOKEN=${CF_ZONE_API_TOKEN}
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
command:
# --- DEBUGGING AKTIVIEREN ---
- "--log.level=DEBUG" # Setzt das Log-Level auf DEBUG (Fehlersuche)
- "--accesslog=true"
ports:
- "80:80"
- "443:443"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.yml:/etc/traefik/traefik.yml:ro
- ./config/dynamic:/etc/traefik/dynamic:ro
- ./certs:/certs
networks:
- proxy
networks:
proxy:
name: proxy-edge

View File

@@ -0,0 +1,23 @@
---
services:
traefik:
image: traefik:v3.6
container_name: traefik-sub
restart: unless-stopped
environment:
- TZ=Europe/Berlin
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
networks:
proxy:
name: proxy-sub
external: false

View File

@@ -0,0 +1,12 @@
FROM hashicorp/vault:1.15
# Install dependencies for automation script
RUN apk add --no-cache openssl jq curl bash ca-certificates
# Copy entrypoint script
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Use our script as entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

View File

@@ -0,0 +1,81 @@
# Vault Operations Manual (Automated)
Dieses Dokument beschreibt den Betrieb von HashiCorp Vault innerhalb der Stabify Infrastruktur.
Vault läuft als Docker-Container auf der VM `vm-docker-apps-301.stabify.de` (IP: `10.100.30.11`).
## Automatisiertes Setup
Dieser Service nutzt ein **Custom Entrypoint Script**, welches folgende Schritte automatisiert:
1. **Zertifikate**: Generiert CA & Server-Zertifikate beim Start, falls diese fehlen.
2. **Initialisierung**: Initialisiert Vault automatisch beim ersten Start.
3. **Auto-Unseal**: Speichert die Keys lokal (`file/init_keys.json`) und nutzt sie zum automatischen Entsperren beim Boot.
**⚠️ SECURITY WARNING:**
Die Unseal-Keys werden im Klartext unter `/opt/vault/file/init_keys.json` gespeichert.
Dies dient dem komfortablen "Set-and-Forget" Betrieb im Homelab. In Hochsicherheitsumgebungen sollte diese Datei nach dem initialen Setup gelöscht und die Keys an einem sicheren Ort (Passwort Manager) verwahrt werden.
## Inbetriebnahme
### 1. Deployment (via Ansible)
Da der Service Teil der `vm-docker-apps-301` Deployment-Definition ist, wird er automatisch gestartet, sobald das Ansible-Playbook läuft.
### 2. Zugriff erhalten
Nach dem Start liegen die generierten Daten auf dem Server.
1. **CA Zertifikat holen** (damit dein Browser/Client vertraut):
```bash
scp ansible@10.100.30.11:/opt/vault/certs/ca.crt ./
# Importiere ca.crt in deinen Truststore / Schlüsselbund
```
2. **Root Token holen** (für Admin-Zugriff):
```bash
ssh ansible@10.100.30.11 "cat /opt/vault/file/init_keys.json" | jq -r .root_token
```
3. **Login**:
```bash
export VAULT_ADDR='https://10.100.30.11:8200'
export VAULT_CACERT=./ca.crt
vault login <Root-Token>
```
## Secrets anlegen (Einmalig)
Aktiviere die KV v2 Engine und lege die benötigten Secrets an.
```bash
# Engine aktivieren
vault secrets enable -path=secret kv-v2
# 1. Proxmox Credentials
vault kv put secret/infrastructure/proxmox \
api_token_id="root@pam!terraform" \
api_token_secret="dein-secret-token"
# 2. OPNsense Credentials
vault kv put secret/infrastructure/opnsense \
api_key="dein-api-key" \
api_secret="dein-api-secret"
# 3. VM User Credentials
vault kv put secret/infrastructure/vm-credentials \
ci_user="ansible" \
ci_password="super-secure-password" \
ssh_public_key="ssh-ed25519 AAAA..."
```
## Troubleshooting
**Logs prüfen:**
```bash
ssh ansible@10.100.30.11 "docker logs vault-prod"
```
**Zertifikate neu generieren:**
Lösche einfach den Ordner `certs` auf dem Server und starte den Container neu.
```bash
rm -rf /opt/vault/certs/*
docker compose restart vault
```
**Achtung:** Danach musst du das neue `ca.crt` wieder auf deine Clients verteilen.

View File

@@ -0,0 +1,20 @@
storage "raft" {
path = "/vault/file"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/config/certs/vault.crt"
tls_key_file = "/vault/config/certs/vault.key"
tls_disable = 0
}
api_addr = "https://10.100.30.11:8200"
cluster_addr = "https://10.100.30.11:8201"
ui = true
# Production hardening
disable_mlock = true
max_lease_ttl = "768h"
default_lease_ttl = "168h"

View File

@@ -0,0 +1,25 @@
services:
vault:
build: .
image: stabify/vault-custom:latest
container_name: vault-prod
restart: unless-stopped
ports:
- "8200:8200"
environment:
VAULT_ADDR: 'https://127.0.0.1:8200'
VAULT_API_ADDR: 'https://127.0.0.1:8200'
volumes:
- ./config:/vault/config
- ./file:/vault/file
- ./logs:/vault/logs
# Mount certs directory.
- ./certs:/vault/config/certs
cap_add:
- IPC_LOCK
networks:
- internal
networks:
internal:
name: vault-net

View File

@@ -0,0 +1,99 @@
#!/bin/sh
set -e
# --- 1. Auto-Generate Certificates ---
CERTS_DIR="/vault/config/certs"
if [ ! -f "$CERTS_DIR/vault.crt" ] || [ ! -f "$CERTS_DIR/vault.key" ]; then
echo "[ENTRYPOINT] Certificates missing. Generating self-signed certs..."
mkdir -p "$CERTS_DIR"
# Create CA
openssl genrsa -out "$CERTS_DIR/ca.key" 4096
openssl req -new -x509 -days 3650 -key "$CERTS_DIR/ca.key" -out "$CERTS_DIR/ca.crt" \
-subj "/C=DE/ST=Berlin/L=Berlin/O=Stabify/OU=IT/CN=StabifyRootCA"
# Create Server Key/CSR
openssl genrsa -out "$CERTS_DIR/vault.key" 4096
openssl req -new -key "$CERTS_DIR/vault.key" -out "$CERTS_DIR/vault.csr" \
-subj "/C=DE/ST=Berlin/L=Berlin/O=Stabify/OU=IT/CN=vault.stabify.de"
# Config for SANs
cat > "$CERTS_DIR/v3.ext" << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = vault.stabify.de
DNS.2 = vm-docker-apps-301.stabify.de
DNS.3 = localhost
IP.1 = 127.0.0.1
IP.2 = 10.100.30.11
EOF
# Sign Cert
openssl x509 -req -in "$CERTS_DIR/vault.csr" \
-CA "$CERTS_DIR/ca.crt" -CAkey "$CERTS_DIR/ca.key" -CAcreateserial \
-out "$CERTS_DIR/vault.crt" -days 3650 -sha256 -extfile "$CERTS_DIR/v3.ext"
chmod 644 "$CERTS_DIR/vault.crt" "$CERTS_DIR/ca.crt"
chmod 600 "$CERTS_DIR/vault.key" "$CERTS_DIR/ca.key"
echo "[ENTRYPOINT] Certificates generated successfully."
fi
# Trust our own CA inside the container (for local curl/vault calls)
cp "$CERTS_DIR/ca.crt" /usr/local/share/ca-certificates/stabify-ca.crt
update-ca-certificates
# --- 2. Start Vault in Background ---
echo "[ENTRYPOINT] Starting Vault server..."
vault server -config=/vault/config/vault.hcl &
VAULT_PID=$!
# Wait for Vault to be ready (it will be sealed initially)
echo "[ENTRYPOINT] Waiting for Vault API..."
until nc -z 127.0.0.1 8200; do
sleep 1
done
sleep 2
# --- 3. Auto-Init ---
export VAULT_ADDR='https://127.0.0.1:8200'
export VAULT_SKIP_VERIFY=true # We trust localhost
KEYS_FILE="/vault/file/init_keys.json"
if ! vault status | grep -q "Initialized.*true"; then
echo "[ENTRYPOINT] Vault is not initialized. Initializing..."
vault operator init -format=json > "$KEYS_FILE"
chmod 600 "$KEYS_FILE"
echo "[ENTRYPOINT] Vault initialized. Keys saved to $KEYS_FILE"
echo "!!! WARNING: Unseal keys are stored in $KEYS_FILE. Secure this file or delete it after noting the keys !!!"
fi
# --- 4. Auto-Unseal ---
if [ -f "$KEYS_FILE" ]; then
echo "[ENTRYPOINT] Found keys file. Attempting auto-unseal..."
# Read first 3 keys and unseal
KEY1=$(jq -r ".unseal_keys_b64[0]" "$KEYS_FILE")
KEY2=$(jq -r ".unseal_keys_b64[1]" "$KEYS_FILE")
KEY3=$(jq -r ".unseal_keys_b64[2]" "$KEYS_FILE")
vault operator unseal "$KEY1" > /dev/null
vault operator unseal "$KEY2" > /dev/null
vault operator unseal "$KEY3" > /dev/null
if vault status | grep -q "Sealed.*false"; then
echo "[ENTRYPOINT] Vault successfully unsealed!"
else
echo "[ENTRYPOINT] Failed to unseal Vault."
fi
else
echo "[ENTRYPOINT] No keys file found. Manual unseal required."
fi
# --- 5. Wait for Vault Process ---
wait $VAULT_PID

View File

@@ -0,0 +1,8 @@
app_name: "vault"
vault_config:
ui: true
listener_address: "0.0.0.0:8200"
api_addr: "https://10.100.30.11:8200"
cluster_addr: "https://10.100.30.11:8201"

View File

@@ -0,0 +1,16 @@
---
services:
whoami:
image: traefik/whoami
container_name: whoami
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.apps.stabify.de`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
- proxy-sub
networks:
proxy-sub:
external: true