Setup erkennt Docker oder Podman und deployt entsprechend
- setup.sh erkennt Engine (Docker, Podman, podman-docker-Wrapper) und Compose-Werkzeug (docker compose, docker-compose, podman-compose, podman compose) - Rootless Podman wird mit Hinweis abgelehnt (Ulimits, Port 443, Zertifikatsrechte) - Als root: vm.max_map_count, firewalld-Port und podman-restart.service setzen - Neue Befehle: up, down, ps, logs, info; WAZUH_SKIP_SYSCTL und CONTAINER_ENGINE - Images voll qualifiziert (docker.io/..., localhost/...) wegen Podman-Short-Name-Policy - Bind-Mounts mit :z fuer SELinux (RHEL) - README: Abschnitt Red Hat / Podman, Befehle ueber setup.sh Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8ddceda9e2
commit
61232af61c
@@ -56,18 +56,43 @@ device changed“), mit dem Diff im Alarmtext.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Voraussetzungen: Docker und docker-compose, ca. 8 GB RAM frei, ca. 10 GB Platz für Images und
|
Voraussetzungen: Docker **oder** Podman, ca. 8 GB RAM frei, ca. 10 GB Platz für Images und Daten.
|
||||||
Daten. Für den Indexer:
|
|
||||||
|
|
||||||
```bash
|
`setup.sh` erkennt die Umgebung selbst (`./setup.sh info` zeigt, was erkannt wurde):
|
||||||
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-wazuh.conf && sudo sysctl --system
|
|
||||||
```
|
| Erkannt | Verwendet |
|
||||||
|
|---|---|
|
||||||
|
| Docker | `docker compose` oder `docker-compose` |
|
||||||
|
| Podman (z. B. RHEL, auch mit podman-docker-Wrapper) | `podman-compose` oder `podman compose` |
|
||||||
|
| SELinux aktiv | Alle Bind-Mounts haben `:z`. Ohne SELinux wirkt das nicht. |
|
||||||
|
|
||||||
|
Als root (`sudo ./setup.sh ...`) passt das Skript das System zusätzlich an:
|
||||||
|
|
||||||
|
- `vm.max_map_count=262144` (dauerhaft in `/etc/sysctl.d/99-wazuh.conf`)
|
||||||
|
- firewalld: Port für das Dashboard freigeben
|
||||||
|
- Podman: `podman-restart.service` aktivieren, damit der Stack nach einem Reboot startet
|
||||||
|
|
||||||
|
Ohne root gibt es dafür nur Hinweise. Mit `WAZUH_SKIP_SYSCTL=1` bleibt der Kernel-Parameter
|
||||||
|
unangetastet. Mit `CONTAINER_ENGINE=docker|podman` lässt sich die Erkennung übersteuern.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./setup.sh # Passwörter (.env), TLS-Zertifikate, SSH-Key ssh/id_ed25519, Images bauen
|
./setup.sh # Passwörter (.env), TLS-Zertifikate, SSH-Key ssh/id_ed25519, Images bauen
|
||||||
nano hosts.yml # Hosts eintragen (siehe hosts.yml.example)
|
nano hosts.yml # Hosts eintragen (siehe hosts.yml.example)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Red Hat / Podman
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dnf install -y podman openssh-clients
|
||||||
|
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm # RHEL 9
|
||||||
|
sudo dnf install -y podman-compose
|
||||||
|
sudo ./setup.sh # Podman bitte als root, alle weiteren Befehle ebenfalls mit sudo
|
||||||
|
```
|
||||||
|
|
||||||
|
Podman muss als root laufen. Rootless scheitert an den Ulimits der Wazuh-Container (memlock,
|
||||||
|
nofile), an Port 443 und an den Zertifikatsrechten. `setup.sh` bricht in diesem Fall mit einem
|
||||||
|
Hinweis ab.
|
||||||
|
|
||||||
### Zielhosts vorbereiten
|
### Zielhosts vorbereiten
|
||||||
|
|
||||||
Auf jedem Host wird ein Benutzer `wazuh-pull` angelegt. Er bekommt die Gruppen
|
Auf jedem Host wird ein Benutzer `wazuh-pull` angelegt. Er bekommt die Gruppen
|
||||||
@@ -87,7 +112,7 @@ Das Skript erst ansehen, dann ausführen: `./setup.sh host-script`
|
|||||||
```bash
|
```bash
|
||||||
./setup.sh keyscan # Host-Keys -> ssh/known_hosts, Fingerprints mit den Hosts vergleichen!
|
./setup.sh keyscan # Host-Keys -> ssh/known_hosts, Fingerprints mit den Hosts vergleichen!
|
||||||
./setup.sh test # prüft Login, Gruppen, Journal-/Datei-Leserechte
|
./setup.sh test # prüft Login, Gruppen, Journal-/Datei-Leserechte
|
||||||
docker-compose up -d
|
./setup.sh up # starten (down, ps, logs [dienst] analog)
|
||||||
./setup.sh passwords # Login fürs Dashboard: https://<server>/ (admin / ...)
|
./setup.sh passwords # Login fürs Dashboard: https://<server>/ (admin / ...)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -143,13 +168,18 @@ Ports 1514 und 1515 sind nicht nach außen veröffentlicht. Nur der Collector er
|
|||||||
## Fehlersuche
|
## Fehlersuche
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose logs -f sshpull.collector # Verbindungen/Reconnects pro Host
|
./setup.sh logs sshpull.collector # Verbindungen/Reconnects pro Host
|
||||||
docker-compose exec wazuh.manager grep -i agentless /var/ossec/logs/ossec.log
|
./setup.sh logs wazuh.manager | grep -i agentless
|
||||||
docker-compose exec wazuh.manager ls -la /remote-logs/web01/ # kommen Logs an?
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Für `exec` die passende Engine nehmen (`docker` oder `sudo podman`). Die Containernamen zeigt
|
||||||
|
`./setup.sh ps`, z. B.:
|
||||||
|
`sudo podman exec wazuh_wazuh.manager_1 ls -la /remote-logs/web01/`
|
||||||
|
|
||||||
- `journal=WARNUNG:nur-eigene-Logs…` bei `./setup.sh test`: Der Benutzer ist nicht in der
|
- `journal=WARNUNG:nur-eigene-Logs…` bei `./setup.sh test`: Der Benutzer ist nicht in der
|
||||||
Gruppe `systemd-journal`. Danach neu einloggen bzw. den Collector neu starten.
|
Gruppe `systemd-journal`. Danach neu einloggen bzw. den Collector neu starten.
|
||||||
|
- Podman: Hängt `./setup.sh up` bei „podman wait“, konnte ein Container nicht angelegt werden.
|
||||||
|
Die Ursache zeigt `sudo podman-compose --verbose up -d 2>&1 | grep -i error`.
|
||||||
- `Host key verification failed`: `./setup.sh keyscan` ausführen, oder in `hosts.yml`
|
- `Host key verification failed`: `./setup.sh keyscan` ausführen, oder in `hosts.yml`
|
||||||
`ssh.host_key_checking: accept-new` setzen.
|
`ssh.host_key_checking: accept-new` setzen.
|
||||||
- Agentless-Checks laufen das erste Mal kurz nach dem Start, danach alle `interval` Sekunden.
|
- Agentless-Checks laufen das erste Mal kurz nach dem Start, danach alle `interval` Sekunden.
|
||||||
@@ -157,6 +187,6 @@ docker-compose exec wazuh.manager ls -la /remote-logs/web01/ # kommen Logs an?
|
|||||||
laufen nacheinander. Bei vielen Hosts mit großen Pfaden (`/usr`) das `interval` großzügig
|
laufen nacheinander. Bei vielen Hosts mit großen Pfaden (`/usr`) das `interval` großzügig
|
||||||
wählen.
|
wählen.
|
||||||
- Baseline eines Hosts neu anlegen (z. B. nach einem gewollten Update):
|
- Baseline eines Hosts neu anlegen (z. B. nach einem gewollten Update):
|
||||||
`docker-compose exec wazuh.manager rm /var/ossec/agentless/.sshpull/web01.json`
|
`<docker|podman> exec wazuh_wazuh.manager_1 rm /var/ossec/agentless/.sshpull/web01.json`
|
||||||
- Ohne `sudo` sind root-only Dateien (z. B. `/etc/shadow`, Host-Keys) nur über Größe, Rechte
|
- Ohne `sudo` sind root-only Dateien (z. B. `/etc/shadow`, Host-Keys) nur über Größe, Rechte
|
||||||
und Besitzer überwacht, nicht über den Inhalt.
|
und Besitzer überwacht, nicht über den Inhalt.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM python:3.12-slim
|
FROM docker.io/library/python:3.12-slim
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends openssh-client tzdata \
|
&& apt-get install -y --no-install-recommends openssh-client tzdata \
|
||||||
|
|||||||
+28
-24
@@ -2,7 +2,11 @@
|
|||||||
# + sshpull-collector: holt Logs per SSH von Hosts, auf die nur per SSH zugegriffen werden kann
|
# + sshpull-collector: holt Logs per SSH von Hosts, auf die nur per SSH zugegriffen werden kann
|
||||||
# + Manager-Erweiterung: Agentless-Integritaets- und Befehls-Checks per SSH
|
# + Manager-Erweiterung: Agentless-Integritaets- und Befehls-Checks per SSH
|
||||||
#
|
#
|
||||||
# Vor dem ersten Start: ./setup.sh
|
# Vor dem ersten Start: ./setup.sh (erkennt Docker/Podman selbst, danach ./setup.sh up)
|
||||||
|
#
|
||||||
|
# Kompatibel mit docker compose, docker-compose, podman-compose und "podman compose":
|
||||||
|
# - Images voll qualifiziert (docker.io/..., localhost/...) wegen Podman-Short-Name-Policy
|
||||||
|
# - Bind-Mounts mit ":z" fuer SELinux (RHEL/Fedora); ohne SELinux wirkungslos
|
||||||
|
|
||||||
services:
|
services:
|
||||||
wazuh.manager:
|
wazuh.manager:
|
||||||
@@ -11,7 +15,7 @@ services:
|
|||||||
dockerfile: manager/Dockerfile
|
dockerfile: manager/Dockerfile
|
||||||
args:
|
args:
|
||||||
WAZUH_VERSION: ${WAZUH_VERSION}
|
WAZUH_VERSION: ${WAZUH_VERSION}
|
||||||
image: sshpull/wazuh-manager:${WAZUH_VERSION}
|
image: localhost/sshpull/wazuh-manager:${WAZUH_VERSION}
|
||||||
hostname: wazuh.manager
|
hostname: wazuh.manager
|
||||||
restart: always
|
restart: always
|
||||||
ulimits:
|
ulimits:
|
||||||
@@ -49,17 +53,17 @@ services:
|
|||||||
- wazuh_wodles:/var/ossec/wodles
|
- wazuh_wodles:/var/ossec/wodles
|
||||||
- filebeat_etc:/etc/filebeat
|
- filebeat_etc:/etc/filebeat
|
||||||
- filebeat_var:/var/lib/filebeat
|
- filebeat_var:/var/lib/filebeat
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key:ro,z
|
||||||
- ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf:ro
|
- ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf:ro,z
|
||||||
# sshpull
|
# sshpull
|
||||||
- ./hosts.yml:/sshpull/hosts.yml:ro
|
- ./hosts.yml:/sshpull/hosts.yml:ro,z
|
||||||
- ./ssh:/sshpull/ssh:ro
|
- ./ssh:/sshpull/ssh:ro,z
|
||||||
- remote_logs:/remote-logs:ro
|
- remote_logs:/remote-logs:ro
|
||||||
|
|
||||||
wazuh.indexer:
|
wazuh.indexer:
|
||||||
image: wazuh/wazuh-indexer:${WAZUH_VERSION}
|
image: docker.io/wazuh/wazuh-indexer:${WAZUH_VERSION}
|
||||||
hostname: wazuh.indexer
|
hostname: wazuh.indexer
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
@@ -73,16 +77,16 @@ services:
|
|||||||
hard: 65536
|
hard: 65536
|
||||||
volumes:
|
volumes:
|
||||||
- wazuh-indexer-data:/var/lib/wazuh-indexer
|
- wazuh-indexer-data:/var/lib/wazuh-indexer
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem:ro,z
|
||||||
- ./config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml:ro
|
- ./config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml:ro,z
|
||||||
- ./config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml:ro
|
- ./config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml:ro,z
|
||||||
|
|
||||||
wazuh.dashboard:
|
wazuh.dashboard:
|
||||||
image: wazuh/wazuh-dashboard:${WAZUH_VERSION}
|
image: docker.io/wazuh/wazuh-dashboard:${WAZUH_VERSION}
|
||||||
hostname: wazuh.dashboard
|
hostname: wazuh.dashboard
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -96,10 +100,10 @@ services:
|
|||||||
- API_USERNAME=wazuh-wui
|
- API_USERNAME=wazuh-wui
|
||||||
- API_PASSWORD=${API_PASSWORD}
|
- API_PASSWORD=${API_PASSWORD}
|
||||||
volumes:
|
volumes:
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem:ro,z
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem:ro
|
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem:ro,z
|
||||||
- ./config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml:ro
|
- ./config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml:ro,z
|
||||||
- wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config
|
- wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config
|
||||||
- wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom
|
- wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -110,7 +114,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: collector/Dockerfile
|
dockerfile: collector/Dockerfile
|
||||||
image: sshpull/collector:latest
|
image: localhost/sshpull/collector:latest
|
||||||
hostname: sshpull.collector
|
hostname: sshpull.collector
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
@@ -118,8 +122,8 @@ services:
|
|||||||
- MANAGER_HOST=wazuh.manager
|
- MANAGER_HOST=wazuh.manager
|
||||||
- MAX_LOG_MB=${COLLECTOR_MAX_LOG_MB}
|
- MAX_LOG_MB=${COLLECTOR_MAX_LOG_MB}
|
||||||
volumes:
|
volumes:
|
||||||
- ./hosts.yml:/sshpull/hosts.yml:ro
|
- ./hosts.yml:/sshpull/hosts.yml:ro,z
|
||||||
- ./ssh:/ssh # rw, damit "keyscan" known_hosts schreiben kann
|
- ./ssh:/ssh:z # rw, damit "keyscan" known_hosts schreiben kann
|
||||||
- remote_logs:/remote-logs
|
- remote_logs:/remote-logs
|
||||||
- collector_state:/state
|
- collector_state:/state
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Hosts, die per SSH ueberwacht werden.
|
# Hosts, die per SSH ueberwacht werden.
|
||||||
# Nach Aenderungen: docker-compose up -d --force-recreate wazuh.manager sshpull.collector
|
# Nach Aenderungen: ./setup.sh apply (Manager + Collector neu starten)
|
||||||
#
|
#
|
||||||
# Pro Host gibt es drei Bausteine (alle optional, Defaults siehe unten):
|
# Pro Host gibt es drei Bausteine (alle optional, Defaults siehe unten):
|
||||||
# logs Logs werden dauerhaft per SSH gestreamt (journald und/oder Dateien)
|
# logs Logs werden dauerhaft per SSH gestreamt (journald und/oder Dateien)
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
ARG WAZUH_VERSION=4.14.8
|
ARG WAZUH_VERSION=4.14.8
|
||||||
FROM wazuh/wazuh-manager:${WAZUH_VERSION}
|
FROM docker.io/wazuh/wazuh-manager:${WAZUH_VERSION}
|
||||||
|
|
||||||
# openssh-clients: Agentless per SSH; diffutils: wazuh-agentlessd vergleicht Befehlsausgaben mit diff
|
# openssh-clients: Agentless per SSH; diffutils: wazuh-agentlessd vergleicht Befehlsausgaben mit diff
|
||||||
RUN dnf install -y openssh-clients diffutils && dnf clean all && rm -rf /var/cache/dnf
|
RUN dnf install -y openssh-clients diffutils && dnf clean all && rm -rf /var/cache/dnf
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Einrichtung und Hilfsbefehle fuer den Wazuh-SSH-Pull-Stack.
|
# Einrichtung und Betrieb des Wazuh-SSH-Pull-Stacks.
|
||||||
|
# Erkennt selbst, ob Docker oder Podman vorhanden ist (RHEL: Podman), und das passende
|
||||||
|
# Compose-Werkzeug (docker compose, docker-compose, podman-compose, podman compose).
|
||||||
#
|
#
|
||||||
# ./setup.sh Erstinstallation (Passwoerter, Zertifikate, SSH-Key, Images)
|
# ./setup.sh Erstinstallation (Passwoerter, Zertifikate, SSH-Key, Images)
|
||||||
|
# ./setup.sh up Stack starten (+ Kernel-Parameter, Firewall, Autostart als root)
|
||||||
|
# ./setup.sh down Stack stoppen
|
||||||
|
# ./setup.sh ps | logs [dienst]
|
||||||
# ./setup.sh host-script Skript zum Vorbereiten eines Zielhosts ausgeben
|
# ./setup.sh host-script Skript zum Vorbereiten eines Zielhosts ausgeben
|
||||||
# ./setup.sh host-script | ssh admin@host sudo sh
|
# ./setup.sh host-script | ssh admin@host sudo sh
|
||||||
# Optionen: --sudo (NOPASSWD-sudo), --tunnel (fuer agent_tunnel),
|
# Optionen: --sudo (NOPASSWD-sudo), --tunnel (fuer agent_tunnel),
|
||||||
@@ -10,15 +15,77 @@
|
|||||||
# ./setup.sh test SSH-Zugriff und Rechte auf allen Hosts pruefen
|
# ./setup.sh test SSH-Zugriff und Rechte auf allen Hosts pruefen
|
||||||
# ./setup.sh apply hosts.yml uebernehmen (Manager + Collector neu starten)
|
# ./setup.sh apply hosts.yml uebernehmen (Manager + Collector neu starten)
|
||||||
# ./setup.sh passwords Zugangsdaten anzeigen
|
# ./setup.sh passwords Zugangsdaten anzeigen
|
||||||
|
# ./setup.sh info Erkannte Umgebung anzeigen
|
||||||
|
#
|
||||||
|
# Mit Podman bitte als root ausfuehren (sudo ./setup.sh ...), siehe check_rootless.
|
||||||
|
# Erkennung uebersteuern: CONTAINER_ENGINE=docker|podman ./setup.sh ...
|
||||||
|
# Kernel-Parameter nicht anfassen: WAZUH_SKIP_SYSCTL=1 ./setup.sh ...
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
if docker compose version >/dev/null 2>&1; then DC=(docker compose); else DC=(docker-compose); fi
|
|
||||||
|
|
||||||
info() { echo -e "\e[1;32m==>\e[0m $*"; }
|
info() { echo -e "\e[1;32m==>\e[0m $*"; }
|
||||||
warn() { echo -e "\e[1;33m!!\e[0m $*" >&2; }
|
warn() { echo -e "\e[1;33m!!\e[0m $*" >&2; }
|
||||||
die() { echo -e "\e[1;31mFEHLER:\e[0m $*" >&2; exit 1; }
|
die() { echo -e "\e[1;31mFEHLER:\e[0m $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
is_root() { [ "$(id -u)" -eq 0 ]; }
|
||||||
|
|
||||||
|
ENGINE=""
|
||||||
|
DC=()
|
||||||
|
SELINUX=no
|
||||||
|
|
||||||
|
detect_runtime() {
|
||||||
|
[ -n "$ENGINE" ] && return
|
||||||
|
ENGINE="${CONTAINER_ENGINE:-}"
|
||||||
|
if [ -z "$ENGINE" ]; then
|
||||||
|
# Auf RHEL ist "docker" oft nur der podman-docker-Wrapper -> dann Podman nehmen
|
||||||
|
if command -v docker >/dev/null 2>&1 && ! docker --version 2>/dev/null | grep -qi podman; then
|
||||||
|
ENGINE=docker
|
||||||
|
elif command -v podman >/dev/null 2>&1; then
|
||||||
|
ENGINE=podman
|
||||||
|
else
|
||||||
|
die "Weder Docker noch Podman gefunden. RHEL: sudo dnf install -y podman"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$ENGINE" in
|
||||||
|
docker)
|
||||||
|
docker info >/dev/null 2>&1 || die "Docker-Daemon nicht erreichbar (laeuft dockerd? Benutzer in Gruppe docker?)"
|
||||||
|
if docker compose version >/dev/null 2>&1; then DC=(docker compose)
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then DC=(docker-compose)
|
||||||
|
else die "Docker Compose fehlt (Paket docker-compose-plugin)"; fi
|
||||||
|
;;
|
||||||
|
podman)
|
||||||
|
check_rootless
|
||||||
|
if command -v podman-compose >/dev/null 2>&1; then DC=(podman-compose)
|
||||||
|
elif podman compose version >/dev/null 2>&1; then DC=(podman compose)
|
||||||
|
else
|
||||||
|
die "podman-compose fehlt. RHEL 9:
|
||||||
|
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
|
||||||
|
sudo dnf install -y podman-compose
|
||||||
|
oder: sudo pip3 install podman-compose"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) die "CONTAINER_ENGINE muss docker oder podman sein" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then
|
||||||
|
SELINUX=yes # docker-compose.yml nutzt ":z" auf allen Bind-Mounts
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_rootless() {
|
||||||
|
# Rootless Podman scheitert hier an: memlock/nofile-Ulimits der Wazuh-Container,
|
||||||
|
# Port 443 (< 1024) und Zertifikaten, die im Container per chown an UIDs 999/1000 gehen.
|
||||||
|
if [ "$(podman info --format '{{.Host.Security.Rootless}}' 2>/dev/null)" = "true" ]; then
|
||||||
|
die "Podman laeuft rootless. Wazuh braucht erhoehte Ulimits und Port $(env_get DASHBOARD_PORT 2>/dev/null || echo 443).
|
||||||
|
Bitte als root ausfuehren: sudo ./setup.sh ${CMD:-}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker oder Podman (gleiche CLI fuer run/images/info)
|
||||||
|
engine() { "$ENGINE" "$@"; }
|
||||||
|
compose() { "${DC[@]}" "$@"; }
|
||||||
|
|
||||||
genpw() {
|
genpw() {
|
||||||
# Erfuellt die Wazuh-API-Richtlinie (Gross, klein, Ziffer, Sonderzeichen) und
|
# Erfuellt die Wazuh-API-Richtlinie (Gross, klein, Ziffer, Sonderzeichen) und
|
||||||
# enthaelt keine Zeichen, die in den sed-Aufrufen der Wazuh-Images stoeren.
|
# enthaelt keine Zeichen, die in den sed-Aufrufen der Wazuh-Images stoeren.
|
||||||
@@ -29,18 +96,64 @@ set_env() { # set_env KEY VALUE
|
|||||||
if grep -q "^$1=" .env; then sed -i "s|^$1=.*|$1=$2|" .env; else echo "$1=$2" >> .env; fi
|
if grep -q "^$1=" .env; then sed -i "s|^$1=.*|$1=$2|" .env; else echo "$1=$2" >> .env; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
env_get() { grep "^$1=" .env | cut -d= -f2-; }
|
env_get() { grep "^$1=" .env 2>/dev/null | cut -d= -f2-; }
|
||||||
|
|
||||||
cmd_init() {
|
tune_kernel() {
|
||||||
command -v docker >/dev/null || die "docker fehlt"
|
|
||||||
|
|
||||||
# --- Kernel-Parameter fuer den Indexer ---------------------------------
|
|
||||||
local mmc
|
local mmc
|
||||||
mmc=$(cat /proc/sys/vm/max_map_count)
|
mmc=$(cat /proc/sys/vm/max_map_count)
|
||||||
if [ "$mmc" -lt 262144 ]; then
|
[ "$mmc" -ge 262144 ] && return
|
||||||
warn "vm.max_map_count ist $mmc (empfohlen 262144). Dauerhaft setzen mit:"
|
[ "${WAZUH_SKIP_SYSCTL:-0}" = 1 ] && { warn "vm.max_map_count=$mmc, Anpassung uebersprungen (WAZUH_SKIP_SYSCTL=1)"; return; }
|
||||||
|
if is_root; then
|
||||||
|
info "Setze vm.max_map_count=262144 (dauerhaft in /etc/sysctl.d/99-wazuh.conf)"
|
||||||
|
echo 'vm.max_map_count=262144' > /etc/sysctl.d/99-wazuh.conf
|
||||||
|
sysctl -q -w vm.max_map_count=262144
|
||||||
|
else
|
||||||
|
warn "vm.max_map_count ist $mmc (benoetigt 262144). Als root setzen mit:"
|
||||||
warn " echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-wazuh.conf && sudo sysctl --system"
|
warn " echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-wazuh.conf && sudo sysctl --system"
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
open_firewall() {
|
||||||
|
local port
|
||||||
|
port=$(env_get DASHBOARD_PORT)
|
||||||
|
command -v firewall-cmd >/dev/null 2>&1 && firewall-cmd --state >/dev/null 2>&1 || return 0
|
||||||
|
if firewall-cmd --query-port="$port/tcp" >/dev/null 2>&1; then return 0; fi
|
||||||
|
if is_root; then
|
||||||
|
info "firewalld: oeffne Port $port/tcp fuer das Dashboard"
|
||||||
|
firewall-cmd -q --permanent --add-port="$port/tcp" && firewall-cmd -q --reload
|
||||||
|
else
|
||||||
|
warn "firewalld aktiv, Port $port/tcp nicht freigegeben: sudo firewall-cmd --permanent --add-port=$port/tcp && sudo firewall-cmd --reload"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_autostart() {
|
||||||
|
# Docker startet "restart: always"-Container selbst; Podman hat keinen Daemon,
|
||||||
|
# dafuer gibt es podman-restart.service.
|
||||||
|
[ "$ENGINE" = podman ] || return 0
|
||||||
|
command -v systemctl >/dev/null 2>&1 || return 0
|
||||||
|
if systemctl is-enabled podman-restart.service >/dev/null 2>&1; then return 0; fi
|
||||||
|
if is_root; then
|
||||||
|
info "Aktiviere podman-restart.service (Container starten nach Reboot)"
|
||||||
|
systemctl enable -q podman-restart.service
|
||||||
|
else
|
||||||
|
warn "Autostart nach Reboot: sudo systemctl enable podman-restart.service"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_info() {
|
||||||
|
detect_runtime
|
||||||
|
echo "Engine: $ENGINE ($("$ENGINE" --version | head -1))"
|
||||||
|
echo "Compose: ${DC[*]}"
|
||||||
|
echo "SELinux: $SELINUX"
|
||||||
|
echo "root: $(is_root && echo ja || echo nein)"
|
||||||
|
echo "max_map: $(cat /proc/sys/vm/max_map_count)"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_init() {
|
||||||
|
detect_runtime
|
||||||
|
info "Container-Umgebung: $ENGINE mit ${DC[*]} (SELinux: $SELINUX)"
|
||||||
|
command -v ssh-keygen >/dev/null || die "ssh-keygen fehlt (RHEL: dnf install openssh-clients)"
|
||||||
|
tune_kernel
|
||||||
|
|
||||||
# --- .env + Passwoerter -------------------------------------------------
|
# --- .env + Passwoerter -------------------------------------------------
|
||||||
[ -f .env ] || cp .env.example .env
|
[ -f .env ] || cp .env.example .env
|
||||||
@@ -55,8 +168,8 @@ cmd_init() {
|
|||||||
if [ ! -f config/wazuh_indexer/internal_users.yml ]; then
|
if [ ! -f config/wazuh_indexer/internal_users.yml ]; then
|
||||||
info "Erzeuge Indexer-Benutzer (Passwort-Hashes)"
|
info "Erzeuge Indexer-Benutzer (Passwort-Hashes)"
|
||||||
hash() {
|
hash() {
|
||||||
docker run --rm -e JAVA_HOME=/usr/share/wazuh-indexer/jdk --entrypoint bash \
|
engine run --rm -e JAVA_HOME=/usr/share/wazuh-indexer/jdk --entrypoint bash \
|
||||||
"wazuh/wazuh-indexer:$version" \
|
"docker.io/wazuh/wazuh-indexer:$version" \
|
||||||
/usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh -p "$1" 2>/dev/null | tail -1
|
/usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh -p "$1" 2>/dev/null | tail -1
|
||||||
}
|
}
|
||||||
local h_admin h_kibana
|
local h_admin h_kibana
|
||||||
@@ -89,18 +202,18 @@ EOF
|
|||||||
if [ ! -f config/wazuh_indexer_ssl_certs/root-ca.pem ]; then
|
if [ ! -f config/wazuh_indexer_ssl_certs/root-ca.pem ]; then
|
||||||
info "Erzeuge TLS-Zertifikate"
|
info "Erzeuge TLS-Zertifikate"
|
||||||
mkdir -p config/wazuh_indexer_ssl_certs
|
mkdir -p config/wazuh_indexer_ssl_certs
|
||||||
docker run --rm \
|
engine run --rm \
|
||||||
-e CERT_TOOL_VERSION="${version%.*}" \
|
-e CERT_TOOL_VERSION="${version%.*}" \
|
||||||
-v "$PWD/config/wazuh_indexer_ssl_certs/:/certificates/" \
|
-v "$PWD/config/wazuh_indexer_ssl_certs/:/certificates/:z" \
|
||||||
-v "$PWD/config/certs.yml:/config/certs.yml:ro" \
|
-v "$PWD/config/certs.yml:/config/certs.yml:ro,z" \
|
||||||
wazuh/wazuh-certs-generator:0.0.4
|
docker.io/wazuh/wazuh-certs-generator:0.0.4
|
||||||
[ -f config/wazuh_indexer_ssl_certs/root-ca.pem ] || die "Zertifikate wurden nicht erzeugt"
|
[ -f config/wazuh_indexer_ssl_certs/root-ca.pem ] || die "Zertifikate wurden nicht erzeugt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- SSH-Schluessel ----------------------------------------------------
|
# --- SSH-Schluessel ----------------------------------------------------
|
||||||
if [ ! -f ssh/id_ed25519 ]; then
|
if [ ! -f ssh/id_ed25519 ]; then
|
||||||
info "Erzeuge SSH-Schluessel ssh/id_ed25519"
|
info "Erzeuge SSH-Schluessel ssh/id_ed25519"
|
||||||
ssh-keygen -q -t ed25519 -N "" -C "wazuh-sshpull@$(hostname)" -f ssh/id_ed25519
|
ssh-keygen -q -t ed25519 -N "" -C "wazuh-sshpull@$(uname -n)" -f ssh/id_ed25519
|
||||||
fi
|
fi
|
||||||
touch ssh/known_hosts
|
touch ssh/known_hosts
|
||||||
chmod 600 ssh/id_ed25519
|
chmod 600 ssh/id_ed25519
|
||||||
@@ -108,7 +221,7 @@ EOF
|
|||||||
[ -f hosts.yml ] || { cp hosts.yml.example hosts.yml; warn "hosts.yml aus Beispiel angelegt - bitte anpassen!"; }
|
[ -f hosts.yml ] || { cp hosts.yml.example hosts.yml; warn "hosts.yml aus Beispiel angelegt - bitte anpassen!"; }
|
||||||
|
|
||||||
info "Baue Images"
|
info "Baue Images"
|
||||||
"${DC[@]}" build
|
compose build
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
@@ -117,7 +230,7 @@ Fertig. Naechste Schritte:
|
|||||||
2. Zielhosts vorbereiten: ./setup.sh host-script | ssh admin@HOST sudo sh
|
2. Zielhosts vorbereiten: ./setup.sh host-script | ssh admin@HOST sudo sh
|
||||||
3. Host-Keys holen: ./setup.sh keyscan (Fingerprints pruefen!)
|
3. Host-Keys holen: ./setup.sh keyscan (Fingerprints pruefen!)
|
||||||
4. Zugriff testen: ./setup.sh test
|
4. Zugriff testen: ./setup.sh test
|
||||||
5. Starten: ${DC[*]} up -d
|
5. Starten: ./setup.sh up
|
||||||
6. Dashboard: https://<dieser-server>:$(env_get DASHBOARD_PORT) (admin / siehe ./setup.sh passwords)
|
6. Dashboard: https://<dieser-server>:$(env_get DASHBOARD_PORT) (admin / siehe ./setup.sh passwords)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@@ -165,15 +278,30 @@ EOF
|
|||||||
echo 'echo "Host vorbereitet: Benutzer $U ($(id $U))"'
|
echo 'echo "Host vorbereitet: Benutzer $U ($(id $U))"'
|
||||||
}
|
}
|
||||||
|
|
||||||
case "${1:-init}" in
|
cmd_up() {
|
||||||
|
detect_runtime
|
||||||
|
tune_kernel
|
||||||
|
compose up -d
|
||||||
|
enable_autostart
|
||||||
|
open_firewall
|
||||||
|
info "Gestartet ($ENGINE). Dashboard in 1-3 Minuten: https://$(uname -n):$(env_get DASHBOARD_PORT)"
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD="${1:-init}"
|
||||||
|
case "$CMD" in
|
||||||
init) cmd_init ;;
|
init) cmd_init ;;
|
||||||
|
up) cmd_up ;;
|
||||||
|
down) detect_runtime; compose down ;;
|
||||||
|
ps) detect_runtime; compose ps ;;
|
||||||
|
logs) shift; detect_runtime; compose logs -f --tail=100 "$@" ;;
|
||||||
|
info) cmd_info ;;
|
||||||
host-script) shift; cmd_host_script "$@" ;;
|
host-script) shift; cmd_host_script "$@" ;;
|
||||||
keyscan) "${DC[@]}" run --rm --no-deps sshpull.collector keyscan ;;
|
keyscan) detect_runtime; compose run --rm --no-deps sshpull.collector keyscan ;;
|
||||||
test) "${DC[@]}" run --rm --no-deps sshpull.collector test ;;
|
test) detect_runtime; compose run --rm --no-deps sshpull.collector test ;;
|
||||||
apply) "${DC[@]}" up -d --force-recreate wazuh.manager sshpull.collector ;;
|
apply) detect_runtime; compose up -d --force-recreate wazuh.manager sshpull.collector ;;
|
||||||
passwords)
|
passwords)
|
||||||
echo "Dashboard: admin / $(env_get INDEXER_PASSWORD)"
|
echo "Dashboard: admin / $(env_get INDEXER_PASSWORD)"
|
||||||
echo "Wazuh-API: wazuh-wui / $(env_get API_PASSWORD)"
|
echo "Wazuh-API: wazuh-wui / $(env_get API_PASSWORD)"
|
||||||
;;
|
;;
|
||||||
*) sed -n '2,13p' "$0"; exit 2 ;;
|
*) sed -n '2,23p' "$0"; exit 2 ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user