diff --git a/Dockers/gluetun-pia-wireguard-rotator/README.md b/Dockers/gluetun-pia-wireguard-rotator/README.md index 0a638e0..cf1cdcb 100644 --- a/Dockers/gluetun-pia-wireguard-rotator/README.md +++ b/Dockers/gluetun-pia-wireguard-rotator/README.md @@ -1,12 +1,12 @@ # gluetun-pia-wireguard-rotator -Sidecar die dagelijks (en bij container-start) een willekeurige PIA WireGuard-region kiest via [pia-wg-config](https://github.com/kylegrantlucas/pia-wg-config), `wg0.conf` op het gedeelde gluetun-volume schrijft, en de gluetun-container herstart. +Sidecar die dagelijks (en bij container-start) een willekeurige PIA WireGuard-region kiest via [pia-wg-config](https://github.com/kylegrantlucas/pia-wg-config), `wg0.conf` op het gedeelde gluetun-volume schrijft, en een configureerbare lijst containers herstart. ## Vereisten - Gluetun met `VPN_SERVICE_PROVIDER=custom` en `VPN_TYPE=wireguard` - Gedeeld volume met gluetun (bijv. `/var/dockers/m3u-filter-pia:/gluetun` op gluetun, `/config` op de rotator) -- Docker socket (alleen voor `docker restart` van de gluetun-container) +- Docker socket (voor `docker restart` van gluetun en eventuele sidecar-containers) - Actief PIA-abonnement ## Environment variables @@ -31,7 +31,8 @@ docker run --rm --entrypoint pia-wg-config bramkel/gluetun-pia-wireguard-rotator | Variable | Default | Description | |----------|---------|-------------| -| `GLUETUN_CONTAINER` | `m3u-filter-vpn` | Container name/id om te herstarten | +| `RESTART_CONTAINERS` | — | CSV of JSON-array met containers om te herstarten, **in volgorde** (gluetun eerst, daarna sidecars). Voorbeeld: `m3u-filter-vpn,m3u-editor,xtream-proxy` | +| `GLUETUN_CONTAINER` | `m3u-filter-vpn` | Alleen gebruikt als `RESTART_CONTAINERS` leeg is | | `WG_CONFIG_PATH` | `/config/wireguard/wg0.conf` | Pad waar `wg0.conf` wordt geschreven | | `ROTATOR_STATE_PATH` | `/config/rotator-state.json` | Laatste rotatie-metadata | | `ROTATE_AT` | `03:00` | Dagelijks rotatietijdstip (`HH:MM`, in `TZ`) | @@ -40,7 +41,7 @@ docker run --rm --entrypoint pia-wg-config bramkel/gluetun-pia-wireguard-rotator ## Output - `wireguard/wg0.conf` op het gedeelde volume — Gluetun leest dit als `/gluetun/wireguard/wg0.conf` en dit **overschrijft** `WIREGUARD_*` environment variables -- `rotator-state.json` — laatste gekozen region en timestamp +- `rotator-state.json` — laatste gekozen region, timestamp en herstartte containers ## Compose-integratie @@ -58,7 +59,7 @@ Zie [`docker-compose.example.yml`](docker-compose.example.yml) voor een volledig - PIA_USER=${PIA_USER} - PIA_PASS=${PIA_PASSWORD} - PIA_REGIONS=netherlands,france,belgium - - GLUETUN_CONTAINER=m3u-filter-vpn + - RESTART_CONTAINERS=m3u-filter-vpn,m3u-editor,xtream-proxy - ROTATE_AT=03:00 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -96,11 +97,14 @@ Optioneel host-`.env`-keys (`WIREGUARD_*`) opruimen als die niet meer gebruikt w ## Gedrag -1. Bij start: direct roteren (nieuwe config + gluetun restart) +1. Bij start: direct roteren (nieuwe config + container-restarts) 2. Daarna: elke dag om `ROTATE_AT` opnieuw 3. Willekeurige region uit `PIA_REGIONS` +4. Containers uit `RESTART_CONTAINERS` worden één voor één herstart in de opgegeven volgorde -**Let op:** `docker restart` op gluetun veroorzaakt kort VPN-verlies voor alle containers met `network_mode: service:m3u-filter-vpn`. +**Let op:** zet gluetun altijd als eerste in `RESTART_CONTAINERS`. Sidecars met `network_mode: service:...` herstarten pas daarna, zodat ze opnieuw aan de VPN-namespace koppelen. + +**Let op:** elke rotatie veroorzaakt kort downtime voor alle VPN-afhankelijke services. ## Security diff --git a/Dockers/gluetun-pia-wireguard-rotator/rotate.sh b/Dockers/gluetun-pia-wireguard-rotator/rotate.sh index 7768af4..7ca0576 100644 --- a/Dockers/gluetun-pia-wireguard-rotator/rotate.sh +++ b/Dockers/gluetun-pia-wireguard-rotator/rotate.sh @@ -41,17 +41,54 @@ pick_random_region() { printf '%s\n' "${regions[@]}" | shuf -n 1 } +parse_restart_containers() { + # CSV: "m3u-filter-vpn,m3u-editor,xtream-proxy" or JSON array. + # Falls back to GLUETUN_CONTAINER when unset. + local raw="${RESTART_CONTAINERS:-}" + if [[ -z "$raw" ]]; then + echo "${GLUETUN_CONTAINER:-m3u-filter-vpn}" + return + fi + + if [[ "$raw" =~ ^\[.*\]$ ]]; then + jq -r '.[]' <<<"$raw" + return + fi + + tr ',' '\n' <<<"$raw" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | awk 'NF' +} + +restart_containers() { + local container restarted=() + while IFS= read -r container; do + [[ -z "$container" ]] && continue + log "Restarting container: $container" + if ! docker restart "$container"; then + >&2 echo "docker restart failed for container=$container" + exit 1 + fi + restarted+=("$container") + done < <(parse_restart_containers) + + if [[ "${#restarted[@]}" -eq 0 ]]; then + >&2 echo "No containers configured to restart" + exit 1 + fi +} + write_state() { local region="$1" local state_path="${ROTATOR_STATE_PATH:-/config/rotator-state.json}" - local rotated_at + local rotated_at restarted_json rotated_at="$(date -Is)" + restarted_json="$(parse_restart_containers | jq -R -s 'split("\n") | map(select(length > 0))')" mkdir -p "$(dirname "$state_path")" jq -n \ --arg region "$region" \ --arg rotated_at "$rotated_at" \ --arg wg_config "${WG_CONFIG_PATH:-/config/wireguard/wg0.conf}" \ - '{region: $region, rotated_at: $rotated_at, wg_config: $wg_config}' >"$state_path" + --argjson restarted_containers "$restarted_json" \ + '{region: $region, rotated_at: $rotated_at, wg_config: $wg_config, restarted_containers: $restarted_containers}' >"$state_path" chmod 644 "$state_path" } @@ -60,10 +97,9 @@ rotate_once() { require_env PIA_PASS require_env PIA_REGIONS - local region wg_path tmp_dir gluetun_container + local region wg_path tmp_dir region="$(pick_random_region)" wg_path="${WG_CONFIG_PATH:-/config/wireguard/wg0.conf}" - gluetun_container="${GLUETUN_CONTAINER:-m3u-filter-vpn}" log "Selected region: $region" @@ -87,14 +123,9 @@ rotate_once() { chmod 600 "$wg_path" log "Wrote $wg_path" + restart_containers write_state "$region" - log "Restarting gluetun container: $gluetun_container" - if ! docker restart "$gluetun_container"; then - >&2 echo "docker restart failed for container=$gluetun_container" - exit 1 - fi - log "Rotation complete for region=$region" }