Skip to content

Commit

Permalink
remove username from magicdns names
Browse files Browse the repository at this point in the history
This commit removes the username from magicDNS names.
This is in preparation of fixing tags, which currently is
not correctly disassociated from users when added. With the
current behaviour, fixing tagged devices would break the
MagicDNS behaviour.

This brings headscale to use the same behaviour of tailscale.

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
  • Loading branch information
kradalby committed Jun 20, 2024
1 parent 93fb4f6 commit 5ef10ca
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 31 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ after improving the test harness as part of adopting [#1460](https://github.com/
- Prefixes are now defined per v4 and v6 range. [#1756](https://github.com/juanfont/headscale/pull/1756)
- `ip_prefixes` option is now `prefixes.v4` and `prefixes.v6`
- `prefixes.allocation` can be set to assign IPs at `sequential` or `random`. [#1869](https://github.com/juanfont/headscale/pull/1869)
- MagicDNS domains no longer contain usernames []()
- This is in preperation to fix Headscales implementation of tags which currently does not correctly remove the link between a tagged device and a user. As tagged devices will not have a user, this will require a change to the DNS generation, removing the username, see [#1369](https://github.com/juanfont/headscale/issues/1369) for more information.
- `use_username_in_magic_dns` can be used to turn this behaviour on again, but note that this option _will be removed_ when tags are fixed.
- This option brings Headscales behaviour in line with Tailscale.

### Changes

Expand Down
9 changes: 9 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,15 @@ dns_config:
# Only works if there is at least a nameserver defined.
magic_dns: true

# DEPRECATED
# Use the username as part of the DNS name for nodes, with this option enabled:
# node1.username.example.com
# while when this is disabled:
# node1.example.com
# This is a legacy option as Headscale has have this wrongly implemented
# while in upstream Tailscale, the username is not included.
use_username_in_magic_dns: false

# Defines the base domain to create the hostnames for MagicDNS.
# `base_domain` must be a FQDNs, without the trailing dot.
# The FQDN of the hosts will be
Expand Down
54 changes: 29 additions & 25 deletions hscontrol/mapper/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,37 +122,41 @@ func generateUserProfiles(
}

func generateDNSConfig(
base *tailcfg.DNSConfig,
cfg *types.Config,
baseDomain string,
node *types.Node,
peers types.Nodes,
) *tailcfg.DNSConfig {
dnsConfig := base.Clone()
if cfg.DNSConfig == nil {
return nil
}

// if MagicDNS is enabled
if base != nil && base.Proxied {
// Only inject the Search Domain of the current user
// shared nodes should use their full FQDN
dnsConfig.Domains = append(
dnsConfig.Domains,
fmt.Sprintf(
"%s.%s",
node.User.Name,
baseDomain,
),
)
dnsConfig := cfg.DNSConfig.Clone()

userSet := mapset.NewSet[types.User]()
userSet.Add(node.User)
for _, p := range peers {
userSet.Add(p.User)
}
for _, user := range userSet.ToSlice() {
dnsRoute := fmt.Sprintf("%v.%v", user.Name, baseDomain)
dnsConfig.Routes[dnsRoute] = nil
// if MagicDNS is enabled
if dnsConfig.Proxied {
if cfg.DNSUserNameInMagicDNS {
// Only inject the Search Domain of the current user
// shared nodes should use their full FQDN
dnsConfig.Domains = append(
dnsConfig.Domains,
fmt.Sprintf(
"%s.%s",
node.User.Name,
baseDomain,
),
)

userSet := mapset.NewSet[types.User]()
userSet.Add(node.User)
for _, p := range peers {
userSet.Add(p.User)
}
for _, user := range userSet.ToSlice() {
dnsRoute := fmt.Sprintf("%v.%v", user.Name, baseDomain)
dnsConfig.Routes[dnsRoute] = nil
}
}
} else {
dnsConfig = base
}

addNextDNSMetadata(dnsConfig.Resolvers, node)
Expand Down Expand Up @@ -568,7 +572,7 @@ func appendPeerChanges(
profiles := generateUserProfiles(node, changed, cfg.BaseDomain)

dnsConfig := generateDNSConfig(
cfg.DNSConfig,
cfg,
cfg.BaseDomain,
node,
peers,
Expand Down
11 changes: 7 additions & 4 deletions hscontrol/mapper/mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ func TestDNSConfigMapResponse(t *testing.T) {
}

got := generateDNSConfig(
&dnsConfigOrig,
&types.Config{
DNSConfig: &dnsConfigOrig,
DNSUserNameInMagicDNS: true,
},
baseDomain,
nodeInShared1,
peersOfNodeInShared1,
Expand Down Expand Up @@ -187,9 +190,9 @@ func Test_fullMapResponse(t *testing.T) {
UserID: 0,
User: types.User{Name: "mini"},
ForcedTags: []string{},
AuthKey: &types.PreAuthKey{},
LastSeen: &lastSeen,
Expiry: &expire,
AuthKey: &types.PreAuthKey{},
LastSeen: &lastSeen,
Expiry: &expire,
Hostinfo: &tailcfg.Hostinfo{},
Routes: []types.Route{
{
Expand Down
14 changes: 12 additions & 2 deletions hscontrol/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ type Config struct {
ACMEURL string
ACMEEmail string

DNSConfig *tailcfg.DNSConfig
DNSConfig *tailcfg.DNSConfig
DNSUserNameInMagicDNS bool

UnixSocket string
UnixSocketPermission fs.FileMode
Expand Down Expand Up @@ -203,6 +204,7 @@ func LoadConfig(path string, isFile bool) error {

viper.SetDefault("dns_config", nil)
viper.SetDefault("dns_config.override_local_dns", true)
viper.SetDefault("dns_config.use_username_in_magic_dns", false)

viper.SetDefault("derp.server.enabled", false)
viper.SetDefault("derp.server.stun.enabled", true)
Expand Down Expand Up @@ -561,6 +563,13 @@ func GetDNSConfig() (*tailcfg.DNSConfig, string) {
baseDomain = "headscale.net" // does not really matter when MagicDNS is not enabled
}

if !viper.GetBool("dns_config.use_username_in_magic_dns") {
dnsConfig.Domains = []string{baseDomain}
} else {
log.Warn().Msg("DNS: Usernames in DNS has been deprecated, this option will be remove in future versions")
log.Warn().Msg("DNS: see 0.23.0 changelog for more information.")
}

if domains := viper.GetStringSlice("dns_config.domains"); len(domains) > 0 {
dnsConfig.Domains = append(dnsConfig.Domains, domains...)
}
Expand Down Expand Up @@ -708,7 +717,8 @@ func GetHeadscaleConfig() (*Config, error) {

TLS: GetTLSConfig(),

DNSConfig: dnsConfig,
DNSConfig: dnsConfig,
DNSUserNameInMagicDNS: viper.GetBool("dns_config.use_username_in_magic_dns"),

ACMEEmail: viper.GetString("acme_email"),
ACMEURL: viper.GetString("acme_url"),
Expand Down

0 comments on commit 5ef10ca

Please sign in to comment.