modified: core/authelia/docker-compose.yml

modified:   core/crowdsec/docker-compose.yml
	modified:   core/error-pages/docker-compose.yml
	modified:   monitoring/docker-exporter/docker-compose.yml
	modified:   monitoring/docker-socket-proxy/docker-compose.yml
	deleted:    monitoring/influxdb-service/docker-compose.yml
	modified:   monitoring/node-exporter/docker-compose.yml
	modified:   monitoring/pihole-exporter/docker-compose.yml
	modified:   monitoring/telegraf/docker-compose.yml
	new file:   service-access-policy.md
This commit is contained in:
git
2026-04-13 11:51:45 +10:00
parent 9678c6a8f1
commit 43f25321d7
10 changed files with 86 additions and 50 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
authelia: authelia:
profiles: ["core","all","authelia"] profiles: ["core","all","authelia", "traefik"]
image: authelia/authelia image: authelia/authelia
restart: always restart: always
build: build:
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
crowdsec: crowdsec:
profiles: ["core","all","crowdsec"] profiles: ["core","all","crowdsec", "traefik"]
# image: crowdsecurity/crowdsec:latest # image: crowdsecurity/crowdsec:latest
build: ${PROJECT_ROOT}/core/crowdsec build: ${PROJECT_ROOT}/core/crowdsec
container_name: crowdsec container_name: crowdsec
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
error-pages: error-pages:
profiles: ["core","all","error-pages"] profiles: ["core","all","error-pages", "traefik"]
image: tarampampam/error-pages:3 image: tarampampam/error-pages:3
restart: always restart: always
container_name: error-pages container_name: error-pages
@@ -1,6 +1,6 @@
services: services:
docker-update-exporter: docker-update-exporter:
profiles: ["monitoring","all","docker-exporter"] profiles: ["monitoring","all","docker-exporter", "prometheus"]
build: build:
context: ${PROJECT_ROOT}/monitoring/docker-exporter context: ${PROJECT_ROOT}/monitoring/docker-exporter
container_name: docker-update-exporter container_name: docker-update-exporter
@@ -1,6 +1,6 @@
services: services:
docker-socket-proxy: docker-socket-proxy:
profiles: ["monitoring","all","docker-socket-proxy"] profiles: ["monitoring","all","docker-socket-proxy", "core", "traefik", "prometheus"]
image: tecnativa/docker-socket-proxy:latest image: tecnativa/docker-socket-proxy:latest
container_name: docker-socket-proxy container_name: docker-socket-proxy
hostname: docker-socket-proxy hostname: docker-socket-proxy
@@ -1,42 +0,0 @@
services:
influxdb:
profiles: ["monitoring","all","influxdb-service"]
image: influxdb:2.7
container_name: influxdb
restart: unless-stopped
# env_file:
# - ${PROJECT_ROOT}/secrets/stack-secrets.env
volumes:
- ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2
environment:
DOCKER_INFLUXDB_INIT_MODE: ${INFLUXDB_INIT_MODE}
DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME}
DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb_init_password
DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG}
DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_INIT_BUCKET}
secrets:
- influxdb_init_password
networks:
# - edge
# - traefik_reverse_proxy
- traefik
- monitor
labels:
- "traefik.http.routers.influxdb.rule=Host(`influxdb.lan.ddnsgeek.com`)"
- "traefik.enable=true"
- "traefik.http.routers.influxdb.entrypoints=websecure"
- "traefik.http.routers.influxdb.tls.certresolver=myresolver"
- "io.portainer.accesscontrol.public"
- "traefik.http.services.influxdb.loadbalancer.server.port=8086"
- "traefik.http.routers.influxdb.middlewares=authelia"
- "traefik.docker.network=core_traefik"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8086/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
secrets:
influxdb_init_password:
file: ${PROJECT_ROOT}/secrets/influxdb_init_password.txt
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
node-exporter: node-exporter:
profiles: ["monitoring","all","node-exporter"] profiles: ["monitoring","all","node-exporter", "prometheus"]
image: prom/node-exporter:latest image: prom/node-exporter:latest
container_name: node-exporter container_name: node-exporter
pid: host pid: host
@@ -1,6 +1,6 @@
services: services:
pihole-exporter: pihole-exporter:
profiles: ["monitoring","all","pihole-exporter"] profiles: ["monitoring","all","pihole-exporter", "prometheus"]
image: ekofr/pihole-exporter:latest image: ekofr/pihole-exporter:latest
container_name: pihole-exporter container_name: pihole-exporter
# env_file: # env_file:
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
telegraf: telegraf:
profiles: ["monitoring","all","telegraf"] profiles: ["monitoring","all","telegraf", "prometheus"]
image: telegraf:latest image: telegraf:latest
container_name: telegraf container_name: telegraf
restart: unless-stopped restart: unless-stopped
+78
View File
@@ -0,0 +1,78 @@
# Service Access Policy and External Exposure Hardening
## 1) Service classification
| Service/Host | Classification | Rationale |
|---|---|---|
| `auth.lan.ddnsgeek.com` | `authenticated-public` | Public identity/login entrypoint; internet-accessible but requires user authentication. |
| `nextcloud.lan.ddnsgeek.com` | `authenticated-public` | Internet-facing collaboration app that must remain reachable to authenticated users. |
| `passbolt.lan.ddnsgeek.com` | `authenticated-public` | Public password-management portal with strong authentication controls. |
| `gitea.lan.ddnsgeek.com` | `authenticated-public` | Public developer endpoint with account-based access. |
| `searxng.lan.ddnsgeek.com` | `public` | Intended anonymous/search access endpoint. |
| `familytree.lan.ddnsgeek.com` | `authenticated-public` | End-user app; externally reachable but login-protected. |
| `shifts.lan.ddnsgeek.com` | `authenticated-public` | End-user app; externally reachable but login-protected. |
| `stockfill.lan.ddnsgeek.com` | `authenticated-public` | End-user app; externally reachable but login-protected. |
| `gotify.lan.ddnsgeek.com` | `private-admin` | Admin/ops notification backend; should not be internet reachable. |
| `grafana.lan.ddnsgeek.com` | `private-admin` | Infrastructure admin/observability console. |
| `prometheus.lan.ddnsgeek.com` | `private-admin` | Monitoring datastore/query interface. |
| `node-red.lan.ddnsgeek.com` | `private-admin` | Automation runtime and flow editor. |
| `traefik.lan.ddnsgeek.com` | `private-admin` | Reverse-proxy admin/dashboard surface. |
| `portainer.lan.ddnsgeek.com` | `private-admin` | Container management plane. |
| `influxdb.lan.ddnsgeek.com` | `private-admin` | Metrics datastore admin/API surface. |
| `kuma.lan.ddnsgeek.com` | `private-admin` | Monitoring admin surface. |
| `monitor-kuma.lan.ddnsgeek.com` | `private-admin` | Monitoring admin surface. |
| `edge.lan.ddnsgeek.com` | `private-admin` | Edge/network administration plane. |
## 2) Required controls for `private-admin`
Apply **at least one** trusted-path control (preferably layered):
- Private network only (no public DNS / no internet route).
- WireGuard/Tailscale/OpenVPN access gate.
- mTLS client certificate requirement at reverse proxy.
- Source IP allowlist at firewall and reverse proxy.
Minimum target state for all `private-admin` hosts:
- Public internet: connection refused/timeout, or immediate `403` for untrusted source.
- Trusted path (VPN/mTLS/allowlisted IP): normal authenticated access.
## 3) Gateway auth hardening
For all `public` and `authenticated-public` services:
- Keep SSO and MFA enforcement at the identity gateway.
- Enforce lockout/backoff on `/login`, `/oauth/*`, `/auth/*`, `/api/auth/*`.
- Rate-limit by source IP + account identifier to deter credential stuffing.
Suggested baseline:
- Soft limit: `10 req/min` per IP for auth endpoints.
- Burst: `20`.
- Temporary block: `15 min` after repeated failures.
- Account lockout: `5-10` consecutive failed attempts (with secure unlock flow).
## 4) WAF / reverse-proxy protections
Deploy one of:
- WAF managed rules for bot/credential-stuffing signatures.
- Reverse-proxy failed-auth throttling and tarpit/delay policy.
Implement logging + alerting thresholds:
- High failed-auth rate from one IP/CIDR.
- Password spray pattern across many usernames.
- Geo/ASN anomalies for sensitive apps.
## 5) External re-test procedure
Re-test from a non-trusted external network and record outcomes.
Success criteria:
- Every `private-admin` host is inaccessible without VPN/mTLS/allowlisted source.
- `public` and `authenticated-public` hosts remain reachable.
- Auth endpoints trigger rate-limit/lockout controls under failed-attempt simulation.
Use `./scripts/retest-external-access.sh` for a repeatable external validation pass.