nginx: trust X-Forwarded-For only from TRUSTED_PROXIES (closes #64)
check / check (push) Successful in 49s
check / check (push) Successful in 49s
nginx trusted X-Forwarded-For from every RFC1918 address, so a client reaching it from one could write a new address on each request and get a fresh rate-limit allowance. The container's TRUSTED_PROXIES now names the reverse proxies nginx trusts, none by default. bin/entrypoint.sh refuses a value with a character no IP address or CIDR has, and writes one set_real_ip_from line per entry into /etc/nginx/trusted-proxies.conf, which nginx.conf includes. The backend is started with TRUSTED_PROXIES=127.0.0.1/32, since nginx is its only client. The viewport test mounts an empty file there. Model: opus-5-5
This commit is contained in:
+27
-4
@@ -32,16 +32,39 @@ if [ "$PORT" -eq 8081 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TRUSTED_PROXIES names the reverse proxies in front of the container,
|
||||
# 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
|
||||
# unset or empty, it trusts no one. nginx would look up a hostname at
|
||||
# start and trust whatever address it found, so a value with a
|
||||
# character no address has stops the container here. An entry such as
|
||||
# 999.1.1.1 gets past this, and nginx refuses it at start as a
|
||||
# hostname it cannot find.
|
||||
TRUSTED_PROXIES="${TRUSTED_PROXIES:-}"
|
||||
case "$TRUSTED_PROXIES" in
|
||||
*[!0-9A-Fa-f.:/,\ ]*)
|
||||
echo "entrypoint: TRUSTED_PROXIES must be IP addresses or CIDRs" \
|
||||
"separated by commas, not '$TRUSTED_PROXIES'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# nginx.conf includes this file; an empty one trusts no proxy.
|
||||
for proxy in $(echo "$TRUSTED_PROXIES" | tr ',' ' '); do
|
||||
echo "set_real_ip_from $proxy;"
|
||||
done > /etc/nginx/trusted-proxies.conf
|
||||
|
||||
# A stop signal is only noted here; the loop below acts on it.
|
||||
stop_requested=""
|
||||
trap 'stop_requested=yes' TERM INT
|
||||
|
||||
# netwatch-server runs as the netwatch user and listens on loopback
|
||||
# only, on a port other than the public one; nginx.conf proxies to this
|
||||
# address. The netwatch user has no login shell, hence -s /bin/sh.
|
||||
# busybox su replaces itself with the command instead of staying on as
|
||||
# its parent, so $! is the server's own PID.
|
||||
BIND_ADDRESS=127.0.0.1 PORT=8081 \
|
||||
# address. Its only client is nginx, so it takes the client address
|
||||
# nginx passes on from 127.0.0.1 alone, whatever TRUSTED_PROXIES the
|
||||
# container has. The netwatch user has no login shell, hence -s
|
||||
# /bin/sh. busybox su replaces itself with the command instead of
|
||||
# staying on as its parent, so $! is the server's own PID.
|
||||
BIND_ADDRESS=127.0.0.1 PORT=8081 TRUSTED_PROXIES=127.0.0.1/32 \
|
||||
su -s /bin/sh netwatch -c 'exec netwatch-server' &
|
||||
backend=$!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user