feat(waf): Phase 4 — Packaging, CRS, systemd, sudoers — v1.2.69

- Makefile: edgeguard-waf zu BINARIES hinzugefügt
- deploy/systemd/edgeguard-waf.service: systemd-Unit (User=edgeguard,
  After=postgresql + edgeguard-api, Hardening, ReadWritePaths=/var/log/edgeguard)
- build-package.sh: edgeguard-waf Binary + Service ins .deb
- postinst: OWASP CRS v4.7.0 Download bei Erstinstall nach
  /usr/share/edgeguard/waf/crs/; graceful wenn kein Internet vorhanden
- postinst: edgeguard-waf.service enable + start bei install/upgrade
- postinst: sudoers für start/stop/enable/disable/restart edgeguard-waf.service
- system.go: edgeguard-waf in servicesToCheck + toggleAllowlist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-06-02 16:03:37 +02:00
parent bf16ce6666
commit 3a122ffb0f
6 changed files with 75 additions and 5 deletions

View File

@@ -4,7 +4,7 @@
GO ?= $(shell which go || echo /usr/local/go/bin/go)
MODULE := git.netcell-it.de/projekte/edgeguard-native
BINARIES := edgeguard-api edgeguard-scheduler edgeguard-ctl
BINARIES := edgeguard-api edgeguard-scheduler edgeguard-ctl edgeguard-waf
VERSION := $(shell cat VERSION 2>/dev/null || echo 0.0.1-dev)
LDFLAGS := -s -w -X main.version=$(VERSION)
GOFLAGS := -trimpath -mod=readonly

View File

@@ -1 +1 @@
1.2.68
1.2.69

View File

@@ -0,0 +1,32 @@
[Unit]
Description=EdgeGuard WAF SPOE Agent (Coraza/OWASP CRS)
Documentation=https://git.netcell-it.de/projekte/edgeguard-native
After=network-online.target postgresql.service edgeguard-api.service
Wants=network-online.target
Requires=postgresql.service
[Service]
Type=simple
User=edgeguard
Group=edgeguard
ExecStart=/usr/bin/edgeguard-waf
Restart=on-failure
RestartSec=5
# Hardening — WAF agent only needs DB access and one TCP listen socket.
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
PrivateTmp=true
PrivateDevices=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallFilter=@system-service
# CRS rules are read from /usr/share/edgeguard/waf/crs/ (read-only, OK).
# Alerts/logs are written to /var/log/edgeguard/.
ReadWritePaths=/var/log/edgeguard
[Install]
WantedBy=multi-user.target

View File

@@ -197,6 +197,7 @@ var servicesToCheck = []struct{ Label, Unit string }{
{"postgresql", "postgresql"},
{"crowdsec", "crowdsec"},
{"crowdsec-firewall-bouncer", "crowdsec-firewall-bouncer"},
{"edgeguard-waf", "edgeguard-waf"},
}
type serviceStatus struct {
@@ -639,6 +640,7 @@ func (h *SystemHandler) ServiceRestart(c *gin.Context) {
var toggleAllowlist = map[string]bool{
"crowdsec": true,
"crowdsec-firewall-bouncer": true,
"edgeguard-waf": true,
"squid": true,
"unbound": true,
}

View File

@@ -165,6 +165,12 @@ edgeguard ALL=(root) NOPASSWD: /usr/bin/cscli collections list -o json
edgeguard ALL=(root) NOPASSWD: /usr/bin/cscli collections install *
edgeguard ALL=(root) NOPASSWD: /usr/bin/cscli collections remove *
edgeguard ALL=(root) NOPASSWD: /usr/bin/cscli version
# WAF agent service control
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl start edgeguard-waf.service
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl stop edgeguard-waf.service
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl enable edgeguard-waf.service
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl disable edgeguard-waf.service
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl restart edgeguard-waf.service
# CrowdSec service toggle (start/stop/enable/disable)
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl start crowdsec.service
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl stop crowdsec.service
@@ -790,10 +796,38 @@ EOSQL
/etc/systemd/system/haproxy.service.d/edgeguard.conf
fi
# ── OWASP Core Rule Set (CRS) für edgeguard-waf ─────────────────────
# Nur beim Erstinstall — kein Überschreiben bei Upgrades damit
# admins angepasste crs-setup.conf behalten können.
WAF_CRS_DIR="/usr/share/edgeguard/waf/crs"
if [ "$1" = "configure" ] && [ -z "$2" ] && [ ! -d "$WAF_CRS_DIR/rules" ]; then
CRS_VERSION="4.7.0"
echo "postinst: installing OWASP CRS v${CRS_VERSION}..."
install -d -m 0755 "$WAF_CRS_DIR/rules"
CRS_TMP="$(mktemp -d)"
if curl -sL --max-time 60 \
"https://github.com/coreruleset/coreruleset/archive/refs/tags/v${CRS_VERSION}.tar.gz" \
-o "${CRS_TMP}/crs.tar.gz" 2>/dev/null; then
tar xzf "${CRS_TMP}/crs.tar.gz" -C "${CRS_TMP}" 2>/dev/null || true
CRS_SRC="${CRS_TMP}/coreruleset-${CRS_VERSION}"
if [ -f "${CRS_SRC}/crs-setup.conf.example" ]; then
install -m 0644 "${CRS_SRC}/crs-setup.conf.example" "${WAF_CRS_DIR}/crs-setup.conf"
install -m 0644 "${CRS_SRC}/rules/"*.conf "${WAF_CRS_DIR}/rules/" 2>/dev/null || true
chown -R "$EG_USER":"$EG_USER" "$WAF_CRS_DIR"
echo "postinst: OWASP CRS v${CRS_VERSION} installed to ${WAF_CRS_DIR}"
else
echo "postinst: CRS download succeeded but layout unexpected — skipping" >&2
fi
else
echo "postinst: CRS download failed (no internet?) — WAF usable without CRS" >&2
fi
rm -rf "${CRS_TMP}"
fi
# ── systemd: pick up new units + restart haproxy with our cfg
systemctl daemon-reload
systemctl restart haproxy.service || true
systemctl enable edgeguard-api.service edgeguard-scheduler.service || true
systemctl enable edgeguard-api.service edgeguard-scheduler.service edgeguard-waf.service || true
# restart (NICHT enable --now): das neue Unit-File könnte ein
# geänderter ReadWritePaths-Block sein (Befund 1.0.87:
# /var/lib/apt fehlte → apt-get update aus dem Update-Banner-
@@ -802,7 +836,7 @@ EOSQL
# der laufende Daemon behält das alte Sandbox-Snapshot bis zum
# restart. Bei Erst-Install ist nichts running, dann ist das
# ein normaler Start.
systemctl restart edgeguard-api.service edgeguard-scheduler.service || true
systemctl restart edgeguard-api.service edgeguard-scheduler.service edgeguard-waf.service || true
# WireGuard-Sicherung: enabled-aber-inaktive wg-quick@-Interfaces
# nach dem API-Restart starten. Der API-Renderer kann wg-quick@

View File

@@ -61,7 +61,7 @@ build_api() {
[ -f "$pkg_src/DEBIAN/conffiles" ] && cp "$pkg_src/DEBIAN/conffiles" "$build_dir/DEBIAN/"
# binaries
for bin in edgeguard-api edgeguard-scheduler edgeguard-ctl; do
for bin in edgeguard-api edgeguard-scheduler edgeguard-ctl edgeguard-waf; do
install -m 0755 "$REPO_ROOT/build/$ARCH/$bin" "$build_dir/usr/bin/$bin"
done
@@ -70,6 +70,8 @@ build_api() {
"$build_dir/etc/systemd/system/"
install -m 0644 "$REPO_ROOT/deploy/systemd/edgeguard-scheduler.service" \
"$build_dir/etc/systemd/system/"
install -m 0644 "$REPO_ROOT/deploy/systemd/edgeguard-waf.service" \
"$build_dir/etc/systemd/system/"
# systemd drop-in for HAProxy — postinst copies it into
# /etc/systemd/system/haproxy.service.d/. Shipped under