From dfad6a1756449700e08f4495294890f63e28f5f6 Mon Sep 17 00:00:00 2001 From: Jisse Date: Thu, 12 Dec 2024 16:35:09 +0100 Subject: [PATCH] Headscale: Added an option to set an Access-Control-Allow-Origin response header to enable Cross-Origin Resource Sharing (CORS) --- config-example.yaml | 7 +++++++ hscontrol/app.go | 11 +++++++++++ hscontrol/types/config.go | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/config-example.yaml b/config-example.yaml index 529a80edbf..68f0122b2e 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -40,6 +40,13 @@ grpc_listen_addr: 127.0.0.1:50443 # are doing. grpc_allow_insecure: false +# The Access-Control-Allow-Origin header specifies which origins are allowed to access resources. +# Options: +# - "*" to allow access from any origin (not recommended for sensitive data). +# - "http://example.com" to only allow access from a specific origin. +# - "" to disable Cross-Origin Resource Sharing (CORS). +access_control_allow_origin: "" + # The Noise section includes specific configuration for the # TS2021 Noise protocol noise: diff --git a/hscontrol/app.go b/hscontrol/app.go index 3349392b50..8f182227f6 100644 --- a/hscontrol/app.go +++ b/hscontrol/app.go @@ -454,10 +454,21 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error { return os.Remove(h.cfg.UnixSocket) } +func (h *Headscale) corsHeadersMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", h.cfg.AccessControlAllowOrigins) + next.ServeHTTP(w, r) + }) +} + func (h *Headscale) createRouter(grpcMux *grpcRuntime.ServeMux) *mux.Router { router := mux.NewRouter() router.Use(prometheusMiddleware) + if h.cfg.AccessControlAllowOrigins != "" { + router.Use(h.corsHeadersMiddleware) + } + router.HandleFunc(ts2021UpgradePath, h.NoiseUpgradeHandler).Methods(http.MethodPost, http.MethodGet) router.HandleFunc("/health", h.HealthHandler).Methods(http.MethodGet) diff --git a/hscontrol/types/config.go b/hscontrol/types/config.go index f6c5c48a29..16b9d63a0a 100644 --- a/hscontrol/types/config.go +++ b/hscontrol/types/config.go @@ -63,6 +63,8 @@ type Config struct { Log LogConfig DisableUpdateCheck bool + AccessControlAllowOrigins string + Database DatabaseConfig DERP DERPConfig @@ -303,6 +305,8 @@ func LoadConfig(path string, isFile bool) error { viper.SetDefault("tuning.batch_change_delay", "800ms") viper.SetDefault("tuning.node_mapsession_buffered_chan_size", 30) + viper.SetDefault("access_control_allow_origin", "") + viper.SetDefault("prefixes.allocation", string(IPAllocationStrategySequential)) if err := viper.ReadInConfig(); err != nil { @@ -868,6 +872,8 @@ func LoadServerConfig() (*Config, error) { GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"), DisableUpdateCheck: false, + AccessControlAllowOrigins: viper.GetString("access_control_allow_origin"), + PrefixV4: prefix4, PrefixV6: prefix6, IPAllocation: IPAllocationStrategy(alloc),