From 9016605f0d1267bd441585ab2d62a11e84ed521a Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 7 May 2026 08:32:20 +0200 Subject: [PATCH] security: harden wg-init and wg-easy container isolation - wg-init: isolate with network_mode:none, drop repo mount, use explicit PUID/PGID env vars instead of stat trick - wg-easy: add read_only filesystem, /run tmpfs, no-new-privileges - .env.example: simplify and document PUID/PGID Co-Authored-By: Claude Sonnet 4.6 --- .env.example | 39 +++++++++++---------------------------- docker-compose.yml | 13 +++++++++++-- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/.env.example b/.env.example index 904291f..65ace49 100644 --- a/.env.example +++ b/.env.example @@ -1,36 +1,19 @@ -# ============================================================ -# WireGuard VPN — Configurazione locale -# Copia .env.example in .env e compila i valori richiesti. -# ============================================================ - -# Fuso orario (formato IANA) -# Lista completa: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +# Fuso orario IANA — obbligatorio TZ=Europe/Rome -# --- OPZIONALI (valori di default mostrati) --- +# UID/GID dell'utente host proprietario di wg-data/ (trova con: id -u && id -g) +# PUID=1000 +# PGID=1000 -# Porta UDP WireGuard -WG_PORT=51820 +# Porte esposte sull'host (opzionali, default mostrati) +# WG_PORT=51820 +# WG_UI_PORT=51821 -# Porta TCP interfaccia web -WG_UI_PORT=51821 - -# --- OPZIONALI — Limiti risorse container (SBC) --- -# Decommenta e adatta alla RAM disponibile: -# 512 MB RAM (RPi 3B) → WG_MEM_LIMIT=96m (reale: ~37 MB, 96 m è già doppio) -# 1 GB RAM (RPi 3B+) → WG_MEM_LIMIT=128m -# 2 GB+ RAM (RPi 4/5) → WG_MEM_LIMIT=256m (default) +# Limiti risorse container (opzionali — adatta alla RAM disponibile) +# 512 MB → WG_MEM_LIMIT=96m +# 1 GB → WG_MEM_LIMIT=128m +# 2 GB+ → WG_MEM_LIMIT=256m ← default # Tenere WG_MEMSWAP_LIMIT = WG_MEM_LIMIT per disabilitare lo swap del container. -# Su single-core (Pi Zero / Pi 1) impostare WG_CPUS=0.75. -# -# ATTENZIONE — RPi 3 con uptime lungo: il processo Node.js può crescere nel -# tempo. Con 1 GB di RAM totale e OS+Docker che occupano ~350 MB, un limite -# di 256 m lascia pochissimo margine; il kernel OOM-killa SSH prima del -# container. Usare 96-128 m e assicurarsi che lo swap host sia >= 512 MB -# (vedi CLAUDE.md §SBC per il comando). # WG_MEM_LIMIT=256m # WG_MEMSWAP_LIMIT=256m # WG_CPUS=1.0 - -# NOTA: host VPN, password e DNS si configurano dalla web UI al primo avvio — -# non servono variabili d'ambiente per questi valori (comportamento v15+). diff --git a/docker-compose.yml b/docker-compose.yml index 8166ac3..844cbe5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,14 @@ services: wg-init: image: alpine:3.21 + network_mode: none cap_add: - SYS_MODULE + environment: + PUID: "${PUID:-1000}" + PGID: "${PGID:-1000}" volumes: - ./wg-data:/data - - ./:/repo:ro - /lib/modules:/lib/modules:ro command: - /bin/sh @@ -13,7 +16,7 @@ services: - | modprobe ip6_tables 2>/dev/null || true modprobe ip6table_nat 2>/dev/null || true - chown "$(stat -c '%u:%g' /repo)" /data + chown "${PUID}:${PGID}" /data chmod 700 /data restart: "no" @@ -36,6 +39,7 @@ services: max-file: "3" healthcheck: + # porta interna fissa; WG_UI_PORT controlla solo il mapping host test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:51821/"] interval: 60s timeout: 10s @@ -49,8 +53,10 @@ services: volumes: - ./wg-data:/etc/wireguard + read_only: true tmpfs: - /tmp:size=32m,mode=1777 + - /run:size=8m ports: - "${WG_PORT:-51820}:51820/udp" @@ -60,6 +66,9 @@ services: - NET_ADMIN - SYS_MODULE + security_opt: + - no-new-privileges:true + sysctls: - net.ipv4.ip_forward=1 - net.ipv6.conf.all.forwarding=1