Add Customization Options to DERP Map entry of integrated DERP server (#1565)
Co-authored-by: Alexander Halbarth <alexander.halbarth@alite.at> Co-authored-by: Bela Lemle <bela.lemle@alite.at> Co-authored-by: Kristoffer Dalby <kristoffer@dalby.cc>
This commit is contained in:
parent
3b103280ef
commit
7e8bf4bfe5
8 changed files with 61 additions and 27 deletions
|
@ -43,6 +43,7 @@ Fix hang on SIGTERM [#1492](https://github.com/juanfont/headscale/pull/1492) tak
|
||||||
Send logs to stderr by default [#1524](https://github.com/juanfont/headscale/pull/1524)
|
Send logs to stderr by default [#1524](https://github.com/juanfont/headscale/pull/1524)
|
||||||
Fix [TS-2023-006](https://tailscale.com/security-bulletins/#ts-2023-006) security UPnP issue [#1563](https://github.com/juanfont/headscale/pull/1563)
|
Fix [TS-2023-006](https://tailscale.com/security-bulletins/#ts-2023-006) security UPnP issue [#1563](https://github.com/juanfont/headscale/pull/1563)
|
||||||
Turn off gRPC logging [#1640](https://github.com/juanfont/headscale/pull/1640) fixes [#1259](https://github.com/juanfont/headscale/issues/1259)
|
Turn off gRPC logging [#1640](https://github.com/juanfont/headscale/pull/1640) fixes [#1259](https://github.com/juanfont/headscale/issues/1259)
|
||||||
|
Added the possibility to manually create a DERP-map entry which can be customized, instead of automatically creating it. [#1565](https://github.com/juanfont/headscale/pull/1565)
|
||||||
|
|
||||||
## 0.22.3 (2023-05-12)
|
## 0.22.3 (2023-05-12)
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,16 @@ derp:
|
||||||
#
|
#
|
||||||
private_key_path: /var/lib/headscale/derp_server_private.key
|
private_key_path: /var/lib/headscale/derp_server_private.key
|
||||||
|
|
||||||
|
# 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 false, it is required to add the DERP server to the DERP map using DERP.paths
|
||||||
|
automatically_add_embedded_derp_region: true
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# List of externally available DERP maps encoded in JSON
|
# List of externally available DERP maps encoded in JSON
|
||||||
urls:
|
urls:
|
||||||
- https://controlplane.tailscale.com/derpmap/default
|
- https://controlplane.tailscale.com/derpmap/default
|
||||||
|
|
|
@ -268,7 +268,7 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
log.Info().Msg("Fetching DERPMap updates")
|
log.Info().Msg("Fetching DERPMap updates")
|
||||||
h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
|
h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
|
||||||
if h.cfg.DERP.ServerEnabled {
|
if h.cfg.DERP.ServerEnabled && h.cfg.DERP.AutomaticallyAddEmbeddedDerpRegion {
|
||||||
region, _ := h.DERPServer.GenerateRegion()
|
region, _ := h.DERPServer.GenerateRegion()
|
||||||
h.DERPMap.Regions[region.RegionID] = ®ion
|
h.DERPMap.Regions[region.RegionID] = ®ion
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,9 @@ func (h *Headscale) Serve() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
h.DERPMap.Regions[region.RegionID] = ®ion
|
if h.cfg.DERP.AutomaticallyAddEmbeddedDerpRegion {
|
||||||
|
h.DERPMap.Regions[region.RegionID] = ®ion
|
||||||
|
}
|
||||||
|
|
||||||
go h.DERPServer.ServeSTUN()
|
go h.DERPServer.ServeSTUN()
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ func (hsdb *HSDatabase) GetNodePrimaryRoutes(node *types.Node) (types.Routes, er
|
||||||
|
|
||||||
// SaveNodeRoutes takes a node and updates the database with
|
// SaveNodeRoutes takes a node and updates the database with
|
||||||
// the new routes.
|
// the new routes.
|
||||||
// It returns a bool wheter an update should be sent as the
|
// It returns a bool whether an update should be sent as the
|
||||||
// saved route impacts nodes.
|
// saved route impacts nodes.
|
||||||
func (hsdb *HSDatabase) SaveNodeRoutes(node *types.Node) (bool, error) {
|
func (hsdb *HSDatabase) SaveNodeRoutes(node *types.Node) (bool, error) {
|
||||||
hsdb.mu.Lock()
|
hsdb.mu.Lock()
|
||||||
|
|
|
@ -84,6 +84,8 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) {
|
||||||
RegionID: d.cfg.ServerRegionID,
|
RegionID: d.cfg.ServerRegionID,
|
||||||
HostName: host,
|
HostName: host,
|
||||||
DERPPort: port,
|
DERPPort: port,
|
||||||
|
IPv4: d.cfg.IPv4,
|
||||||
|
IPv6: d.cfg.IPv6,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -99,6 +101,7 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) {
|
||||||
localDERPregion.Nodes[0].STUNPort = portSTUN
|
localDERPregion.Nodes[0].STUNPort = portSTUN
|
||||||
|
|
||||||
log.Info().Caller().Msgf("DERP region: %+v", localDERPregion)
|
log.Info().Caller().Msgf("DERP region: %+v", localDERPregion)
|
||||||
|
log.Info().Caller().Msgf("DERP Nodes[0]: %+v", localDERPregion.Nodes[0])
|
||||||
|
|
||||||
return localDERPregion, nil
|
return localDERPregion, nil
|
||||||
}
|
}
|
||||||
|
@ -208,6 +211,7 @@ func DERPProbeHandler(
|
||||||
// The initial implementation is here https://github.com/tailscale/tailscale/pull/1406
|
// 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.
|
// 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
|
// 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(
|
func DERPBootstrapDNSHandler(
|
||||||
derpMap *tailcfg.DERPMap,
|
derpMap *tailcfg.DERPMap,
|
||||||
) func(http.ResponseWriter, *http.Request) {
|
) func(http.ResponseWriter, *http.Request) {
|
||||||
|
|
|
@ -107,16 +107,19 @@ type OIDCConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DERPConfig struct {
|
type DERPConfig struct {
|
||||||
ServerEnabled bool
|
ServerEnabled bool
|
||||||
ServerRegionID int
|
AutomaticallyAddEmbeddedDerpRegion bool
|
||||||
ServerRegionCode string
|
ServerRegionID int
|
||||||
ServerRegionName string
|
ServerRegionCode string
|
||||||
ServerPrivateKeyPath string
|
ServerRegionName string
|
||||||
STUNAddr string
|
ServerPrivateKeyPath string
|
||||||
URLs []url.URL
|
STUNAddr string
|
||||||
Paths []string
|
URLs []url.URL
|
||||||
AutoUpdate bool
|
Paths []string
|
||||||
UpdateFrequency time.Duration
|
AutoUpdate bool
|
||||||
|
UpdateFrequency time.Duration
|
||||||
|
IPv4 string
|
||||||
|
IPv6 string
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogTailConfig struct {
|
type LogTailConfig struct {
|
||||||
|
@ -169,6 +172,7 @@ func LoadConfig(path string, isFile bool) error {
|
||||||
|
|
||||||
viper.SetDefault("derp.server.enabled", false)
|
viper.SetDefault("derp.server.enabled", false)
|
||||||
viper.SetDefault("derp.server.stun.enabled", true)
|
viper.SetDefault("derp.server.stun.enabled", true)
|
||||||
|
viper.SetDefault("derp.server.automatically_add_embedded_derp_region", true)
|
||||||
|
|
||||||
viper.SetDefault("unix_socket", "/var/run/headscale/headscale.sock")
|
viper.SetDefault("unix_socket", "/var/run/headscale/headscale.sock")
|
||||||
viper.SetDefault("unix_socket_permission", "0o770")
|
viper.SetDefault("unix_socket_permission", "0o770")
|
||||||
|
@ -286,8 +290,14 @@ func GetDERPConfig() DERPConfig {
|
||||||
serverRegionCode := viper.GetString("derp.server.region_code")
|
serverRegionCode := viper.GetString("derp.server.region_code")
|
||||||
serverRegionName := viper.GetString("derp.server.region_name")
|
serverRegionName := viper.GetString("derp.server.region_name")
|
||||||
stunAddr := viper.GetString("derp.server.stun_listen_addr")
|
stunAddr := viper.GetString("derp.server.stun_listen_addr")
|
||||||
privateKeyPath := util.AbsolutePathFromConfigPath(viper.GetString("derp.server.private_key_path"))
|
privateKeyPath := util.AbsolutePathFromConfigPath(
|
||||||
|
viper.GetString("derp.server.private_key_path"),
|
||||||
|
)
|
||||||
|
ipv4 := viper.GetString("derp.server.ipv4")
|
||||||
|
ipv6 := viper.GetString("derp.server.ipv6")
|
||||||
|
automaticallyAddEmbeddedDerpRegion := viper.GetBool(
|
||||||
|
"derp.server.automatically_add_embedded_derp_region",
|
||||||
|
)
|
||||||
if serverEnabled && stunAddr == "" {
|
if serverEnabled && stunAddr == "" {
|
||||||
log.Fatal().
|
log.Fatal().
|
||||||
Msg("derp.server.stun_listen_addr must be set if derp.server.enabled is true")
|
Msg("derp.server.stun_listen_addr must be set if derp.server.enabled is true")
|
||||||
|
@ -310,20 +320,28 @@ func GetDERPConfig() DERPConfig {
|
||||||
|
|
||||||
paths := viper.GetStringSlice("derp.paths")
|
paths := viper.GetStringSlice("derp.paths")
|
||||||
|
|
||||||
|
if serverEnabled && !automaticallyAddEmbeddedDerpRegion && len(paths) == 0 {
|
||||||
|
log.Fatal().
|
||||||
|
Msg("Disabling derp.server.automatically_add_embedded_derp_region requires to configure the derp server in derp.paths")
|
||||||
|
}
|
||||||
|
|
||||||
autoUpdate := viper.GetBool("derp.auto_update_enabled")
|
autoUpdate := viper.GetBool("derp.auto_update_enabled")
|
||||||
updateFrequency := viper.GetDuration("derp.update_frequency")
|
updateFrequency := viper.GetDuration("derp.update_frequency")
|
||||||
|
|
||||||
return DERPConfig{
|
return DERPConfig{
|
||||||
ServerEnabled: serverEnabled,
|
ServerEnabled: serverEnabled,
|
||||||
ServerRegionID: serverRegionID,
|
ServerRegionID: serverRegionID,
|
||||||
ServerRegionCode: serverRegionCode,
|
ServerRegionCode: serverRegionCode,
|
||||||
ServerRegionName: serverRegionName,
|
ServerRegionName: serverRegionName,
|
||||||
ServerPrivateKeyPath: privateKeyPath,
|
ServerPrivateKeyPath: privateKeyPath,
|
||||||
STUNAddr: stunAddr,
|
STUNAddr: stunAddr,
|
||||||
URLs: urls,
|
URLs: urls,
|
||||||
Paths: paths,
|
Paths: paths,
|
||||||
AutoUpdate: autoUpdate,
|
AutoUpdate: autoUpdate,
|
||||||
UpdateFrequency: updateFrequency,
|
UpdateFrequency: updateFrequency,
|
||||||
|
IPv4: ipv4,
|
||||||
|
IPv6: ipv6,
|
||||||
|
AutomaticallyAddEmbeddedDerpRegion: automaticallyAddEmbeddedDerpRegion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ func (node *Node) GetFQDN(dnsConfig *tailcfg.DNSConfig, baseDomain string) (stri
|
||||||
// inform peers about smaller changes to the node.
|
// inform peers about smaller changes to the node.
|
||||||
// When a field is added to this function, remember to also add it to:
|
// When a field is added to this function, remember to also add it to:
|
||||||
// - node.ApplyPeerChange
|
// - node.ApplyPeerChange
|
||||||
// - logTracePeerChange in poll.go
|
// - logTracePeerChange in poll.go.
|
||||||
func (node *Node) PeerChangeFromMapRequest(req tailcfg.MapRequest) tailcfg.PeerChange {
|
func (node *Node) PeerChangeFromMapRequest(req tailcfg.MapRequest) tailcfg.PeerChange {
|
||||||
ret := tailcfg.PeerChange{
|
ret := tailcfg.PeerChange{
|
||||||
NodeID: tailcfg.NodeID(node.ID),
|
NodeID: tailcfg.NodeID(node.ID),
|
||||||
|
|
|
@ -320,7 +320,6 @@ func TestTaildrop(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to install curl on %s, err: %s", client.Hostname(), err)
|
t.Fatalf("failed to install curl on %s, err: %s", client.Hostname(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
curlCommand := []string{"curl", "--unix-socket", "/var/run/tailscale/tailscaled.sock", "http://local-tailscaled.sock/localapi/v0/file-targets"}
|
curlCommand := []string{"curl", "--unix-socket", "/var/run/tailscale/tailscaled.sock", "http://local-tailscaled.sock/localapi/v0/file-targets"}
|
||||||
err = retry(10, 1*time.Second, func() error {
|
err = retry(10, 1*time.Second, func() error {
|
||||||
|
|
Loading…
Reference in a new issue