From 4aea53cb2dc30bf553b920e5b765059e2ac91275 Mon Sep 17 00:00:00 2001 From: "Simon L." Date: Wed, 5 Aug 2026 11:59:13 +0200 Subject: [PATCH] mastercontainer: block the docker network gateway on the login endpoints The `/api/auth/login` and `/api/auth/getlogin` endpoints are already blocked for the nextcloud container. However containers that reach the mastercontainer via the host use the gateway ip of the `nextcloud-aio` network as source address, so requests from them were not caught by the existing matcher. The gateway ip is now read in start.sh and exported as DOCKER_NETWORK_GATEWAY so that it can be used via `remote_ip` in both Caddyfiles. Note that this needs a second matcher block instead of an additional line in the existing one because matchers of different types inside one named matcher are AND'ed together, which would never match. Also `remote_host` only resolves host names, hence the built-in `remote_ip` matcher is used for the ip. If the `nextcloud-aio` network does not exist yet - it only gets created by the php code once the containers get started for the first time - the value falls back to localhost, which is a no-op for the matcher, and the actual gateway ip gets applied on the next restart of the mastercontainer. Signed-off-by: Simon L. --- Containers/mastercontainer/acme.Caddyfile | 14 ++++++++++++-- Containers/mastercontainer/internal.Caddyfile | 14 ++++++++++++-- Containers/mastercontainer/start.sh | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Containers/mastercontainer/acme.Caddyfile b/Containers/mastercontainer/acme.Caddyfile index 77d7df9e..c3a117d2 100644 --- a/Containers/mastercontainer/acme.Caddyfile +++ b/Containers/mastercontainer/acme.Caddyfile @@ -36,11 +36,21 @@ https://:8443 { import headers.Caddyfile header Strict-Transport-Security max-age=31536000; - @denied { + @denied-host { path /api/auth/login /api/auth/getlogin remote_host nextcloud-aio-nextcloud } - abort @denied + abort @denied-host + + # The gateway ip of the nextcloud-aio network is used as source address by containers + # that reach the mastercontainer via the host, so it needs to be blocked as well. + # The variable gets set in start.sh and falls back to localhost if the network + # does not exist yet. In that case it gets applied on the next container restart. + @denied-gateway { + path /api/auth/login /api/auth/getlogin + remote_ip {$DOCKER_NETWORK_GATEWAY} + } + abort @denied-gateway root * /var/www/docker-aio/php/public php_fastcgi unix//run/php.sock diff --git a/Containers/mastercontainer/internal.Caddyfile b/Containers/mastercontainer/internal.Caddyfile index 9890acc0..ccd3c70c 100644 --- a/Containers/mastercontainer/internal.Caddyfile +++ b/Containers/mastercontainer/internal.Caddyfile @@ -26,11 +26,21 @@ https://:8080 { import headers.Caddyfile - @denied { + @denied-host { path /api/auth/login /api/auth/getlogin remote_host nextcloud-aio-nextcloud } - abort @denied + abort @denied-host + + # The gateway ip of the nextcloud-aio network is used as source address by containers + # that reach the mastercontainer via the host, so it needs to be blocked as well. + # The variable gets set in start.sh and falls back to localhost if the network + # does not exist yet. In that case it gets applied on the next container restart. + @denied-gateway { + path /api/auth/login /api/auth/getlogin + remote_ip {$DOCKER_NETWORK_GATEWAY} + } + abort @denied-gateway root * /var/www/docker-aio/php/public php_fastcgi unix//run/php.sock diff --git a/Containers/mastercontainer/start.sh b/Containers/mastercontainer/start.sh index c7f130e4..c1b401a6 100755 --- a/Containers/mastercontainer/start.sh +++ b/Containers/mastercontainer/start.sh @@ -436,6 +436,20 @@ if [ -d "/mnt/docker-aio-config/caddy/locks" ]; then rm -rf /mnt/docker-aio-config/caddy/locks/* fi +# Get the gateway ip of the nextcloud-aio network which is used by the Caddyfiles. +# Containers that reach the mastercontainer via the host use it as source address, +# so it needs to be blocked in addition to the nextcloud container itself. +# A network can have multiple gateways (e.g. one for IPv4 and one for IPv6), so get them all. +# remote_ip accepts multiple space separated values. +DOCKER_NETWORK_GATEWAY="$(su-exec www-data docker network inspect nextcloud-aio --format '{{range .IPAM.Config}}{{if .Gateway}}{{.Gateway}} {{end}}{{end}}' 2>/dev/null | sed 's| *$||')" +if [ -z "$DOCKER_NETWORK_GATEWAY" ]; then + # The network gets created by the php code when the containers get started for the first time, + # so it might not exist yet. Fall back to localhost which is a no-op for the matcher and + # apply the actual gateway ip on the next container restart. + DOCKER_NETWORK_GATEWAY="127.0.0.1" +fi +export DOCKER_NETWORK_GATEWAY + # Fix the Caddyfile format caddy fmt --overwrite /acme.Caddyfile caddy fmt --overwrite /internal.Caddyfile