From eb06054a7b1e9d429b69d1c205ea81058468f60d Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Sun, 6 Mar 2022 17:25:21 +0100 Subject: [PATCH] Make DERP Region configurable --- app.go | 17 ++++++++++------- cmd/headscale/cli/utils.go | 22 ++++++++++++++-------- config-example.yaml | 9 +++++++++ derp_server.go | 14 ++++++++------ 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/app.go b/app.go index 82e87cf0..f1426bbb 100644 --- a/app.go +++ b/app.go @@ -120,13 +120,16 @@ type OIDCConfig struct { } type DERPConfig struct { - ServerEnabled bool - STUNEnabled bool - STUNAddr string - URLs []url.URL - Paths []string - AutoUpdate bool - UpdateFrequency time.Duration + ServerEnabled bool + ServerRegionID int + ServerRegionCode string + ServerRegionName string + STUNEnabled bool + STUNAddr string + URLs []url.URL + Paths []string + AutoUpdate bool + UpdateFrequency time.Duration } type CLIConfig struct { diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index e6dce3a1..dc7a4e9f 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -117,7 +117,10 @@ func LoadConfig(path string) error { } func GetDERPConfig() headscale.DERPConfig { - enabled := viper.GetBool("derp.server.enabled") + serverEnabled := viper.GetBool("derp.server.enabled") + serverRegionID := viper.GetInt("derp.server.region_id") + serverRegionCode := viper.GetString("derp.server.region_code") + serverRegionName := viper.GetString("derp.server.region_name") stunEnabled := viper.GetBool("derp.server.stun.enabled") stunAddr := viper.GetString("derp.server.stun.listen_addr") @@ -142,13 +145,16 @@ func GetDERPConfig() headscale.DERPConfig { updateFrequency := viper.GetDuration("derp.update_frequency") return headscale.DERPConfig{ - ServerEnabled: enabled, - STUNEnabled: stunEnabled, - STUNAddr: stunAddr, - URLs: urls, - Paths: paths, - AutoUpdate: autoUpdate, - UpdateFrequency: updateFrequency, + ServerEnabled: serverEnabled, + ServerRegionID: serverRegionID, + ServerRegionCode: serverRegionCode, + ServerRegionName: serverRegionName, + STUNEnabled: stunEnabled, + STUNAddr: stunAddr, + URLs: urls, + Paths: paths, + AutoUpdate: autoUpdate, + UpdateFrequency: updateFrequency, } } diff --git a/config-example.yaml b/config-example.yaml index 57b43fd4..1ab92dca 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -60,6 +60,15 @@ derp: # The Headscale server_url defined above MUST be using https, DERP requires TLS to be in place enabled: false + # Region ID to use for the embedded DERP server. + # The local DERP prevails if the region ID collides with other region ID coming from + # the regular DERP config. + region_id: 999 + + # Region code and name are displayed in the Tailscale UI to identify a DERP region + region_code: "headscale" + region_name: "Headscale Embedded DERP" + # If enabled, also listens in the configured address for STUN connections to help on NAT traversal # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ stun: diff --git a/derp_server.go b/derp_server.go index aeb4877a..8995ca8b 100644 --- a/derp_server.go +++ b/derp_server.go @@ -62,14 +62,14 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) { } localDERPregion := tailcfg.DERPRegion{ - RegionID: 999, - RegionCode: "headscale", - RegionName: "Headscale Embedded DERP", + RegionID: h.cfg.DERP.ServerRegionID, + RegionCode: h.cfg.DERP.ServerRegionCode, + RegionName: h.cfg.DERP.ServerRegionName, Avoid: false, Nodes: []*tailcfg.DERPNode{ { - Name: "999a", - RegionID: 999, + Name: fmt.Sprintf("%d", h.cfg.DERP.ServerRegionID), + RegionID: h.cfg.DERP.ServerRegionID, HostName: host, DERPPort: port, }, @@ -108,6 +108,7 @@ func (h *Headscale) DERPHandler(ctx *gin.Context) { if !ok { log.Error().Caller().Msg("DERP requires Hijacker interface from Gin") ctx.String(http.StatusInternalServerError, "HTTP does not support general TCP support") + return } @@ -115,6 +116,7 @@ func (h *Headscale) DERPHandler(ctx *gin.Context) { if err != nil { log.Error().Caller().Err(err).Msgf("Hijack failed") ctx.String(http.StatusInternalServerError, "HTTP does not support general TCP support") + return } @@ -169,7 +171,7 @@ func (h *Headscale) DERPBootstrapDNSHandler(ctx *gin.Context) { ctx.JSON(http.StatusOK, dnsEntries) } -// ServeSTUN starts a STUN server on the configured addr +// ServeSTUN starts a STUN server on the configured addr. func (h *Headscale) ServeSTUN() { packetConn, err := net.ListenPacket("udp", h.cfg.DERP.STUNAddr) if err != nil {