Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Customization Options to DERP Map entry of integrated DERP server #1565

Merged
merged 17 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ derp:
# For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/
stun_listen_addr: "0.0.0.0:3478"

# For better connection stability (especially when using an Exit-Node and DNS is not working),
# it is possible to optionall add the public IPv4 and IPv6 address to the Derp-Map using:
IPv4: 1.2.3.4
IPv6: 2001:db8::1
alexhalbi marked this conversation as resolved.
Show resolved Hide resolved

# This flag can be used, so the DERP map entry for the embedded DERP server is not written automatically,
# it enables the creation of your very own DERP map entry using a locally available file with the parameter DERP.paths
# If you enable the DERP server and set this to true, it is required to add the DERP server to the DERP map using DERP.paths
manual_derp_map: false
alexhalbi marked this conversation as resolved.
Show resolved Hide resolved

# List of externally available DERP maps encoded in JSON
urls:
- https://controlplane.tailscale.com/derpmap/default
Expand Down
6 changes: 4 additions & 2 deletions hscontrol/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
case <-ticker.C:
log.Info().Msg("Fetching DERPMap updates")
h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled {
if h.cfg.DERP.ServerEnabled && !h.cfg.DERP.ManualDerpMap {
region, _ := h.DERPServer.GenerateRegion()
h.DERPMap.Regions[region.RegionID] = &region
}
Expand Down Expand Up @@ -499,7 +499,9 @@ func (h *Headscale) Serve() error {
return err
}

h.DERPMap.Regions[region.RegionID] = &region
if !h.cfg.DERP.ManualDerpMap {
h.DERPMap.Regions[region.RegionID] = &region
}

go h.DERPServer.ServeSTUN()
}
Expand Down
4 changes: 4 additions & 0 deletions hscontrol/derp/server/derp_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) {
RegionID: d.cfg.ServerRegionID,
HostName: host,
DERPPort: port,
IPv4: d.cfg.IPv4,
IPv6: d.cfg.IPv6,
},
},
}
Expand All @@ -98,6 +100,7 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) {
localDERPregion.Nodes[0].STUNPort = portSTUN

log.Info().Caller().Msgf("DERP region: %+v", localDERPregion)
log.Info().Caller().Msgf("DERP Nodes[0]: %+v", localDERPregion.Nodes[0])

return localDERPregion, nil
}
Expand Down Expand Up @@ -207,6 +210,7 @@ func DERPProbeHandler(
// The initial implementation is here https://github.com/tailscale/tailscale/pull/1406
// They have a cache, but not clear if that is really necessary at Headscale, uh, scale.
// An example implementation is found here https://derp.tailscale.com/bootstrap-dns
// Coordination server is included automatically, since local DERP is using the same DNS Name in d.serverURL
func DERPBootstrapDNSHandler(
derpMap *tailcfg.DERPMap,
) func(http.ResponseWriter, *http.Request) {
Expand Down
15 changes: 15 additions & 0 deletions hscontrol/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type OIDCConfig struct {

type DERPConfig struct {
ServerEnabled bool
ManualDerpMap bool
ServerRegionID int
ServerRegionCode string
ServerRegionName string
Expand All @@ -117,6 +118,8 @@ type DERPConfig struct {
Paths []string
AutoUpdate bool
UpdateFrequency time.Duration
IPv4 string
IPv6 string
}

type LogTailConfig struct {
Expand Down Expand Up @@ -169,6 +172,7 @@ func LoadConfig(path string, isFile bool) error {

viper.SetDefault("derp.server.enabled", false)
viper.SetDefault("derp.server.stun.enabled", true)
viper.SetDefault("derp.server.manual_derp_map", false)

viper.SetDefault("unix_socket", "/var/run/headscale/headscale.sock")
viper.SetDefault("unix_socket_permission", "0o770")
Expand Down Expand Up @@ -286,6 +290,9 @@ func GetDERPConfig() DERPConfig {
serverRegionCode := viper.GetString("derp.server.region_code")
serverRegionName := viper.GetString("derp.server.region_name")
stunAddr := viper.GetString("derp.server.stun_listen_addr")
IPv4 := viper.GetString("derp.server.IPv4")
IPv6 := viper.GetString("derp.server.IPv6")
manual_derp_map := viper.GetBool("derp.server.manual_derp_map")

if serverEnabled && stunAddr == "" {
log.Fatal().
Expand All @@ -309,6 +316,11 @@ func GetDERPConfig() DERPConfig {

paths := viper.GetStringSlice("derp.paths")

if serverEnabled && manual_derp_map && len(paths) == 0 {
log.Fatal().
Msg("Enabling derp.server.manual_derp_map requires to configure the derp server in derp.paths")
}

autoUpdate := viper.GetBool("derp.auto_update_enabled")
updateFrequency := viper.GetDuration("derp.update_frequency")

Expand All @@ -322,6 +334,9 @@ func GetDERPConfig() DERPConfig {
Paths: paths,
AutoUpdate: autoUpdate,
UpdateFrequency: updateFrequency,
IPv4: IPv4,
IPv6: IPv6,
ManualDerpMap: manual_derp_map,
}
}

Expand Down