mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-28 15:29:09 +01:00
[client] Add opt-in --allow-server-rdp flag, reuse SSH ACL, dynamic DLL registration
- Add ServerRDPAllowed field to daemon proto, EngineConfig, and profile config - Add --allow-server-rdp flag to `netbird up` (opt-in, defaults to false) - Wire RDP server start/stop in engine based on the flag - Reuse SSH ACL (SSHAuth proto) for RDP authorization via sshauth.Authorizer - Register/unregister credential provider COM DLL dynamically when flag is toggled - Ship DLL alongside netbird.exe, register via regsvr32 at runtime (not install time) - Update SetConfig tests to cover the new field https://claude.ai/code/session_01C38bCDyYzLgxYLVwJkcUng
This commit is contained in:
@@ -12,6 +12,8 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
sshauth "github.com/netbirdio/netbird/client/ssh/auth"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,6 +47,7 @@ type Server struct {
|
||||
pipeServer PipeServer
|
||||
jwtValidator JWTValidator
|
||||
authorizer Authorizer
|
||||
sshAuthorizer *sshauth.Authorizer // reuses SSH ACL for RDP access control
|
||||
networkAddr netip.Prefix // WireGuard network for source IP validation
|
||||
|
||||
mu sync.Mutex
|
||||
@@ -76,14 +79,21 @@ func New(cfg *Config) *Server {
|
||||
pending := NewPendingStore(ttl)
|
||||
|
||||
return &Server{
|
||||
pending: pending,
|
||||
pipeServer: newPipeServer(pending),
|
||||
jwtValidator: cfg.JWTValidator,
|
||||
authorizer: cfg.Authorizer,
|
||||
networkAddr: cfg.NetworkAddr,
|
||||
pending: pending,
|
||||
pipeServer: newPipeServer(pending),
|
||||
jwtValidator: cfg.JWTValidator,
|
||||
authorizer: cfg.Authorizer,
|
||||
sshAuthorizer: sshauth.NewAuthorizer(),
|
||||
networkAddr: cfg.NetworkAddr,
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateRDPAuth updates the RDP authorization config (reuses SSH ACL).
|
||||
func (s *Server) UpdateRDPAuth(config *sshauth.Config) {
|
||||
s.sshAuthorizer.Update(config)
|
||||
log.Debugf("RDP auth: updated authorization config")
|
||||
}
|
||||
|
||||
// Start begins listening for sideband auth requests on the given address.
|
||||
func (s *Server) Start(ctx context.Context, addr netip.AddrPort) error {
|
||||
s.mu.Lock()
|
||||
@@ -219,12 +229,17 @@ func (s *Server) processAuthRequest(peerIP netip.Addr, req *AuthRequest) *AuthRe
|
||||
return &AuthResponse{Status: StatusDenied, Reason: "JWT validation failed"}
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
// Check authorization - try explicit authorizer first, then SSH ACL
|
||||
if s.authorizer != nil {
|
||||
if _, err := s.authorizer.Authorize(userID, req.RequestedUser); err != nil {
|
||||
log.Warnf("RDP auth denied for user %s -> %s: %v", userID, req.RequestedUser, err)
|
||||
return &AuthResponse{Status: StatusDenied, Reason: "not authorized for this user"}
|
||||
}
|
||||
} else if s.sshAuthorizer != nil {
|
||||
if _, err := s.sshAuthorizer.Authorize(userID, req.RequestedUser); err != nil {
|
||||
log.Warnf("RDP auth denied (SSH ACL) for user %s -> %s: %v", userID, req.RequestedUser, err)
|
||||
return &AuthResponse{Status: StatusDenied, Reason: "not authorized for this user"}
|
||||
}
|
||||
}
|
||||
|
||||
return s.createSession(peerIP, req, userID)
|
||||
|
||||
Reference in New Issue
Block a user