This commit is contained in:
DerLinkman
2026-10-17 17:16:53 +02:00
parent ceda1ae4a6
commit 7abcd14c94
11 changed files with 93 additions and 25 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
This wiki stores the project knowledge base for requirements, changes, technical documentation, implementation state, and traceability. Use this file as the routing entrypoint; open only the linked files needed for the current task. This wiki stores the project knowledge base for requirements, changes, technical documentation, implementation state, and traceability. Use this file as the routing entrypoint; open only the linked files needed for the current task.
Last updated: 2026-09-09 Last updated: 2026-10-11
## Current State ## Current State
+12 -3
View File
@@ -1,5 +1,5 @@
version: 1 version: 1
updated: '2026-09-09' updated: '2026-10-11'
documents: documents:
- id: GLOSSARY - id: GLOSSARY
type: note type: note
@@ -162,7 +162,7 @@ documents:
confidence: confirmed confidence: confirmed
- id: TECH-DEPLOYMENT - id: TECH-DEPLOYMENT
type: technical type: technical
title: Deployment title: Deployment (Runtime Environment)
path: technical/deployment.md path: technical/deployment.md
status: active status: active
tags: tags:
@@ -173,7 +173,11 @@ documents:
- TECH-ARCHITECTURE - TECH-ARCHITECTURE
source_paths: source_paths:
- execute.sh - execute.sh
- docker/ - docker/Dockerfile
- docker/requirements.yml
- docker/ansible-functs.sh
- ansible.cfg
- README.md
confidence: confirmed confidence: confirmed
- id: TECH-SECURITY - id: TECH-SECURITY
type: technical type: technical
@@ -185,11 +189,16 @@ documents:
- security - security
related: related:
- ALERT-20260909-001 - ALERT-20260909-001
- ALERT-20260909-002
- NFR-002 - NFR-002
- MOD-003
- MOD-007
source_paths: source_paths:
- vault.yml - vault.yml
- roles/monitoring/tasks/configure-psk.yml
- roles/bootstrap/defaults/main.yml - roles/bootstrap/defaults/main.yml
- ansible.cfg - ansible.cfg
- execute.sh
confidence: confirmed confidence: confirmed
- id: TECH-TESTING - id: TECH-TESTING
type: technical type: technical
+4 -1
View File
@@ -1,6 +1,6 @@
# Project Status # Project Status
Last updated: 2026-09-09 Last updated: 2026-10-11
## Scaffold State ## Scaffold State
@@ -11,6 +11,9 @@ Last updated: 2026-09-09
## Current State ## Current State
- Updated 2026-10-11: Docker launcher uses the caller's local SSH directory
read-only (`SSH_KEY_DIR`, default `$HOME/.ssh`); runtime behavior and usage
are documented in [deployment](./technical/deployment.md) and `README.md`.
- Repository fully scanned (root config, docker runtime, 3 inventories, - Repository fully scanned (root config, docker runtime, 3 inventories,
6 playbooks, 7 roles). Findings and module docs confirmed against source. 6 playbooks, 7 roles). Findings and module docs confirmed against source.
- Open alerts: 0 (2 resolved on 2026-09-09) - see - Open alerts: 0 (2 resolved on 2026-09-09) - see
+1 -1
View File
@@ -11,7 +11,7 @@ This section records implemented or observed code behavior and technical structu
- [Architecture](./architecture.md) - [Architecture](./architecture.md)
- [Codebase map](./codebase-map.md) - [Codebase map](./codebase-map.md)
- [Testing](./testing.md) - [Testing](./testing.md)
- [Deployment](./deployment.md) - [Deployment](./deployment.md) - image build, launcher, read-only local SSH keys
- [Security](./security.md) - [Security](./security.md)
## Modules ## Modules
+20 -7
View File
@@ -4,7 +4,7 @@ type: technical
status: active status: active
title: Deployment (Runtime Environment) title: Deployment (Runtime Environment)
created: '2026-09-09' created: '2026-09-09'
updated: '2026-09-09' updated: '2026-10-11'
tags: tags:
- technical - technical
- deployment - deployment
@@ -17,6 +17,7 @@ source_paths:
- docker/requirements.yml - docker/requirements.yml
- docker/ansible-functs.sh - docker/ansible-functs.sh
- ansible.cfg - ansible.cfg
- README.md
confidence: confirmed confidence: confirmed
--- ---
@@ -38,14 +39,24 @@ confidence: confirmed
## Launch Flow (execute.sh) ## Launch Flow (execute.sh)
1. Pick next free container name `ansible-<n>`. 1. Resolve `SSH_KEY_DIR` (default `$HOME/.ssh`) and reject a missing or
2. Ensure IPv6-enabled bridge network `ansible-dualstack` (fails fast with unreadable directory before invoking Docker. Relative paths are resolved
against the current working directory.
2. Pick next free container name `ansible-<n>`.
3. Ensure IPv6-enabled bridge network `ansible-dualstack` (fails fast with
a clear message if the network exists without IPv6). a clear message if the network exists without IPv6).
3. Run the container detached: repo mounted at `/ansible` (workdir), SSH 4. Run the container detached: repo mounted at `/ansible` (workdir), local
keys from the `ansible_ssh_keys` volume into `/root/.ssh`, env SSH directory bind-mounted read-only at `/root/.ssh`, env
`ANSIBLE_HOST_KEY_CHECKING=False`, `ANSIBLE_CONFIG=./ansible.cfg`. `ANSIBLE_HOST_KEY_CHECKING=False`, `ANSIBLE_CONFIG=./ansible.cfg`.
4. Write a per-container SSH client config, print name/IPv4/IPv6/OS, then Abort if `docker run` fails.
`docker attach` for interactive use. 5. Print name/IPv4/IPv6/OS, then `docker attach` for interactive use.
The launcher preserves the local SSH configuration and permissions. Standard
key names are discovered by OpenSSH; other filenames require `IdentityFile`
or Ansible's `--private-key /root/.ssh/<filename>`. Host-specific absolute
paths in SSH configuration must also exist inside the container. Encrypted
keys can be loaded into an agent started inside the container with
`eval "$(ssh-agent -s)"` followed by `ssh-add /root/.ssh/<filename>`.
## Controller-Side Artifacts ## Controller-Side Artifacts
@@ -57,3 +68,5 @@ confidence: confirmed
- Changing collections requires updating `docker/requirements.yml` and an - Changing collections requires updating `docker/requirements.yml` and an
image rebuild (AGENTS.md). image rebuild (AGENTS.md).
- Default image tag: `ansible:deb13`. - Default image tag: `ansible:deb13`.
- Build from the repository root with `docker build -t ansible:deb13 docker/`.
- SSH keys are supplied at runtime, not embedded in the image.
+5 -1
View File
@@ -4,7 +4,7 @@ type: technical
status: active status: active
title: Security title: Security
created: '2026-09-09' created: '2026-09-09'
updated: '2026-09-09' updated: '2026-10-11'
tags: tags:
- technical - technical
- security - security
@@ -19,6 +19,7 @@ source_paths:
- roles/monitoring/tasks/configure-psk.yml - roles/monitoring/tasks/configure-psk.yml
- roles/bootstrap/defaults/main.yml - roles/bootstrap/defaults/main.yml
- ansible.cfg - ansible.cfg
- execute.sh
confidence: confirmed confidence: confirmed
--- ---
@@ -39,6 +40,9 @@ confidence: confirmed
## SSH Posture ## SSH Posture
- Runtime key access: `execute.sh` bind-mounts the caller's `$HOME/.ssh`
(or `SSH_KEY_DIR`) read-only at `/root/.ssh`. It does not rewrite the host
SSH configuration or permissions. Private keys are not baked into the image.
- Controller/transport: `host_key_checking = False`, - Controller/transport: `host_key_checking = False`,
`StrictHostKeyChecking=no`, `UserKnownHostsFile=/dev/null` (ansible.cfg, `StrictHostKeyChecking=no`, `UserKnownHostsFile=/dev/null` (ansible.cfg,
execute.sh, Dockerfile). Deliberate for first-time provisioning; README execute.sh, Dockerfile). Deliberate for first-time provisioning; README
+2 -2
View File
@@ -11,8 +11,8 @@ Connects wiki documents to source paths. Created during the 2026-09-09 scan.
| [MOD-005 Healthcheck](../technical/modules/MOD-005-healthcheck-role.md) | `playbooks/os-updates-deb.yml`, `roles/healthcheck/` | Container quality gate | | [MOD-005 Healthcheck](../technical/modules/MOD-005-healthcheck-role.md) | `playbooks/os-updates-deb.yml`, `roles/healthcheck/` | Container quality gate |
| [MOD-006 Hawser](../technical/modules/MOD-006-hawser-role.md) | `playbooks/upgrade-hawser.yml`, `roles/hawser/` | Compose stack update | | [MOD-006 Hawser](../technical/modules/MOD-006-hawser-role.md) | `playbooks/upgrade-hawser.yml`, `roles/hawser/` | Compose stack update |
| [MOD-007 Manage SSH Keys](../technical/modules/MOD-007-manage-ssh-keys-role.md) | `playbooks/hardening/manage-ssh-keys.yml`, `roles/manage-ssh-keys/` | No Debian guard (gap) | | [MOD-007 Manage SSH Keys](../technical/modules/MOD-007-manage-ssh-keys-role.md) | `playbooks/hardening/manage-ssh-keys.yml`, `roles/manage-ssh-keys/` | No Debian guard (gap) |
| [TECH-DEPLOYMENT](../technical/deployment.md) | `execute.sh`, `docker/`, `ansible.cfg` | Runtime environment | | [TECH-DEPLOYMENT](../technical/deployment.md) | `execute.sh`, `docker/`, `ansible.cfg`, `README.md` | Runtime environment; local SSH directory mounted read-only via `SSH_KEY_DIR` |
| [TECH-SECURITY](../technical/security.md) | `vault.yml`, `roles/*/defaults/`, `ansible.cfg`, `roles/monitoring/tasks/configure-psk.yml` | Secrets, SSH, PSK | | [TECH-SECURITY](../technical/security.md) | `vault.yml`, `roles/*/defaults/`, `ansible.cfg`, `execute.sh`, `roles/monitoring/tasks/configure-psk.yml` | Secrets, SSH, PSK; runtime-only local key access |
| [TECH-INTEGRATIONS-ZABBIX](../technical/integrations/zabbix.md) | `roles/monitoring/`, `inventory/group_vars/` | Zabbix + external services | | [TECH-INTEGRATIONS-ZABBIX](../technical/integrations/zabbix.md) | `roles/monitoring/`, `inventory/group_vars/` | Zabbix + external services |
| [NFR-003](../requirements/non-functional/operational-policies.md#nfr-003) | `roles/os-updates/tasks/logging_*.yml`, `roles/healthcheck/tasks/main.yml` | Update log audit trail | | [NFR-003](../requirements/non-functional/operational-policies.md#nfr-003) | `roles/os-updates/tasks/logging_*.yml`, `roles/healthcheck/tasks/main.yml` | Update log audit trail |
| [NFR-006](../requirements/non-functional/operational-policies.md#nfr-006) | `roles/os-updates/tasks/reboot.yml`, `roles/bootstrap/tasks/configure-sysctl.yml` | LXC skips | | [NFR-006](../requirements/non-functional/operational-policies.md#nfr-006) | `roles/os-updates/tasks/reboot.yml`, `roles/bootstrap/tasks/configure-sysctl.yml` | LXC skips |
+30 -2
View File
@@ -33,13 +33,41 @@ gestartet werden können.
### Docker-Ausführungsumgebung ### Docker-Ausführungsumgebung
Damit Playbooks nicht lokal installiert werden müssen, liefert das Repository Damit Playbooks nicht lokal installiert werden müssen, liefert das Repository
ein fertiges Docker-Image. `execute.sh` erstellt ein IPv6-fähiges Bridge-Netzwerk, ein fertiges Docker-Image. Das Image lässt sich vom Repository-Verzeichnis aus
startet einen interaktiven Container und mountet das Repository nach `/ansible`: bauen:
```bash
docker build -t ansible:deb13 docker/
```
`execute.sh` erstellt ein IPv6-fähiges Bridge-Netzwerk, startet einen interaktiven
Container und mountet das Repository nach `/ansible`. Das lokale SSH-Verzeichnis
`~/.ssh` des aufrufenden Benutzers wird schreibgeschützt nach `/root/.ssh`
eingebunden. Damit verwendet SSH im Container deine lokalen Standard-Keys
(z. B. `id_ed25519` oder `id_rsa`) und eine vorhandene SSH-Konfiguration:
```bash ```bash
./execute.sh ./execute.sh
``` ```
Ein anderes lokales Schlüsselverzeichnis kann über `SSH_KEY_DIR` angegeben
werden (Standard: `$HOME/.ssh`). Das Verzeichnis muss vorhanden und lesbar sein:
```bash
SSH_KEY_DIR=/pfad/zu/ssh ./execute.sh
```
Bei einem abweichenden Key-Dateinamen gibst du im Container beispielsweise
`--private-key /root/.ssh/mein_key` beim Ansible-Aufruf an. Pfade in deiner
SSH-Konfiguration müssen im Container erreichbar sein, z. B.
`IdentityFile ~/.ssh/mein_key`. Für passwortgeschützte Keys kannst du im
Container einen SSH-Agent starten und den Key laden:
```bash
eval "$(ssh-agent -s)"
ssh-add /root/.ssh/id_ed25519
```
Im Container stehen Aliase wie `ap` (ansible-playbook), `ag` (ansible-galaxy) Im Container stehen Aliase wie `ap` (ansible-playbook), `ag` (ansible-galaxy)
und `av` (ansible-vault) zur Verfügung. Das Image wird über und `av` (ansible-vault) zur Verfügung. Das Image wird über
`docker/Dockerfile` gebaut, die benötigten Collections werden beim Build `docker/Dockerfile` gebaut, die benötigten Collections werden beim Build
+1 -1
View File
@@ -1,6 +1,6 @@
- hosts: all - hosts: all
become: true become: true
user: admin user: root
vars_files: vars_files:
- vault.yml - vault.yml
tasks: tasks:
+15 -6
View File
@@ -1,6 +1,18 @@
#!/bin/bash #!/bin/bash
defaultimage="ansible:deb13" defaultimage="ansible:deb13"
ssh_key_dir="${SSH_KEY_DIR:-$HOME/.ssh}"
if [ ! -d "$ssh_key_dir" ] || [ ! -r "$ssh_key_dir" ]; then
echo "Lokales SSH-Verzeichnis '$ssh_key_dir' fehlt oder ist nicht lesbar." >&2
echo "Setze SSH_KEY_DIR auf das Verzeichnis mit deinem SSH-Key." >&2
exit 1
fi
case "$ssh_key_dir" in
/*) ;;
*) ssh_key_dir="$(pwd)/$ssh_key_dir" ;;
esac
export ANSIBLE_HOST_KEY_CHECKING=False export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_CONFIG=./ansible.cfg export ANSIBLE_CONFIG=./ansible.cfg
@@ -36,12 +48,10 @@ docker run --rm -dit \
-e ANSIBLE_HOST_KEY_CHECKING=False \ -e ANSIBLE_HOST_KEY_CHECKING=False \
-e ANSIBLE_CONFIG=./ansible.cfg \ -e ANSIBLE_CONFIG=./ansible.cfg \
-v "$(pwd):/ansible" \ -v "$(pwd):/ansible" \
-v ansible_ssh_keys:/root/.ssh \ -v "$ssh_key_dir:/root/.ssh:ro" \
-w /ansible \ -w /ansible \
$defaultimage \ "$defaultimage" \
"/bin/bash" "/bin/bash" || exit "$?"
docker exec "$container_name" sh -lc "mkdir -p /root/.ssh && chmod 700 /root/.ssh && printf 'Host *\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null\n' > /root/.ssh/config && chmod 600 /root/.ssh/config"
container_ipv4=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{if .IPAddress}}{{.IPAddress}}{{end}}{{end}}' "$container_name" 2>/dev/null) container_ipv4=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{if .IPAddress}}{{.IPAddress}}{{end}}{{end}}' "$container_name" 2>/dev/null)
container_ipv6=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{if .GlobalIPv6Address}}{{.GlobalIPv6Address}}{{end}}{{end}}' "$container_name" 2>/dev/null) container_ipv6=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{if .GlobalIPv6Address}}{{.GlobalIPv6Address}}{{end}}{{end}}' "$container_name" 2>/dev/null)
@@ -56,4 +66,3 @@ echo "-----------------------------------"
docker attach "$container_name" docker attach "$container_name"
+2
View File
@@ -33,6 +33,8 @@ debian:
ansible_host: 192.168.212.80 ansible_host: 192.168.212.80
einstein-dns: einstein-dns:
ansible_host: 192.168.212.53 ansible_host: 192.168.212.53
weddigram-devel:
ansible_host: 192.168.212.201
proxmox: proxmox:
hosts: hosts: