Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1ccea78fb |
@@ -215,12 +215,11 @@ has its forwarded headers ignored, and the direct peer is logged and
|
|||||||
rate-limited instead. From a direct peer inside the set, the client address is
|
rate-limited instead. From a direct peer inside the set, the client address is
|
||||||
the right-most `X-Forwarded-For` entry that is not in the set: each proxy
|
the right-most `X-Forwarded-For` entry that is not in the set: each proxy
|
||||||
appends the address it took the request from, so the entries further left were
|
appends the address it took the request from, so the entries further left were
|
||||||
written by the client and are not used. An entry written as an address with a
|
written by the client and are not used. If the search from the right finds only
|
||||||
port, such as `198.51.100.7:5000` or `[2001:db8::1]:443`, is read as that
|
addresses in the set, or meets an entry that is not an IP address, the direct
|
||||||
address. If the search from the right finds only addresses in the set, or meets
|
peer is used. `X-Real-IP` is read only when `X-Forwarded-For` is missing or
|
||||||
an entry that is not an address at all, such as `unknown`, the direct peer is
|
empty. The container image does not use this default; see
|
||||||
used. `X-Real-IP` is read only when `X-Forwarded-For` is missing or empty. The
|
[Deployment](#deployment).
|
||||||
container image does not use this default; see [Deployment](#deployment).
|
|
||||||
|
|
||||||
A variable set to a value the server cannot use, such as `PORT=abc`,
|
A variable set to a value the server cannot use, such as `PORT=abc`,
|
||||||
`DEBUG=maybe` or a `BIND_ADDRESS` that is not an IP address, stops it from
|
`DEBUG=maybe` or a `BIND_ADDRESS` that is not an IP address, stops it from
|
||||||
|
|||||||
@@ -26,15 +26,13 @@ Run `make frontend-viewport-test` in CI as its own step; it is not part of
|
|||||||
([#144](https://git.eeqj.de/sneak/netwatch/issues/144)). It took the left-most
|
([#144](https://git.eeqj.de/sneak/netwatch/issues/144)). It took the left-most
|
||||||
entry, which the client writes itself behind a proxy that appends to the
|
entry, which the client writes itself behind a proxy that appends to the
|
||||||
header, so a client could choose the address the rate limit counts and the
|
header, so a client could choose the address the rate limit counts and the
|
||||||
request log records. An entry written as an address with a port is read as
|
request log records. With only trusted addresses in the header, or an entry
|
||||||
that address. With only trusted addresses in the header, or an entry that is
|
that is not an IP address met on the way, the direct peer is used. `X-Real-IP`
|
||||||
not an address at all (such as `unknown`) met on the way, the direct peer is
|
is read only without `X-Forwarded-For`, and every `X-Forwarded-For` header
|
||||||
used. `X-Real-IP` is read only without `X-Forwarded-For`, and every
|
line is read, not only the first. The image's nginx, and the
|
||||||
`X-Forwarded-For` header line is read, not only the first. The image's nginx,
|
`TRUSTED_PROXIES=127.0.0.1/32` it starts the backend with, are unchanged. Unit
|
||||||
and the `TRUSTED_PROXIES=127.0.0.1/32` it starts the backend with, are
|
tests resolve the address from chains ending in an untrusted address, in
|
||||||
unchanged. Unit tests resolve the address from chains ending in an untrusted
|
trusted ones, of only trusted ones, and split over two header lines
|
||||||
address, in trusted ones, of only trusted ones, with ports, with an entry that
|
|
||||||
is not an address, and split over two header lines
|
|
||||||
- 2026-10-18: after an interval change, the summary's Reachable slot reads
|
- 2026-10-18: after an interval change, the summary's Reachable slot reads
|
||||||
`--/--` in white, as at page load, until the second round since the change
|
`--/--` in white, as at page load, until the second round since the change
|
||||||
ends ([#140](https://git.eeqj.de/sneak/netwatch/issues/140)). It used to read
|
ends ([#140](https://git.eeqj.de/sneak/netwatch/issues/140)). It used to read
|
||||||
|
|||||||
@@ -139,12 +139,10 @@ func ipFromHostPort(hostPort string) string {
|
|||||||
// request from, so the entries on the right are written by the
|
// request from, so the entries on the right are written by the
|
||||||
// trusted proxies and those further left by the client. The
|
// trusted proxies and those further left by the client. The
|
||||||
// client's address is therefore the right-most entry that is not
|
// client's address is therefore the right-most entry that is not
|
||||||
// a trusted proxy. An entry written as an address with a port is
|
// a trusted proxy. When every entry is a trusted proxy, or the
|
||||||
// read as that address, both for the trust check and as the
|
// walk from the right meets an entry that is not an address, the
|
||||||
// result. When every entry is a trusted proxy, or the walk from
|
// peer is used. X-Real-IP is read only when there is no
|
||||||
// the right meets an entry that is not an address at all (such as
|
// X-Forwarded-For entry at all.
|
||||||
// "unknown"), the peer is used. X-Real-IP is read only when there
|
|
||||||
// is no X-Forwarded-For entry at all.
|
|
||||||
func clientIP(
|
func clientIP(
|
||||||
remoteAddr string,
|
remoteAddr string,
|
||||||
header http.Header,
|
header http.Header,
|
||||||
@@ -182,10 +180,7 @@ func clientIP(
|
|||||||
// forwardedFor returns the entries of X-Forwarded-For in order,
|
// forwardedFor returns the entries of X-Forwarded-For in order,
|
||||||
// leaving out blank ones. A proxy may add its entry as a header
|
// leaving out blank ones. A proxy may add its entry as a header
|
||||||
// line of its own rather than append it to the line the client
|
// line of its own rather than append it to the line the client
|
||||||
// sent, so every line is read, not only the first. Some proxies
|
// sent, so every line is read, not only the first.
|
||||||
// write an entry as an address with a port, such as
|
|
||||||
// 198.51.100.7:5000 or [2001:db8::1]:443; the port is removed so
|
|
||||||
// that the entry is read as its address.
|
|
||||||
func forwardedFor(header http.Header) []string {
|
func forwardedFor(header http.Header) []string {
|
||||||
value := strings.Join(header.Values("X-Forwarded-For"), ",")
|
value := strings.Join(header.Values("X-Forwarded-For"), ",")
|
||||||
|
|
||||||
@@ -194,7 +189,7 @@ func forwardedFor(header http.Header) []string {
|
|||||||
for part := range strings.SplitSeq(value, ",") {
|
for part := range strings.SplitSeq(value, ",") {
|
||||||
entry := strings.TrimSpace(part)
|
entry := strings.TrimSpace(part)
|
||||||
if entry != "" {
|
if entry != "" {
|
||||||
entries = append(entries, ipFromHostPort(entry))
|
entries = append(entries, entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,28 +105,10 @@ func clientIPCases() []clientIPCase {
|
|||||||
xff: "10.0.0.5, 10.1.2.3",
|
xff: "10.0.0.5, 10.1.2.3",
|
||||||
want: loopbackIP,
|
want: loopbackIP,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "entry with a port is read as its address",
|
|
||||||
remoteAddr: loopbackPeer,
|
|
||||||
xff: "203.0.113.9, 198.51.100.7:5000",
|
|
||||||
want: "198.51.100.7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ipv6 entry with a port is read as its address",
|
|
||||||
remoteAddr: loopbackPeer,
|
|
||||||
xff: "203.0.113.9, [2001:db8::1]:443",
|
|
||||||
want: "2001:db8::1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "trusted proxy entry with a port is skipped",
|
|
||||||
remoteAddr: loopbackPeer,
|
|
||||||
xff: "203.0.113.9, 10.0.0.5:5000",
|
|
||||||
want: "203.0.113.9",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "entry that is not an address uses peer",
|
name: "entry that is not an address uses peer",
|
||||||
remoteAddr: loopbackPeer,
|
remoteAddr: loopbackPeer,
|
||||||
xff: "203.0.113.9, unknown",
|
xff: "203.0.113.9, 198.51.100.7:5000",
|
||||||
want: loopbackIP,
|
want: loopbackIP,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user