mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-01 14:46:41 +00:00
[client] Unexport GetServerPublicKey, add HealthCheck method (#5735)
* Unexport GetServerPublicKey, add HealthCheck method Internalize server key fetching into Login, Register, GetDeviceAuthorizationFlow, and GetPKCEAuthorizationFlow methods, removing the need for callers to fetch and pass the key separately. Replace the exported GetServerPublicKey with a HealthCheck() error method for connection validation, keeping IsHealthy() bool for non-blocking background monitoring. Fix test encryption to use correct key pairs (client public key as remotePubKey instead of server private key). * Refactor `doMgmLogin` to return only error, removing unused response
This commit is contained in:
@@ -202,7 +202,7 @@ func (c *GrpcClient) withMgmtStream(
|
||||
return fmt.Errorf("connection to management is not ready and in %s state", connState)
|
||||
}
|
||||
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
log.Debugf(errMsgMgmtPublicKey, err)
|
||||
return err
|
||||
@@ -404,7 +404,7 @@ func (c *GrpcClient) handleSyncStream(ctx context.Context, serverPubKey wgtypes.
|
||||
|
||||
// GetNetworkMap return with the network map
|
||||
func (c *GrpcClient) GetNetworkMap(sysInfo *system.Info) (*proto.NetworkMap, error) {
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
log.Debugf("failed getting Management Service public key: %s", err)
|
||||
return nil, err
|
||||
@@ -490,18 +490,24 @@ func (c *GrpcClient) receiveUpdatesEvents(stream proto.ManagementService_SyncCli
|
||||
}
|
||||
}
|
||||
|
||||
// GetServerPublicKey returns server's WireGuard public key (used later for encrypting messages sent to the server)
|
||||
func (c *GrpcClient) GetServerPublicKey() (*wgtypes.Key, error) {
|
||||
// HealthCheck actively probes the management server and returns an error if unreachable.
|
||||
// Used to validate connectivity before committing configuration changes.
|
||||
func (c *GrpcClient) HealthCheck() error {
|
||||
if !c.ready() {
|
||||
return nil, errors.New(errMsgNoMgmtConnection)
|
||||
return errors.New(errMsgNoMgmtConnection)
|
||||
}
|
||||
|
||||
_, err := c.getServerPublicKey()
|
||||
return err
|
||||
}
|
||||
|
||||
// getServerPublicKey fetches the server's WireGuard public key.
|
||||
func (c *GrpcClient) getServerPublicKey() (*wgtypes.Key, error) {
|
||||
mgmCtx, cancel := context.WithTimeout(c.ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
resp, err := c.realClient.GetServerKey(mgmCtx, &proto.Empty{})
|
||||
if err != nil {
|
||||
log.Errorf("failed while getting Management Service public key: %v", err)
|
||||
return nil, fmt.Errorf("failed while getting Management Service public key")
|
||||
return nil, fmt.Errorf("failed getting Management Service public key: %w", err)
|
||||
}
|
||||
|
||||
serverKey, err := wgtypes.ParseKey(resp.Key)
|
||||
@@ -512,7 +518,8 @@ func (c *GrpcClient) GetServerPublicKey() (*wgtypes.Key, error) {
|
||||
return &serverKey, nil
|
||||
}
|
||||
|
||||
// IsHealthy probes the gRPC connection and returns false on errors
|
||||
// IsHealthy returns the current connection status without blocking.
|
||||
// Used by the engine to monitor connectivity in the background.
|
||||
func (c *GrpcClient) IsHealthy() bool {
|
||||
switch c.conn.GetState() {
|
||||
case connectivity.TransientFailure:
|
||||
@@ -538,12 +545,17 @@ func (c *GrpcClient) IsHealthy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *GrpcClient) login(serverKey wgtypes.Key, req *proto.LoginRequest) (*proto.LoginResponse, error) {
|
||||
func (c *GrpcClient) login(req *proto.LoginRequest) (*proto.LoginResponse, error) {
|
||||
if !c.ready() {
|
||||
return nil, errors.New(errMsgNoMgmtConnection)
|
||||
}
|
||||
|
||||
loginReq, err := encryption.EncryptMessage(serverKey, c.key, req)
|
||||
serverKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
loginReq, err := encryption.EncryptMessage(*serverKey, c.key, req)
|
||||
if err != nil {
|
||||
log.Errorf("failed to encrypt message: %s", err)
|
||||
return nil, err
|
||||
@@ -577,7 +589,7 @@ func (c *GrpcClient) login(serverKey wgtypes.Key, req *proto.LoginRequest) (*pro
|
||||
}
|
||||
|
||||
loginResp := &proto.LoginResponse{}
|
||||
err = encryption.DecryptMessage(serverKey, c.key, resp.Body, loginResp)
|
||||
err = encryption.DecryptMessage(*serverKey, c.key, resp.Body, loginResp)
|
||||
if err != nil {
|
||||
log.Errorf("failed to decrypt login response: %s", err)
|
||||
return nil, err
|
||||
@@ -589,34 +601,40 @@ func (c *GrpcClient) login(serverKey wgtypes.Key, req *proto.LoginRequest) (*pro
|
||||
// Register registers peer on Management Server. It actually calls a Login endpoint with a provided setup key
|
||||
// Takes care of encrypting and decrypting messages.
|
||||
// This method will also collect system info and send it with the request (e.g. hostname, os, etc)
|
||||
func (c *GrpcClient) Register(serverKey wgtypes.Key, setupKey string, jwtToken string, sysInfo *system.Info, pubSSHKey []byte, dnsLabels domain.List) (*proto.LoginResponse, error) {
|
||||
func (c *GrpcClient) Register(setupKey string, jwtToken string, sysInfo *system.Info, pubSSHKey []byte, dnsLabels domain.List) (*proto.LoginResponse, error) {
|
||||
keys := &proto.PeerKeys{
|
||||
SshPubKey: pubSSHKey,
|
||||
WgPubKey: []byte(c.key.PublicKey().String()),
|
||||
}
|
||||
return c.login(serverKey, &proto.LoginRequest{SetupKey: setupKey, Meta: infoToMetaData(sysInfo), JwtToken: jwtToken, PeerKeys: keys, DnsLabels: dnsLabels.ToPunycodeList()})
|
||||
return c.login(&proto.LoginRequest{SetupKey: setupKey, Meta: infoToMetaData(sysInfo), JwtToken: jwtToken, PeerKeys: keys, DnsLabels: dnsLabels.ToPunycodeList()})
|
||||
}
|
||||
|
||||
// Login attempts login to Management Server. Takes care of encrypting and decrypting messages.
|
||||
func (c *GrpcClient) Login(serverKey wgtypes.Key, sysInfo *system.Info, pubSSHKey []byte, dnsLabels domain.List) (*proto.LoginResponse, error) {
|
||||
func (c *GrpcClient) Login(sysInfo *system.Info, pubSSHKey []byte, dnsLabels domain.List) (*proto.LoginResponse, error) {
|
||||
keys := &proto.PeerKeys{
|
||||
SshPubKey: pubSSHKey,
|
||||
WgPubKey: []byte(c.key.PublicKey().String()),
|
||||
}
|
||||
return c.login(serverKey, &proto.LoginRequest{Meta: infoToMetaData(sysInfo), PeerKeys: keys, DnsLabels: dnsLabels.ToPunycodeList()})
|
||||
return c.login(&proto.LoginRequest{Meta: infoToMetaData(sysInfo), PeerKeys: keys, DnsLabels: dnsLabels.ToPunycodeList()})
|
||||
}
|
||||
|
||||
// GetDeviceAuthorizationFlow returns a device authorization flow information.
|
||||
// It also takes care of encrypting and decrypting messages.
|
||||
func (c *GrpcClient) GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.DeviceAuthorizationFlow, error) {
|
||||
func (c *GrpcClient) GetDeviceAuthorizationFlow() (*proto.DeviceAuthorizationFlow, error) {
|
||||
if !c.ready() {
|
||||
return nil, fmt.Errorf("no connection to management in order to get device authorization flow")
|
||||
}
|
||||
|
||||
serverKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mgmCtx, cancel := context.WithTimeout(c.ctx, time.Second*2)
|
||||
defer cancel()
|
||||
|
||||
message := &proto.DeviceAuthorizationFlowRequest{}
|
||||
encryptedMSG, err := encryption.EncryptMessage(serverKey, c.key, message)
|
||||
encryptedMSG, err := encryption.EncryptMessage(*serverKey, c.key, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -630,7 +648,7 @@ func (c *GrpcClient) GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.D
|
||||
}
|
||||
|
||||
flowInfoResp := &proto.DeviceAuthorizationFlow{}
|
||||
err = encryption.DecryptMessage(serverKey, c.key, resp.Body, flowInfoResp)
|
||||
err = encryption.DecryptMessage(*serverKey, c.key, resp.Body, flowInfoResp)
|
||||
if err != nil {
|
||||
errWithMSG := fmt.Errorf("failed to decrypt device authorization flow message: %s", err)
|
||||
log.Error(errWithMSG)
|
||||
@@ -642,15 +660,21 @@ func (c *GrpcClient) GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.D
|
||||
|
||||
// GetPKCEAuthorizationFlow returns a pkce authorization flow information.
|
||||
// It also takes care of encrypting and decrypting messages.
|
||||
func (c *GrpcClient) GetPKCEAuthorizationFlow(serverKey wgtypes.Key) (*proto.PKCEAuthorizationFlow, error) {
|
||||
func (c *GrpcClient) GetPKCEAuthorizationFlow() (*proto.PKCEAuthorizationFlow, error) {
|
||||
if !c.ready() {
|
||||
return nil, fmt.Errorf("no connection to management in order to get pkce authorization flow")
|
||||
}
|
||||
|
||||
serverKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mgmCtx, cancel := context.WithTimeout(c.ctx, time.Second*2)
|
||||
defer cancel()
|
||||
|
||||
message := &proto.PKCEAuthorizationFlowRequest{}
|
||||
encryptedMSG, err := encryption.EncryptMessage(serverKey, c.key, message)
|
||||
encryptedMSG, err := encryption.EncryptMessage(*serverKey, c.key, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -664,7 +688,7 @@ func (c *GrpcClient) GetPKCEAuthorizationFlow(serverKey wgtypes.Key) (*proto.PKC
|
||||
}
|
||||
|
||||
flowInfoResp := &proto.PKCEAuthorizationFlow{}
|
||||
err = encryption.DecryptMessage(serverKey, c.key, resp.Body, flowInfoResp)
|
||||
err = encryption.DecryptMessage(*serverKey, c.key, resp.Body, flowInfoResp)
|
||||
if err != nil {
|
||||
errWithMSG := fmt.Errorf("failed to decrypt pkce authorization flow message: %s", err)
|
||||
log.Error(errWithMSG)
|
||||
@@ -681,7 +705,7 @@ func (c *GrpcClient) SyncMeta(sysInfo *system.Info) error {
|
||||
return errors.New(errMsgNoMgmtConnection)
|
||||
}
|
||||
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
log.Debugf(errMsgMgmtPublicKey, err)
|
||||
return err
|
||||
@@ -724,7 +748,7 @@ func (c *GrpcClient) notifyConnected() {
|
||||
}
|
||||
|
||||
func (c *GrpcClient) Logout() error {
|
||||
serverKey, err := c.GetServerPublicKey()
|
||||
serverKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get server public key: %w", err)
|
||||
}
|
||||
@@ -751,7 +775,7 @@ func (c *GrpcClient) Logout() error {
|
||||
|
||||
// CreateExpose calls the management server to create a new expose service.
|
||||
func (c *GrpcClient) CreateExpose(ctx context.Context, req ExposeRequest) (*ExposeResponse, error) {
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -787,7 +811,7 @@ func (c *GrpcClient) CreateExpose(ctx context.Context, req ExposeRequest) (*Expo
|
||||
|
||||
// RenewExpose extends the TTL of an active expose session on the management server.
|
||||
func (c *GrpcClient) RenewExpose(ctx context.Context, domain string) error {
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -810,7 +834,7 @@ func (c *GrpcClient) RenewExpose(ctx context.Context, domain string) error {
|
||||
|
||||
// StopExpose terminates an active expose session on the management server.
|
||||
func (c *GrpcClient) StopExpose(ctx context.Context, domain string) error {
|
||||
serverPubKey, err := c.GetServerPublicKey()
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user