mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-08 15:41:15 +02:00
* Revert "volume: fail closed in admin gRPC gate when no whitelist is configured (#9440)" This reverts commit21054b6c18. The fail-closed gate broke any multi-host cluster: in compose / k8s / remote-host deployments the master's IP isn't loopback, so every master->volume admin RPC (AllocateVolume, BatchDelete, EC reroute, vacuum, scrub, ...) is rejected with PermissionDenied unless the operator manually configures -whiteList. The e2e workflow has been failing since10cc06333with `not authorized: 172.18.0.2` on AllocateVolume; downstream symptom is fio fsync EIO because zero volumes can be grown. The gate's intent was to lock down destructive admin tooling, but the same RPCs are the master's normal mechanism for growing and managing volumes. Reverting to restore cluster-internal operation; a narrower re-do should distinguish operator/admin callers from the master peer (e.g. trust IPs resolved from -master) before going back in. * security: skip invalid CIDR in UpdateWhiteList so IsWhiteListed can't panic The revert in the previous commit also rolled back an unrelated bug fix that lived inside #9440: UpdateWhiteList logged on net.ParseCIDR error but did not continue, so the nil *net.IPNet was stored in whiteListCIDR and IsWhiteListed would panic dereferencing cidrnet.Contains(remote) on the next gRPC admin check. Restore the continue. Orthogonal to the fail-closed semantics this PR is reverting.
51 lines
1.7 KiB
Go
51 lines
1.7 KiB
Go
package security
|
|
|
|
import "testing"
|
|
|
|
// TestIsWhiteListedEmptyConfigAllowsEverything pins the contract that the
|
|
// gRPC admin auth helper relies on: when no whitelist and no signing key
|
|
// are configured, IsWhiteListed accepts any host (including the empty
|
|
// string and unparseable peer addresses like the gRPC "@" passthrough
|
|
// form). Otherwise insecure default deployments would lock themselves out
|
|
// of every destructive admin RPC.
|
|
func TestIsWhiteListedEmptyConfigAllowsEverything(t *testing.T) {
|
|
g := NewGuard(nil, "", 0, "", 0)
|
|
for _, host := range []string{"", "@", "127.0.0.1", "::1", "garbage:value"} {
|
|
if !g.IsWhiteListed(host) {
|
|
t.Errorf("empty config should accept host=%q, got false", host)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsWhiteListedWithListRejectsUnknown(t *testing.T) {
|
|
g := NewGuard([]string{"10.0.0.1", "192.168.1.0/24"}, "", 0, "", 0)
|
|
cases := []struct {
|
|
host string
|
|
want bool
|
|
}{
|
|
{"10.0.0.1", true},
|
|
{"192.168.1.42", true},
|
|
{"192.168.2.1", false},
|
|
{"127.0.0.1", false},
|
|
{"", false},
|
|
{"@", false},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := g.IsWhiteListed(tc.host); got != tc.want {
|
|
t.Errorf("IsWhiteListed(%q) = %v want %v", tc.host, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsWhiteListedWithSigningKeyButNoWhitelistAllowsAll(t *testing.T) {
|
|
// JWT-only mode: signing key set, whitelist empty. Without this branch
|
|
// the gRPC admin auth helper would falsely deny in-process callers when
|
|
// the operator wires up signing keys but hasn't enumerated IPs.
|
|
g := NewGuard(nil, "deadbeef", 0, "", 0)
|
|
for _, host := range []string{"", "@", "127.0.0.1"} {
|
|
if !g.IsWhiteListed(host) {
|
|
t.Errorf("signing-key + empty whitelist should accept host=%q", host)
|
|
}
|
|
}
|
|
}
|