From b8aad5451daa24c8eeac9ab52c92b42542078675 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 15 Mar 2022 13:22:25 +0100 Subject: [PATCH] Make STUN run by default when embedded DERP is enabled This commit also allows to set an external STUN server, while running the embedded DERP server (without embedded STUN) --- app.go | 5 +++++ cmd/headscale/cli/utils.go | 3 +++ config-example.yaml | 7 +++++-- derp_server.go | 18 ++++++++---------- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app.go b/app.go index f1426bb..177c3ee 100644 --- a/app.go +++ b/app.go @@ -62,6 +62,7 @@ const ( errUnsupportedLetsEncryptChallengeType = Error( "unknown value for Lets Encrypt challenge type", ) + errSTUNAddressNotSet = Error("STUN address not set") DisabledClientAuth = "disabled" RelaxedClientAuth = "relaxed" @@ -502,6 +503,10 @@ func (h *Headscale) Serve() error { h.DERPMap = GetDERPMap(h.cfg.DERP) if h.cfg.DERP.ServerEnabled { + if h.cfg.DERP.STUNAddr == "" { // When embedded DERP is enabled we always need a STUN server address, embedded or external + return errSTUNAddressNotSet + } + h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region if h.cfg.DERP.STUNEnabled { go h.ServeSTUN() diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index dc7a4e9..eb26a83 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -55,6 +55,9 @@ func LoadConfig(path string) error { viper.SetDefault("dns_config", nil) + viper.SetDefault("derp.server.enabled", false) + viper.SetDefault("derp.server.stun.enabled", true) + viper.SetDefault("unix_socket", "/var/run/headscale.sock") viper.SetDefault("unix_socket_permission", "0o770") diff --git a/config-example.yaml b/config-example.yaml index 2075e69..31d7a8a 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -69,10 +69,13 @@ derp: region_code: "headscale" region_name: "Headscale Embedded DERP" - # If enabled, also listens in UDP at the configured address for STUN connections to help on NAT traversal + # Enabled by default when embedded DERP is enabled. Listens in UDP at the configured address for STUN connections + # to help on NAT traversal. + # If DERP is enabled, but STUN is disabled you still need to input an external STUN server in the listen_addr field. + # # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ stun: - enabled: false + enabled: true listen_addr: "0.0.0.0:3478" # List of externally available DERP maps encoded in JSON diff --git a/derp_server.go b/derp_server.go index 11e3eb1..6580419 100644 --- a/derp_server.go +++ b/derp_server.go @@ -77,17 +77,15 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) { }, } - if h.cfg.DERP.STUNEnabled { - _, portStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) - if err != nil { - return tailcfg.DERPRegion{}, err - } - port, err := strconv.Atoi(portStr) - if err != nil { - return tailcfg.DERPRegion{}, err - } - localDERPregion.Nodes[0].STUNPort = port + _, portSTUNStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) + if err != nil { + return tailcfg.DERPRegion{}, err } + portSTUN, err := strconv.Atoi(portSTUNStr) + if err != nil { + return tailcfg.DERPRegion{}, err + } + localDERPregion.Nodes[0].STUNPort = portSTUN return localDERPregion, nil }