Unset TRUSTED_PROXIES trusts the RFC 1918 ranges (closes #119)
check / check (push) Successful in 2m48s
check / check (push) Successful in 2m48s
With TRUSTED_PROXIES unset, bin/entrypoint.sh gives nginx one set_real_ip_from line for each of 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16, as sneak ruled on 2026-09-22 for every app. A list replaces them, and set and empty trusts no proxy; each entry is checked as before. The backend inside the container still trusts only 127.0.0.1/32. Both READMEs, nginx.conf and the comment in script/frontend-viewport-test say the new default. Model: opus-5-5
This commit is contained in:
@@ -273,7 +273,8 @@ which listens only inside the container, on `127.0.0.1:8081`. The image:
|
|||||||
|
|
||||||
- Listens on port 8080 by default (override with `PORT` env var)
|
- Listens on port 8080 by default (override with `PORT` env var)
|
||||||
- Takes the client address from `X-Forwarded-For` only on requests from the
|
- Takes the client address from `X-Forwarded-For` only on requests from the
|
||||||
reverse proxies named in `TRUSTED_PROXIES`, and by default from none
|
reverse proxies named in `TRUSTED_PROXIES`, by default from any address in
|
||||||
|
`10.0.0.0/8`, `172.16.0.0/12` or `192.168.0.0/16`
|
||||||
- Sends access logs to stdout
|
- Sends access logs to stdout
|
||||||
- Caches static assets with immutable headers
|
- Caches static assets with immutable headers
|
||||||
- Sends the security headers `REPO_POLICIES.md` requires on every response, as
|
- Sends the security headers `REPO_POLICIES.md` requires on every response, as
|
||||||
@@ -291,9 +292,9 @@ What the [upaas](https://git.eeqj.de/sneak/upaas) app for netwatch needs:
|
|||||||
|
|
||||||
- **Port:** container port `8080`.
|
- **Port:** container port `8080`.
|
||||||
- **Volume:** container path `/data`; the reports are kept in `/data/reports`.
|
- **Volume:** container path `/data`; the reports are kept in `/data/reports`.
|
||||||
- **Environment variables:** none is required. An empty one counts as unset, and
|
- **Environment variables:** none is required. An empty one counts as unset,
|
||||||
one set to a value netwatch cannot use stops the container at start, with the
|
except `TRUSTED_PROXIES`, and one set to a value netwatch cannot use stops the
|
||||||
reason in its log.
|
container at start, with the reason in its log.
|
||||||
- `PORT`, default `8080`: the container port, from 1 to 65535. `8081` cannot
|
- `PORT`, default `8080`: the container port, from 1 to 65535. `8081` cannot
|
||||||
be used: the backend listens on it inside the container
|
be used: the backend listens on it inside the container
|
||||||
- `REPORTS_PER_MINUTE`, default `60`: reports each client address may send a
|
- `REPORTS_PER_MINUTE`, default `60`: reports each client address may send a
|
||||||
@@ -307,16 +308,17 @@ What the [upaas](https://git.eeqj.de/sneak/upaas) app for netwatch needs:
|
|||||||
in: `/data` or a path below it, with no `.` or `..` part and no extra `/`.
|
in: `/data` or a path below it, with no `.` or `..` part and no extra `/`.
|
||||||
The container also stops if the path goes through a symbolic link that
|
The container also stops if the path goes through a symbolic link that
|
||||||
leads out of `/data` or is written as a full path
|
leads out of `/data` or is written as a full path
|
||||||
- `TRUSTED_PROXIES`, default empty: set it to the address the reverse proxy
|
- `TRUSTED_PROXIES`, default `10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`: the
|
||||||
in front of the container connects from, as an IP address or CIDR; several
|
addresses the reverse proxy in front of the container connects from, as IP
|
||||||
are separated by commas. nginx takes the client address from
|
addresses or CIDRs separated by commas. nginx takes the client address
|
||||||
`X-Forwarded-For` only on a request from one of them, and the rate limit
|
from `X-Forwarded-For` only on a request from one of them, and the rate
|
||||||
counts that address. Unset, `X-Forwarded-For` is ignored and every client
|
limit counts that address. A list replaces the default. Set and empty,
|
||||||
behind the proxy shares the proxy's one allowance of `REPORTS_PER_MINUTE`.
|
`X-Forwarded-For` is ignored and every client behind the proxy shares the
|
||||||
Name only addresses nothing but the proxy connects from: any client that
|
proxy's one allowance of `REPORTS_PER_MINUTE`. Any client that connects
|
||||||
connects from one can write its own `X-Forwarded-For`, and through a port
|
from one of these addresses can write its own `X-Forwarded-For`, and
|
||||||
Docker publishes, every client may connect from the Docker network's
|
through a port Docker publishes, every client may connect from the Docker
|
||||||
gateway, such as `172.17.0.1`.
|
network's gateway, such as `172.17.0.1`, which the default includes; where
|
||||||
|
that matters, name only the addresses nothing but the proxy connects from.
|
||||||
- `METRICS_USERNAME` and `METRICS_PASSWORD`, default empty: with both set,
|
- `METRICS_USERNAME` and `METRICS_PASSWORD`, default empty: with both set,
|
||||||
the backend records Prometheus metrics of its requests and serves them at
|
the backend records Prometheus metrics of its requests and serves them at
|
||||||
`/metrics` on the container port, to requests with this user name and
|
`/metrics` on the container port, to requests with this user name and
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ Decide whether the repo moves to the layout `REPO_POLICIES.md` gives, with
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-14: with `TRUSTED_PROXIES` unset, the container's nginx trusts the
|
||||||
|
three private ranges of RFC 1918, `10.0.0.0/8`, `172.16.0.0/12` and
|
||||||
|
`192.168.0.0/16` ([#119](https://git.eeqj.de/sneak/netwatch/issues/119)), as
|
||||||
|
sneak ruled on 2026-09-22 for every app; it trusted no proxy before. A list
|
||||||
|
replaces them, and set and empty it trusts none. The backend inside the
|
||||||
|
container still trusts only `127.0.0.1/32`
|
||||||
- 2026-10-07: the files shared from `sneak/prompts` are its copies at commit
|
- 2026-10-07: the files shared from `sneak/prompts` are its copies at commit
|
||||||
`dd4027b` ([#113](https://git.eeqj.de/sneak/netwatch/issues/113)), with this
|
`dd4027b` ([#113](https://git.eeqj.de/sneak/netwatch/issues/113)), with this
|
||||||
repository's own entries after the shared content in `.gitignore`,
|
repository's own entries after the shared content in `.gitignore`,
|
||||||
|
|||||||
+8
-6
@@ -121,12 +121,14 @@ replaces the security headers this server sets with those in the root
|
|||||||
The container's own `TRUSTED_PROXIES` goes to nginx instead: IP addresses or
|
The container's own `TRUSTED_PROXIES` goes to nginx instead: IP addresses or
|
||||||
CIDRs, separated by commas, of the reverse proxies in front of the container.
|
CIDRs, separated by commas, of the reverse proxies in front of the container.
|
||||||
nginx takes the client address from `X-Forwarded-For` only on a request from one
|
nginx takes the client address from `X-Forwarded-For` only on a request from one
|
||||||
of them. Unset or empty, nginx trusts no proxy, and the client address is the
|
of them. Unset, nginx trusts `10.0.0.0/8`, `172.16.0.0/12` and `192.168.0.0/16`,
|
||||||
one each request comes from, so every client behind a proxy shares one rate
|
and a list replaces them. Set and empty, nginx trusts no proxy, and the client
|
||||||
limit. An entry that is not an IP address or CIDR, such as a hostname or
|
address is the one each request comes from, so every client behind a proxy
|
||||||
`1.2.3`, stops the container at start with an error naming `TRUSTED_PROXIES`:
|
shares one rate limit. An entry that is not an IP address or CIDR, such as a
|
||||||
the entrypoint checks each entry with `netwatch-server check-cidr`, which parses
|
hostname or `1.2.3`, stops the container at start with an error naming
|
||||||
it as this server parses its own `TRUSTED_PROXIES`.
|
`TRUSTED_PROXIES`: the entrypoint checks each entry with
|
||||||
|
`netwatch-server check-cidr`, which parses it as this server parses its own
|
||||||
|
`TRUSTED_PROXIES`.
|
||||||
|
|
||||||
### Report storage
|
### Report storage
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -34,9 +34,11 @@ fi
|
|||||||
|
|
||||||
# TRUSTED_PROXIES names the reverse proxies in front of the container,
|
# TRUSTED_PROXIES names the reverse proxies in front of the container,
|
||||||
# as IP addresses or CIDRs separated by commas. nginx takes the client
|
# as IP addresses or CIDRs separated by commas. nginx takes the client
|
||||||
# address from X-Forwarded-For only on a request from one of them, so
|
# address from X-Forwarded-For only on a request from one of them.
|
||||||
# unset or empty, it trusts no one. nginx.conf includes the file written
|
# Unset, they are the three private ranges of RFC 1918; set and empty,
|
||||||
# here, one set_real_ip_from line per entry.
|
# nginx trusts no one, which is why the default below follows - and not
|
||||||
|
# :-. nginx.conf includes the file written here, one set_real_ip_from
|
||||||
|
# line per entry.
|
||||||
#
|
#
|
||||||
# nginx looks up an entry it cannot read as an address as a hostname,
|
# nginx looks up an entry it cannot read as an address as a hostname,
|
||||||
# and trusts what it finds (1.2.3 is found as 1.2.0.3). So each entry
|
# and trusts what it finds (1.2.3 is found as 1.2.0.3). So each entry
|
||||||
@@ -45,7 +47,7 @@ fi
|
|||||||
# TRUSTED_PROXIES. Its error, naming the CIDR, is dropped for the one
|
# TRUSTED_PROXIES. Its error, naming the CIDR, is dropped for the one
|
||||||
# below, naming the entry as written. set -f keeps a * in an entry from
|
# below, naming the entry as written. set -f keeps a * in an entry from
|
||||||
# becoming a list of file names.
|
# becoming a list of file names.
|
||||||
TRUSTED_PROXIES="${TRUSTED_PROXIES:-}"
|
TRUSTED_PROXIES="${TRUSTED_PROXIES-10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}"
|
||||||
set -f
|
set -f
|
||||||
for proxy in $(printf '%s' "$TRUSTED_PROXIES" | tr ',' ' '); do
|
for proxy in $(printf '%s' "$TRUSTED_PROXIES" | tr ',' ' '); do
|
||||||
case "$proxy" in
|
case "$proxy" in
|
||||||
|
|||||||
+4
-3
@@ -18,9 +18,10 @@ server {
|
|||||||
|
|
||||||
# The client address comes from X-Forwarded-For only on a request
|
# The client address comes from X-Forwarded-For only on a request
|
||||||
# from the reverse proxies in TRUSTED_PROXIES: bin/entrypoint.sh
|
# from the reverse proxies in TRUSTED_PROXIES: bin/entrypoint.sh
|
||||||
# writes one set_real_ip_from line for each into this file, and
|
# writes one set_real_ip_from line for each into this file. Unset,
|
||||||
# leaves it empty when TRUSTED_PROXIES is unset, so that by default
|
# TRUSTED_PROXIES is the three private ranges of RFC 1918; set and
|
||||||
# the client address is the one each request comes from.
|
# empty, the file is empty and the client address is the one each
|
||||||
|
# request comes from.
|
||||||
include /etc/nginx/trusted-proxies.conf;
|
include /etc/nginx/trusted-proxies.conf;
|
||||||
real_ip_header X-Forwarded-For;
|
real_ip_header X-Forwarded-For;
|
||||||
real_ip_recursive on;
|
real_ip_recursive on;
|
||||||
|
|||||||
@@ -64,8 +64,9 @@ main() {
|
|||||||
# nginx.conf is a template: the image renders it over its own
|
# nginx.conf is a template: the image renders it over its own
|
||||||
# default.conf, with the same port and limit bin/entrypoint.sh uses.
|
# default.conf, with the same port and limit bin/entrypoint.sh uses.
|
||||||
# The empty file it includes trusts no proxy, as bin/entrypoint.sh
|
# The empty file it includes trusts no proxy, as bin/entrypoint.sh
|
||||||
# writes it when TRUSTED_PROXIES is unset. nginx.conf also includes
|
# writes it when TRUSTED_PROXIES is set and empty. nginx.conf also
|
||||||
# the security headers, so the page runs under the shipped policy.
|
# includes the security headers, so the page runs under the shipped
|
||||||
|
# policy.
|
||||||
docker run -d --rm --name "$SERVER" \
|
docker run -d --rm --name "$SERVER" \
|
||||||
--network "$NETWORK" --network-alias netwatch \
|
--network "$NETWORK" --network-alias netwatch \
|
||||||
-e PORT=8080 -e NGINX_ENVSUBST_FILTER='^PORT$' \
|
-e PORT=8080 -e NGINX_ENVSUBST_FILTER='^PORT$' \
|
||||||
|
|||||||
Reference in New Issue
Block a user