mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-01 19:09:22 +01:00
167 lines
5.4 KiB
Go
167 lines
5.4 KiB
Go
package http
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
s "github.com/netbirdio/netbird/management/server"
|
|
"github.com/netbirdio/netbird/management/server/http/handler"
|
|
"github.com/netbirdio/netbird/management/server/http/middleware"
|
|
"github.com/rs/cors"
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.org/x/crypto/acme/autocert"
|
|
)
|
|
|
|
type Server struct {
|
|
server *http.Server
|
|
config *s.HttpServerConfig
|
|
certManager *autocert.Manager
|
|
tlsConfig *tls.Config
|
|
accountManager s.AccountManager
|
|
}
|
|
|
|
// NewHttpsServer creates a new HTTPs server (with HTTPS support) and a certManager that is responsible for generating and renewing Let's Encrypt certificate
|
|
// The listening address will be :443 no matter what was specified in s.HttpServerConfig.Address
|
|
func NewHttpsServer(
|
|
config *s.HttpServerConfig,
|
|
certManager *autocert.Manager,
|
|
accountManager s.AccountManager,
|
|
) *Server {
|
|
server := &http.Server{
|
|
Addr: config.Address,
|
|
WriteTimeout: time.Second * 15,
|
|
ReadTimeout: time.Second * 15,
|
|
IdleTimeout: time.Second * 60,
|
|
}
|
|
return &Server{
|
|
server: server,
|
|
config: config,
|
|
certManager: certManager,
|
|
accountManager: accountManager,
|
|
}
|
|
}
|
|
|
|
// NewHttpsServerWithTLSConfig creates a new HTTPs server with a provided tls.Config.
|
|
// Usually used when you already have a certificate
|
|
func NewHttpsServerWithTLSConfig(
|
|
config *s.HttpServerConfig,
|
|
tlsConfig *tls.Config,
|
|
accountManager s.AccountManager,
|
|
) *Server {
|
|
server := &http.Server{
|
|
Addr: config.Address,
|
|
WriteTimeout: time.Second * 15,
|
|
ReadTimeout: time.Second * 15,
|
|
IdleTimeout: time.Second * 60,
|
|
}
|
|
return &Server{
|
|
server: server,
|
|
config: config,
|
|
tlsConfig: tlsConfig,
|
|
accountManager: accountManager,
|
|
}
|
|
}
|
|
|
|
// NewHttpServer creates a new HTTP server (without HTTPS)
|
|
func NewHttpServer(config *s.HttpServerConfig, accountManager s.AccountManager) *Server {
|
|
return NewHttpsServer(config, nil, accountManager)
|
|
}
|
|
|
|
// Stop stops the http server
|
|
func (s *Server) Stop(ctx context.Context) error {
|
|
err := s.server.Shutdown(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Start defines http handlers and starts the http server. Blocks until server is shutdown.
|
|
func (s *Server) Start() error {
|
|
jwtMiddleware, err := middleware.NewJwtMiddleware(
|
|
s.config.AuthIssuer,
|
|
s.config.AuthAudience,
|
|
s.config.AuthKeysLocation,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
corsMiddleware := cors.AllowAll()
|
|
|
|
acMiddleware := middleware.NewAccessControll(
|
|
s.config.AuthAudience,
|
|
s.accountManager.IsUserAdmin)
|
|
|
|
r := mux.NewRouter()
|
|
r.Use(jwtMiddleware.Handler, corsMiddleware.Handler, acMiddleware.Handler)
|
|
|
|
groupsHandler := handler.NewGroups(s.accountManager, s.config.AuthAudience)
|
|
rulesHandler := handler.NewRules(s.accountManager, s.config.AuthAudience)
|
|
peersHandler := handler.NewPeers(s.accountManager, s.config.AuthAudience)
|
|
keysHandler := handler.NewSetupKeysHandler(s.accountManager, s.config.AuthAudience)
|
|
r.HandleFunc("/api/peers", peersHandler.GetPeers).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/api/peers/{id}", peersHandler.HandlePeer).
|
|
Methods("GET", "PUT", "DELETE", "OPTIONS")
|
|
|
|
userHandler := handler.NewUserHandler(s.accountManager, s.config.AuthAudience)
|
|
r.HandleFunc("/api/users", userHandler.GetUsers).Methods("GET", "OPTIONS")
|
|
|
|
r.HandleFunc("/api/setup-keys", keysHandler.GetKeys).Methods("GET", "POST", "OPTIONS")
|
|
r.HandleFunc("/api/setup-keys/{id}", keysHandler.HandleKey).Methods("GET", "PUT", "OPTIONS")
|
|
|
|
r.HandleFunc("/api/setup-keys", keysHandler.GetKeys).Methods("POST", "OPTIONS")
|
|
r.HandleFunc("/api/setup-keys/{id}", keysHandler.HandleKey).
|
|
Methods("GET", "PUT", "DELETE", "OPTIONS")
|
|
|
|
r.HandleFunc("/api/rules", rulesHandler.GetAllRulesHandler).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/api/rules", rulesHandler.CreateOrUpdateRuleHandler).
|
|
Methods("POST", "PUT", "OPTIONS")
|
|
r.HandleFunc("/api/rules/{id}", rulesHandler.GetRuleHandler).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/api/rules/{id}", rulesHandler.DeleteRuleHandler).Methods("DELETE", "OPTIONS")
|
|
|
|
r.HandleFunc("/api/groups", groupsHandler.GetAllGroupsHandler).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/api/groups", groupsHandler.CreateOrUpdateGroupHandler).
|
|
Methods("POST", "PUT", "OPTIONS")
|
|
r.HandleFunc("/api/groups/{id}", groupsHandler.GetGroupHandler).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/api/groups/{id}", groupsHandler.DeleteGroupHandler).Methods("DELETE", "OPTIONS")
|
|
http.Handle("/", r)
|
|
|
|
if s.certManager != nil {
|
|
// if HTTPS is enabled we reuse the listener from the cert manager
|
|
listener := s.certManager.Listener()
|
|
log.Infof(
|
|
"HTTPs server listening on %s with Let's Encrypt autocert configured",
|
|
listener.Addr(),
|
|
)
|
|
if err = http.Serve(listener, s.certManager.HTTPHandler(r)); err != nil {
|
|
log.Errorf("failed to serve https server: %v", err)
|
|
return err
|
|
}
|
|
} else if s.tlsConfig != nil {
|
|
listener, err := tls.Listen("tcp", s.config.Address, s.tlsConfig)
|
|
if err != nil {
|
|
log.Errorf("failed to serve https server: %v", err)
|
|
return err
|
|
}
|
|
log.Infof("HTTPs server listening on %s", listener.Addr())
|
|
|
|
if err = http.Serve(listener, r); err != nil {
|
|
log.Errorf("failed to serve https server: %v", err)
|
|
return err
|
|
}
|
|
|
|
} else {
|
|
log.Infof("HTTP server listening on %s", s.server.Addr)
|
|
if err = s.server.ListenAndServe(); err != nil {
|
|
log.Errorf("failed to serve http server: %v", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|