1f77473d8f
Proxy / base-URL: - ORCHESTRAD_TRUSTED_PROXIES now defaults to "local", trusting reverse proxies in loopback + RFC1918 + link-local/ULA ranges out of the box, so X-Forwarded-* (client IP, scheme, host) is honored behind an edge proxy without extra config. New keywords: local/private, all/any, none. - OIDC redirect URI derivation now uses the trust-gated request base URL instead of reading X-Forwarded-Proto directly, and audit client IP now trusts the middleware-rewritten RemoteAddr rather than the raw (spoofable) X-Forwarded-For header. Both honor forwarded values only from trusted peers. Schedules: - Seed eight built-in schedules on startup (every 5/15/30 min, hourly, every 6/12h, daily, weekly), idempotent by name, so operators have ready-made cadences in the Schedules page and the rule editor's schedule dropdown without hand-building one. Test covers the trusted-proxy keyword expansion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
package server
|
|
|
|
import (
|
|
"net"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseTrustedProxiesKeywords(t *testing.T) {
|
|
// "local" expands to loopback + private ranges.
|
|
tp, err := parseTrustedProxies([]string{"local"})
|
|
if err != nil {
|
|
t.Fatalf("local: %v", err)
|
|
}
|
|
for _, ip := range []string{"127.0.0.1", "10.1.2.3", "192.168.5.5", "172.16.0.1", "169.254.1.1"} {
|
|
if !tp.contains(net.ParseIP(ip)) {
|
|
t.Errorf("local should trust %s", ip)
|
|
}
|
|
}
|
|
if tp.contains(net.ParseIP("8.8.8.8")) {
|
|
t.Errorf("local should NOT trust a public IP")
|
|
}
|
|
|
|
// "all" trusts everything.
|
|
all, err := parseTrustedProxies([]string{"all"})
|
|
if err != nil {
|
|
t.Fatalf("all: %v", err)
|
|
}
|
|
if !all.contains(net.ParseIP("8.8.8.8")) {
|
|
t.Errorf("all should trust any IP")
|
|
}
|
|
|
|
// "none" and "" trust nothing.
|
|
for _, kw := range []string{"none", ""} {
|
|
none, err := parseTrustedProxies([]string{kw})
|
|
if err != nil {
|
|
t.Fatalf("%q: %v", kw, err)
|
|
}
|
|
if none.contains(net.ParseIP("127.0.0.1")) {
|
|
t.Errorf("%q should trust nothing", kw)
|
|
}
|
|
}
|
|
|
|
// An explicit CIDR still works and is additive with a keyword.
|
|
mix, err := parseTrustedProxies([]string{"local", "203.0.113.0/24"})
|
|
if err != nil {
|
|
t.Fatalf("mix: %v", err)
|
|
}
|
|
if !mix.contains(net.ParseIP("203.0.113.7")) || !mix.contains(net.ParseIP("10.0.0.1")) {
|
|
t.Errorf("mix should trust both the explicit CIDR and local ranges")
|
|
}
|
|
}
|