mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-03 23:56:38 +00:00
[management,proxy,client] Add L4 capabilities (TLS/TCP/UDP) (#5530)
This commit is contained in:
@@ -2,6 +2,7 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
pb "github.com/golang/protobuf/proto" // nolint
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -39,23 +40,38 @@ func (s *Server) CreateExpose(ctx context.Context, req *proto.EncryptedMessage)
|
||||
return nil, status.Errorf(codes.Internal, "reverse proxy manager not available")
|
||||
}
|
||||
|
||||
if exposeReq.Port > 65535 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "port out of range: %d", exposeReq.Port)
|
||||
}
|
||||
if exposeReq.ListenPort > 65535 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "listen_port out of range: %d", exposeReq.ListenPort)
|
||||
}
|
||||
|
||||
mode, err := exposeProtocolToString(exposeReq.Protocol)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
created, err := reverseProxyMgr.CreateServiceFromPeer(ctx, accountID, peer.ID, &rpservice.ExposeServiceRequest{
|
||||
NamePrefix: exposeReq.NamePrefix,
|
||||
Port: int(exposeReq.Port),
|
||||
Protocol: exposeProtocolToString(exposeReq.Protocol),
|
||||
Domain: exposeReq.Domain,
|
||||
Pin: exposeReq.Pin,
|
||||
Password: exposeReq.Password,
|
||||
UserGroups: exposeReq.UserGroups,
|
||||
NamePrefix: exposeReq.NamePrefix,
|
||||
Port: uint16(exposeReq.Port), //nolint:gosec // validated above
|
||||
Mode: mode,
|
||||
TargetProtocol: exposeTargetProtocol(exposeReq.Protocol),
|
||||
Domain: exposeReq.Domain,
|
||||
Pin: exposeReq.Pin,
|
||||
Password: exposeReq.Password,
|
||||
UserGroups: exposeReq.UserGroups,
|
||||
ListenPort: uint16(exposeReq.ListenPort), //nolint:gosec // validated above
|
||||
})
|
||||
if err != nil {
|
||||
return nil, mapExposeError(ctx, err)
|
||||
}
|
||||
|
||||
return s.encryptResponse(peerKey, &proto.ExposeServiceResponse{
|
||||
ServiceName: created.ServiceName,
|
||||
ServiceUrl: created.ServiceURL,
|
||||
Domain: created.Domain,
|
||||
ServiceName: created.ServiceName,
|
||||
ServiceUrl: created.ServiceURL,
|
||||
Domain: created.Domain,
|
||||
PortAutoAssigned: created.PortAutoAssigned,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -77,7 +93,12 @@ func (s *Server) RenewExpose(ctx context.Context, req *proto.EncryptedMessage) (
|
||||
return nil, status.Errorf(codes.Internal, "reverse proxy manager not available")
|
||||
}
|
||||
|
||||
if err := reverseProxyMgr.RenewServiceFromPeer(ctx, accountID, peer.ID, renewReq.Domain); err != nil {
|
||||
serviceID, err := s.resolveServiceID(ctx, renewReq.Domain)
|
||||
if err != nil {
|
||||
return nil, mapExposeError(ctx, err)
|
||||
}
|
||||
|
||||
if err := reverseProxyMgr.RenewServiceFromPeer(ctx, accountID, peer.ID, serviceID); err != nil {
|
||||
return nil, mapExposeError(ctx, err)
|
||||
}
|
||||
|
||||
@@ -102,7 +123,12 @@ func (s *Server) StopExpose(ctx context.Context, req *proto.EncryptedMessage) (*
|
||||
return nil, status.Errorf(codes.Internal, "reverse proxy manager not available")
|
||||
}
|
||||
|
||||
if err := reverseProxyMgr.StopServiceFromPeer(ctx, accountID, peer.ID, stopReq.Domain); err != nil {
|
||||
serviceID, err := s.resolveServiceID(ctx, stopReq.Domain)
|
||||
if err != nil {
|
||||
return nil, mapExposeError(ctx, err)
|
||||
}
|
||||
|
||||
if err := reverseProxyMgr.StopServiceFromPeer(ctx, accountID, peer.ID, serviceID); err != nil {
|
||||
return nil, mapExposeError(ctx, err)
|
||||
}
|
||||
|
||||
@@ -180,13 +206,46 @@ func (s *Server) SetReverseProxyManager(mgr rpservice.Manager) {
|
||||
s.reverseProxyManager = mgr
|
||||
}
|
||||
|
||||
func exposeProtocolToString(p proto.ExposeProtocol) string {
|
||||
// resolveServiceID looks up the service by its globally unique domain.
|
||||
func (s *Server) resolveServiceID(ctx context.Context, domain string) (string, error) {
|
||||
if domain == "" {
|
||||
return "", status.Errorf(codes.InvalidArgument, "domain is required")
|
||||
}
|
||||
|
||||
svc, err := s.accountManager.GetStore().GetServiceByDomain(ctx, domain)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return svc.ID, nil
|
||||
}
|
||||
|
||||
func exposeProtocolToString(p proto.ExposeProtocol) (string, error) {
|
||||
switch p {
|
||||
case proto.ExposeProtocol_EXPOSE_HTTP:
|
||||
return "http"
|
||||
case proto.ExposeProtocol_EXPOSE_HTTPS:
|
||||
return "https"
|
||||
case proto.ExposeProtocol_EXPOSE_HTTP, proto.ExposeProtocol_EXPOSE_HTTPS:
|
||||
return "http", nil
|
||||
case proto.ExposeProtocol_EXPOSE_TCP:
|
||||
return "tcp", nil
|
||||
case proto.ExposeProtocol_EXPOSE_UDP:
|
||||
return "udp", nil
|
||||
case proto.ExposeProtocol_EXPOSE_TLS:
|
||||
return "tls", nil
|
||||
default:
|
||||
return "http"
|
||||
return "", fmt.Errorf("unsupported expose protocol: %v", p)
|
||||
}
|
||||
}
|
||||
|
||||
// exposeTargetProtocol returns the target protocol for the given expose protocol.
|
||||
// For HTTP mode, this is http or https (the scheme used to connect to the backend).
|
||||
// For L4 modes, this is tcp or udp (the transport used to connect to the backend).
|
||||
func exposeTargetProtocol(p proto.ExposeProtocol) string {
|
||||
switch p {
|
||||
case proto.ExposeProtocol_EXPOSE_HTTPS:
|
||||
return rpservice.TargetProtoHTTPS
|
||||
case proto.ExposeProtocol_EXPOSE_TCP, proto.ExposeProtocol_EXPOSE_TLS:
|
||||
return rpservice.TargetProtoTCP
|
||||
case proto.ExposeProtocol_EXPOSE_UDP:
|
||||
return rpservice.TargetProtoUDP
|
||||
default:
|
||||
return rpservice.TargetProtoHTTP
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user