security: add method-level authorization for privileged RPC methods
RELEASE BLOCKER FIX - Prevents containers from triggering host-level operations. Added host-only method restrictions: - RPCEnsureClusterKeys (SSH key distribution) - RPCRegisterNodes (node registration) - RPCRequestCleanup (cleanup operations) Implementation: - New privilegedMethods map defines host-only methods - Request handler checks if method is privileged - If privileged AND caller is from ID-mapped UID range (container), reject - Host processes (real root, configured UIDs) can still call privileged methods - Containers can still call get_temperature and get_status Security impact: - Prevents compromised containers from: • Triggering unwanted SSH key distribution to cluster nodes • Learning about cluster topology via forced registration • DOS attacks by repeatedly calling key distribution • Other host-level privileged operations Without this fix, any container with root could call these methods after authentication, undermining the security isolation between container and host. Addresses high-severity finding #2 from security audit.
This commit is contained in:
parent
3a6a4fd362
commit
026b9c5b77
1 changed files with 21 additions and 0 deletions
|
|
@ -106,6 +106,13 @@ const (
|
||||||
RPCRequestCleanup = "request_cleanup"
|
RPCRequestCleanup = "request_cleanup"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Privileged RPC methods that require host-level access (not accessible from containers)
|
||||||
|
var privilegedMethods = map[string]bool{
|
||||||
|
RPCEnsureClusterKeys: true, // SSH key distribution
|
||||||
|
RPCRegisterNodes: true, // Node registration
|
||||||
|
RPCRequestCleanup: true, // Cleanup operations
|
||||||
|
}
|
||||||
|
|
||||||
// RPCRequest represents a request from Pulse
|
// RPCRequest represents a request from Pulse
|
||||||
type RPCRequest struct {
|
type RPCRequest struct {
|
||||||
CorrelationID string `json:"correlation_id,omitempty"`
|
CorrelationID string `json:"correlation_id,omitempty"`
|
||||||
|
|
@ -388,6 +395,20 @@ func (p *Proxy) handleConnection(conn net.Conn) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if method requires host-level privileges
|
||||||
|
if privilegedMethods[req.Method] {
|
||||||
|
// Privileged methods can only be called from host (not from containers)
|
||||||
|
if p.isIDMappedRoot(cred) {
|
||||||
|
resp.Error = "method requires host-level privileges"
|
||||||
|
logger.Warn().
|
||||||
|
Str("method", req.Method).
|
||||||
|
Msg("Container attempted to call privileged method")
|
||||||
|
p.sendResponse(conn, resp)
|
||||||
|
p.metrics.rpcRequests.WithLabelValues(req.Method, "unauthorized").Inc()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Execute handler
|
// Execute handler
|
||||||
result, err := handler(ctx, &req, logger)
|
result, err := handler(ctx, &req, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue