CI / Build and Test (gcc, g++, ubuntu-latest) (push) Failing after 5m2s
CI / Code Coverage (push) Skipped
Build and Publish Docker Image / build-and-test (push) Failing after 6m13s
Build and Publish Docker Image / build-and-push-image (push) Skipped
Build and Publish Docker Image / security-scan (push) Skipped
The per-IP ban tracker treats every globally-routable client equally, but an aggregating front-end like the finger-web proxy funnels the whole internet's federated lookups through a single IP. A burst from any one client of the proxy (or a load test) is then attributed to the proxy's IP and, once it crosses the failure threshold, the daemon blocks the proxy — taking out finger lookups for everyone. Per-client abuse protection for the proxied path belongs in the proxy (which now rate-limits per real client IP), so the daemon should trust it. Add a FINGER_BAN_ALLOWLIST env var (comma-separated IPs). Allowlisted addresses are marked non-trackable in the listener, so their connections are never blocked and never recorded as offenses. Unset = unchanged behaviour. - parse_ip_allowlist() in ban.cpp (trims entries, skips blanks) + unit tests - listener() consults the set when computing 'trackable' - documented in docker-compose.yml and DOCKER.md
49 lines
2.1 KiB
YAML
49 lines
2.1 KiB
YAML
version: '3.8'
|
|
|
|
services:
|
|
finger:
|
|
build: .
|
|
# IMPORTANT: host networking is what lets the daemon's abuse protection
|
|
# work. Under Docker's default bridge networking every external client is
|
|
# SNAT'd to the bridge gateway (a 172.16/12 address), so the daemon sees a
|
|
# single source IP for everyone -- the per-IP ban logic can't tell clients
|
|
# apart and (by design) treats that private address as untrackable, leaving
|
|
# banning inert. Host networking exposes the real client IP, so repeat
|
|
# offenders actually get blocked.
|
|
network_mode: host
|
|
# Under host networking the container shares the host net namespace, which
|
|
# uses the host's privileged-port rule -- so the image's non-root user
|
|
# (UID 1000) cannot bind port 79 and the daemon fails to listen silently.
|
|
# Run as root to bind it. (Alternative: setcap cap_net_bind_service on the
|
|
# binary in the image to keep it non-root.)
|
|
user: "0:0"
|
|
# FINGER_BAN_ALLOWLIST: comma-separated client IPs that are never tracked or
|
|
# banned. Use it for trusted aggregating front-ends — e.g. the finger-web
|
|
# proxy, which funnels every federated lookup through one IP; without an
|
|
# allowlist a burst from any single client of the proxy is attributed to the
|
|
# proxy and bans it for everyone (per-client abuse protection for that path
|
|
# lives in the proxy). Leave unset for a directly-exposed daemon.
|
|
# environment:
|
|
# - FINGER_BAN_ALLOWLIST=203.0.113.10,2001:db8::10
|
|
volumes:
|
|
- ./users:/var/finger/users
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "nc -w 1 127.0.0.1 79 < /dev/null || exit 1"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# Bridge-networking alternative (quick local testing only). NOTE: with this
|
|
# mode the daemon only ever sees the bridge gateway IP, so abuse protection
|
|
# is effectively disabled. Prefer host networking above for any public-facing
|
|
# deployment.
|
|
# finger:
|
|
# image: ghcr.io/waffle2k/finger:latest
|
|
# ports:
|
|
# - "79:79"
|
|
# volumes:
|
|
# - ./users:/var/finger/users
|
|
# restart: unless-stopped
|