mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:24:18 -04:00
[client,management] Rewrite the SSH feature (#4015)
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -84,6 +84,15 @@ service DaemonService {
|
||||
rpc Logout(LogoutRequest) returns (LogoutResponse) {}
|
||||
|
||||
rpc GetFeatures(GetFeaturesRequest) returns (GetFeaturesResponse) {}
|
||||
|
||||
// GetPeerSSHHostKey retrieves SSH host key for a specific peer
|
||||
rpc GetPeerSSHHostKey(GetPeerSSHHostKeyRequest) returns (GetPeerSSHHostKeyResponse) {}
|
||||
|
||||
// RequestJWTAuth initiates JWT authentication flow for SSH
|
||||
rpc RequestJWTAuth(RequestJWTAuthRequest) returns (RequestJWTAuthResponse) {}
|
||||
|
||||
// WaitJWTToken waits for JWT authentication completion
|
||||
rpc WaitJWTToken(WaitJWTTokenRequest) returns (WaitJWTTokenResponse) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +170,13 @@ message LoginRequest {
|
||||
|
||||
// hint is used to pre-fill the email/username field during SSO authentication
|
||||
optional string hint = 33;
|
||||
|
||||
optional bool enableSSHRoot = 34;
|
||||
optional bool enableSSHSFTP = 35;
|
||||
optional bool enableSSHLocalPortForwarding = 36;
|
||||
optional bool enableSSHRemotePortForwarding = 37;
|
||||
optional bool disableSSHAuth = 38;
|
||||
optional int32 sshJWTCacheTTL = 39;
|
||||
}
|
||||
|
||||
message LoginResponse {
|
||||
@@ -188,9 +204,9 @@ message UpResponse {}
|
||||
|
||||
message StatusRequest{
|
||||
bool getFullPeerStatus = 1;
|
||||
bool shouldRunProbes = 2;
|
||||
bool shouldRunProbes = 2;
|
||||
// the UI do not using this yet, but CLIs could use it to wait until the status is ready
|
||||
optional bool waitForReady = 3;
|
||||
optional bool waitForReady = 3;
|
||||
}
|
||||
|
||||
message StatusResponse{
|
||||
@@ -255,6 +271,18 @@ message GetConfigResponse {
|
||||
bool disable_server_routes = 19;
|
||||
|
||||
bool block_lan_access = 20;
|
||||
|
||||
bool enableSSHRoot = 21;
|
||||
|
||||
bool enableSSHSFTP = 24;
|
||||
|
||||
bool enableSSHLocalPortForwarding = 22;
|
||||
|
||||
bool enableSSHRemotePortForwarding = 23;
|
||||
|
||||
bool disableSSHAuth = 25;
|
||||
|
||||
int32 sshJWTCacheTTL = 26;
|
||||
}
|
||||
|
||||
// PeerState contains the latest state of a peer
|
||||
@@ -276,6 +304,7 @@ message PeerState {
|
||||
repeated string networks = 16;
|
||||
google.protobuf.Duration latency = 17;
|
||||
string relayAddress = 18;
|
||||
bytes sshHostKey = 19;
|
||||
}
|
||||
|
||||
// LocalPeerState contains the latest state of the local peer
|
||||
@@ -317,6 +346,20 @@ message NSGroupState {
|
||||
string error = 4;
|
||||
}
|
||||
|
||||
// SSHSessionInfo contains information about an active SSH session
|
||||
message SSHSessionInfo {
|
||||
string username = 1;
|
||||
string remoteAddress = 2;
|
||||
string command = 3;
|
||||
string jwtUsername = 4;
|
||||
}
|
||||
|
||||
// SSHServerState contains the latest state of the SSH server
|
||||
message SSHServerState {
|
||||
bool enabled = 1;
|
||||
repeated SSHSessionInfo sessions = 2;
|
||||
}
|
||||
|
||||
// FullStatus contains the full state held by the Status instance
|
||||
message FullStatus {
|
||||
ManagementState managementState = 1;
|
||||
@@ -330,6 +373,7 @@ message FullStatus {
|
||||
repeated SystemEvent events = 7;
|
||||
|
||||
bool lazyConnectionEnabled = 9;
|
||||
SSHServerState sshServerState = 10;
|
||||
}
|
||||
|
||||
// Networks
|
||||
@@ -543,56 +587,63 @@ message SwitchProfileRequest {
|
||||
message SwitchProfileResponse {}
|
||||
|
||||
message SetConfigRequest {
|
||||
string username = 1;
|
||||
string profileName = 2;
|
||||
// managementUrl to authenticate.
|
||||
string managementUrl = 3;
|
||||
string username = 1;
|
||||
string profileName = 2;
|
||||
// managementUrl to authenticate.
|
||||
string managementUrl = 3;
|
||||
|
||||
// adminUrl to manage keys.
|
||||
string adminURL = 4;
|
||||
// adminUrl to manage keys.
|
||||
string adminURL = 4;
|
||||
|
||||
optional bool rosenpassEnabled = 5;
|
||||
optional bool rosenpassEnabled = 5;
|
||||
|
||||
optional string interfaceName = 6;
|
||||
optional string interfaceName = 6;
|
||||
|
||||
optional int64 wireguardPort = 7;
|
||||
optional int64 wireguardPort = 7;
|
||||
|
||||
optional string optionalPreSharedKey = 8;
|
||||
optional string optionalPreSharedKey = 8;
|
||||
|
||||
optional bool disableAutoConnect = 9;
|
||||
optional bool disableAutoConnect = 9;
|
||||
|
||||
optional bool serverSSHAllowed = 10;
|
||||
optional bool serverSSHAllowed = 10;
|
||||
|
||||
optional bool rosenpassPermissive = 11;
|
||||
optional bool rosenpassPermissive = 11;
|
||||
|
||||
optional bool networkMonitor = 12;
|
||||
optional bool networkMonitor = 12;
|
||||
|
||||
optional bool disable_client_routes = 13;
|
||||
optional bool disable_server_routes = 14;
|
||||
optional bool disable_dns = 15;
|
||||
optional bool disable_firewall = 16;
|
||||
optional bool block_lan_access = 17;
|
||||
optional bool disable_client_routes = 13;
|
||||
optional bool disable_server_routes = 14;
|
||||
optional bool disable_dns = 15;
|
||||
optional bool disable_firewall = 16;
|
||||
optional bool block_lan_access = 17;
|
||||
|
||||
optional bool disable_notifications = 18;
|
||||
optional bool disable_notifications = 18;
|
||||
|
||||
optional bool lazyConnectionEnabled = 19;
|
||||
optional bool lazyConnectionEnabled = 19;
|
||||
|
||||
optional bool block_inbound = 20;
|
||||
optional bool block_inbound = 20;
|
||||
|
||||
repeated string natExternalIPs = 21;
|
||||
bool cleanNATExternalIPs = 22;
|
||||
repeated string natExternalIPs = 21;
|
||||
bool cleanNATExternalIPs = 22;
|
||||
|
||||
bytes customDNSAddress = 23;
|
||||
bytes customDNSAddress = 23;
|
||||
|
||||
repeated string extraIFaceBlacklist = 24;
|
||||
repeated string extraIFaceBlacklist = 24;
|
||||
|
||||
repeated string dns_labels = 25;
|
||||
// cleanDNSLabels clean map list of DNS labels.
|
||||
bool cleanDNSLabels = 26;
|
||||
repeated string dns_labels = 25;
|
||||
// cleanDNSLabels clean map list of DNS labels.
|
||||
bool cleanDNSLabels = 26;
|
||||
|
||||
optional google.protobuf.Duration dnsRouteInterval = 27;
|
||||
optional google.protobuf.Duration dnsRouteInterval = 27;
|
||||
|
||||
optional int64 mtu = 28;
|
||||
optional int64 mtu = 28;
|
||||
|
||||
optional bool enableSSHRoot = 29;
|
||||
optional bool enableSSHSFTP = 30;
|
||||
optional bool enableSSHLocalPortForwarding = 31;
|
||||
optional bool enableSSHRemotePortForwarding = 32;
|
||||
optional bool disableSSHAuth = 33;
|
||||
optional int32 sshJWTCacheTTL = 34;
|
||||
}
|
||||
|
||||
message SetConfigResponse{}
|
||||
@@ -644,3 +695,63 @@ message GetFeaturesResponse{
|
||||
bool disable_profiles = 1;
|
||||
bool disable_update_settings = 2;
|
||||
}
|
||||
|
||||
// GetPeerSSHHostKeyRequest for retrieving SSH host key for a specific peer
|
||||
message GetPeerSSHHostKeyRequest {
|
||||
// peer IP address or FQDN to get SSH host key for
|
||||
string peerAddress = 1;
|
||||
}
|
||||
|
||||
// GetPeerSSHHostKeyResponse contains the SSH host key for the requested peer
|
||||
message GetPeerSSHHostKeyResponse {
|
||||
// SSH host key in SSH public key format (e.g., "ssh-ed25519 AAAAC3... hostname")
|
||||
bytes sshHostKey = 1;
|
||||
// peer IP address
|
||||
string peerIP = 2;
|
||||
// peer FQDN
|
||||
string peerFQDN = 3;
|
||||
// indicates if the SSH host key was found
|
||||
bool found = 4;
|
||||
}
|
||||
|
||||
// RequestJWTAuthRequest for initiating JWT authentication flow
|
||||
message RequestJWTAuthRequest {
|
||||
// hint for OIDC login_hint parameter (typically email address)
|
||||
optional string hint = 1;
|
||||
}
|
||||
|
||||
// RequestJWTAuthResponse contains authentication flow information
|
||||
message RequestJWTAuthResponse {
|
||||
// verification URI for user authentication
|
||||
string verificationURI = 1;
|
||||
// complete verification URI (with embedded user code)
|
||||
string verificationURIComplete = 2;
|
||||
// user code to enter on verification URI
|
||||
string userCode = 3;
|
||||
// device code for polling
|
||||
string deviceCode = 4;
|
||||
// expiration time in seconds
|
||||
int64 expiresIn = 5;
|
||||
// if a cached token is available, it will be returned here
|
||||
string cachedToken = 6;
|
||||
// maximum age of JWT tokens in seconds (from management server)
|
||||
int64 maxTokenAge = 7;
|
||||
}
|
||||
|
||||
// WaitJWTTokenRequest for waiting for authentication completion
|
||||
message WaitJWTTokenRequest {
|
||||
// device code from RequestJWTAuthResponse
|
||||
string deviceCode = 1;
|
||||
// user code for verification
|
||||
string userCode = 2;
|
||||
}
|
||||
|
||||
// WaitJWTTokenResponse contains the JWT token after authentication
|
||||
message WaitJWTTokenResponse {
|
||||
// JWT token (access token or ID token)
|
||||
string token = 1;
|
||||
// token type (e.g., "Bearer")
|
||||
string tokenType = 2;
|
||||
// expiration time in seconds
|
||||
int64 expiresIn = 3;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,12 @@ type DaemonServiceClient interface {
|
||||
// Logout disconnects from the network and deletes the peer from the management server
|
||||
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
|
||||
GetFeatures(ctx context.Context, in *GetFeaturesRequest, opts ...grpc.CallOption) (*GetFeaturesResponse, error)
|
||||
// GetPeerSSHHostKey retrieves SSH host key for a specific peer
|
||||
GetPeerSSHHostKey(ctx context.Context, in *GetPeerSSHHostKeyRequest, opts ...grpc.CallOption) (*GetPeerSSHHostKeyResponse, error)
|
||||
// RequestJWTAuth initiates JWT authentication flow for SSH
|
||||
RequestJWTAuth(ctx context.Context, in *RequestJWTAuthRequest, opts ...grpc.CallOption) (*RequestJWTAuthResponse, error)
|
||||
// WaitJWTToken waits for JWT authentication completion
|
||||
WaitJWTToken(ctx context.Context, in *WaitJWTTokenRequest, opts ...grpc.CallOption) (*WaitJWTTokenResponse, error)
|
||||
}
|
||||
|
||||
type daemonServiceClient struct {
|
||||
@@ -349,6 +355,33 @@ func (c *daemonServiceClient) GetFeatures(ctx context.Context, in *GetFeaturesRe
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) GetPeerSSHHostKey(ctx context.Context, in *GetPeerSSHHostKeyRequest, opts ...grpc.CallOption) (*GetPeerSSHHostKeyResponse, error) {
|
||||
out := new(GetPeerSSHHostKeyResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/GetPeerSSHHostKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) RequestJWTAuth(ctx context.Context, in *RequestJWTAuthRequest, opts ...grpc.CallOption) (*RequestJWTAuthResponse, error) {
|
||||
out := new(RequestJWTAuthResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/RequestJWTAuth", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) WaitJWTToken(ctx context.Context, in *WaitJWTTokenRequest, opts ...grpc.CallOption) (*WaitJWTTokenResponse, error) {
|
||||
out := new(WaitJWTTokenResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/WaitJWTToken", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DaemonServiceServer is the server API for DaemonService service.
|
||||
// All implementations must embed UnimplementedDaemonServiceServer
|
||||
// for forward compatibility
|
||||
@@ -399,6 +432,12 @@ type DaemonServiceServer interface {
|
||||
// Logout disconnects from the network and deletes the peer from the management server
|
||||
Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
|
||||
GetFeatures(context.Context, *GetFeaturesRequest) (*GetFeaturesResponse, error)
|
||||
// GetPeerSSHHostKey retrieves SSH host key for a specific peer
|
||||
GetPeerSSHHostKey(context.Context, *GetPeerSSHHostKeyRequest) (*GetPeerSSHHostKeyResponse, error)
|
||||
// RequestJWTAuth initiates JWT authentication flow for SSH
|
||||
RequestJWTAuth(context.Context, *RequestJWTAuthRequest) (*RequestJWTAuthResponse, error)
|
||||
// WaitJWTToken waits for JWT authentication completion
|
||||
WaitJWTToken(context.Context, *WaitJWTTokenRequest) (*WaitJWTTokenResponse, error)
|
||||
mustEmbedUnimplementedDaemonServiceServer()
|
||||
}
|
||||
|
||||
@@ -490,6 +529,15 @@ func (UnimplementedDaemonServiceServer) Logout(context.Context, *LogoutRequest)
|
||||
func (UnimplementedDaemonServiceServer) GetFeatures(context.Context, *GetFeaturesRequest) (*GetFeaturesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFeatures not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) GetPeerSSHHostKey(context.Context, *GetPeerSSHHostKeyRequest) (*GetPeerSSHHostKeyResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPeerSSHHostKey not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) RequestJWTAuth(context.Context, *RequestJWTAuthRequest) (*RequestJWTAuthResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RequestJWTAuth not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) WaitJWTToken(context.Context, *WaitJWTTokenRequest) (*WaitJWTTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method WaitJWTToken not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
||||
|
||||
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -1010,6 +1058,60 @@ func _DaemonService_GetFeatures_Handler(srv interface{}, ctx context.Context, de
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_GetPeerSSHHostKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPeerSSHHostKeyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).GetPeerSSHHostKey(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/GetPeerSSHHostKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).GetPeerSSHHostKey(ctx, req.(*GetPeerSSHHostKeyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_RequestJWTAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RequestJWTAuthRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).RequestJWTAuth(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/RequestJWTAuth",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).RequestJWTAuth(ctx, req.(*RequestJWTAuthRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_WaitJWTToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WaitJWTTokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).WaitJWTToken(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/WaitJWTToken",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).WaitJWTToken(ctx, req.(*WaitJWTTokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// DaemonService_ServiceDesc is the grpc.ServiceDesc for DaemonService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -1125,6 +1227,18 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetFeatures",
|
||||
Handler: _DaemonService_GetFeatures_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPeerSSHHostKey",
|
||||
Handler: _DaemonService_GetPeerSSHHostKey_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RequestJWTAuth",
|
||||
Handler: _DaemonService_RequestJWTAuth_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "WaitJWTToken",
|
||||
Handler: _DaemonService_WaitJWTToken_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user