feat: default trusted_proxies to the rfc1918 private ranges
An omitted trusted_proxies key now defaults to 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 instead of trusting no one, matching the deployment where pixa sits behind a proxy on a private network. An explicitly empty list still trusts nothing, and an explicit list replaces the default; these are distinguished by parseCIDRList returning nil only for an absent key. Loopback is excluded, as it is not an RFC 1918 range. Model: opus-4-8
This commit is contained in:
@@ -122,8 +122,11 @@ type Config struct {
|
|||||||
// forwarding headers may be believed. Forwarded headers are honored
|
// forwarding headers may be believed. Forwarded headers are honored
|
||||||
// only when the immediate peer falls inside one of these ranges;
|
// only when the immediate peer falls inside one of these ranges;
|
||||||
// otherwise the peer address is used and the headers are ignored, so
|
// otherwise the peer address is used and the headers are ignored, so
|
||||||
// an untrusted client cannot spoof its address. Empty means trust
|
// an untrusted client cannot spoof its address. An omitted key
|
||||||
// nothing and always use the peer address.
|
// defaults to the RFC 1918 private ranges (see defaultTrustedProxies),
|
||||||
|
// since pixa is deployed behind a proxy on a private network; an
|
||||||
|
// explicitly empty list trusts nothing and always uses the peer
|
||||||
|
// address, and an explicit list replaces the default.
|
||||||
TrustedProxies []netip.Prefix
|
TrustedProxies []netip.Prefix
|
||||||
|
|
||||||
// CacheMaxBytes is the disk cache size limit in bytes. Zero
|
// CacheMaxBytes is the disk cache size limit in bytes. Zero
|
||||||
@@ -204,6 +207,14 @@ func newFromSmartConfig(sc *smartconfig.Config) (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseCIDRList returns a nil slice only when the key is absent; an
|
||||||
|
// explicitly empty list ([]) comes back non-nil and empty. An omitted
|
||||||
|
// key takes the RFC 1918 default, while an explicit empty list is left
|
||||||
|
// as trust-nothing.
|
||||||
|
if trustedProxies == nil {
|
||||||
|
trustedProxies = defaultTrustedProxies()
|
||||||
|
}
|
||||||
|
|
||||||
loader := &strictLoader{sc: sc}
|
loader := &strictLoader{sc: sc}
|
||||||
|
|
||||||
c := &Config{
|
c := &Config{
|
||||||
@@ -839,6 +850,21 @@ func getStringSlice(sc *smartconfig.Config) []string {
|
|||||||
// wrong type, an empty entry, a non-string entry, or an unparseable CIDR
|
// wrong type, an empty entry, a non-string entry, or an unparseable CIDR
|
||||||
// aborts startup naming the key and the offending value; the default
|
// aborts startup naming the key and the offending value; the default
|
||||||
// (an empty list) applies only to an omitted key.
|
// (an empty list) applies only to an omitted key.
|
||||||
|
// defaultTrustedProxies returns the trusted_proxies default: the three RFC
|
||||||
|
// 1918 private ranges. pixa is always deployed behind a TLS-terminating
|
||||||
|
// reverse proxy, which in practice sits on a private network, so its
|
||||||
|
// forwarding headers are believed unless the operator says otherwise.
|
||||||
|
// Loopback is deliberately excluded: it is not an RFC 1918 range, and no
|
||||||
|
// deployment reaches pixa over it. A fresh slice is returned on each call so
|
||||||
|
// callers may hold it without aliasing shared state.
|
||||||
|
func defaultTrustedProxies() []netip.Prefix {
|
||||||
|
return []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("10.0.0.0/8"),
|
||||||
|
netip.MustParsePrefix("172.16.0.0/12"),
|
||||||
|
netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func parseCIDRList(sc *smartconfig.Config, key string) ([]netip.Prefix, error) {
|
func parseCIDRList(sc *smartconfig.Config, key string) ([]netip.Prefix, error) {
|
||||||
if sc == nil {
|
if sc == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user