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

feat: remove user if machine is tagged #1405

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions api_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (h *Headscale) generateMapResponse(
Str("func", "generateMapResponse").
Str("machine", mapRequest.Hostinfo.Hostname).
Msg("Creating Map response")
node, err := h.toNode(*machine, h.cfg.BaseDomain, h.cfg.DNSConfig)
node, err := h.toNode(*machine, h.cfg.BaseDomain, h.cfg.RemoveUserFromTaggedDNS, h.cfg.DNSConfig)
if err != nil {
log.Error().
Caller().
Expand All @@ -39,7 +39,7 @@ func (h *Headscale) generateMapResponse(

profiles := h.getMapResponseUserProfiles(*machine, peers)

nodePeers, err := h.toNodes(peers, h.cfg.BaseDomain, h.cfg.DNSConfig)
nodePeers, err := h.toNodes(peers, h.cfg.BaseDomain, h.cfg.RemoveUserFromTaggedDNS, h.cfg.DNSConfig)
if err != nil {
log.Error().
Caller().
Expand Down
3 changes: 2 additions & 1 deletion cmd/headscale/headscale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,13 @@ func (*Suite) TestDNSConfigLoading(c *check.C) {
err = headscale.LoadConfig(tmpDir, false)
c.Assert(err, check.IsNil)

dnsConfig, baseDomain := headscale.GetDNSConfig()
dnsConfig, baseDomain, removeUserFromTaggedDNS := headscale.GetDNSConfig()

c.Assert(dnsConfig.Nameservers[0].String(), check.Equals, "1.1.1.1")
c.Assert(dnsConfig.Resolvers[0].Addr, check.Equals, "1.1.1.1")
c.Assert(dnsConfig.Proxied, check.Equals, true)
c.Assert(baseDomain, check.Equals, "example.com")
c.Assert(removeUserFromTaggedDNS, check.Equals, false)
}

func writeConfig(c *check.C, tmpDir string, configYaml []byte) {
Expand Down
5 changes: 5 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ dns_config:
# `hostname.user.base_domain` (e.g., _myhost.myuser.example.com_).
base_domain: example.com

# Defines if a tagged node should ditch the user in MagicDNS FQDN.
# Would result in `<machine.given_name>.<base_domain>` instead of
# `<machine.given_name>.<machine.user.name>.<base_domain>`
remove_user_from_tagged_dns: false

# Unix socket used for the CLI to connect without authentication
# Note: for production you will want to set this to something like:
unix_socket: /var/run/headscale/headscale.sock
Expand Down
19 changes: 14 additions & 5 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Config struct {
PrivateKeyPath string
NoisePrivateKeyPath string
BaseDomain string
RemoveUserFromTaggedDNS bool
Log LogConfig
DisableUpdateCheck bool

Expand Down Expand Up @@ -373,7 +374,7 @@ func GetLogConfig() LogConfig {
}
}

func GetDNSConfig() (*tailcfg.DNSConfig, string) {
func GetDNSConfig() (*tailcfg.DNSConfig, string, bool) {
if viper.IsSet("dns_config") {
dnsConfig := &tailcfg.DNSConfig{}

Expand Down Expand Up @@ -484,10 +485,17 @@ func GetDNSConfig() (*tailcfg.DNSConfig, string) {
baseDomain = "headscale.net" // does not really matter when MagicDNS is not enabled
}

return dnsConfig, baseDomain
var removeUserFromTaggedDNS bool
if viper.IsSet("dns_config.remove_user_from_tagged_dns") {
removeUserFromTaggedDNS = viper.GetBool("dns_config.remove_user_from_tagged_dns")
} else {
removeUserFromTaggedDNS = false // does not really matter when MagicDNS is not enabled
}

return dnsConfig, baseDomain, removeUserFromTaggedDNS
}

return nil, ""
return nil, "", false
}

func GetHeadscaleConfig() (*Config, error) {
Expand All @@ -502,7 +510,7 @@ func GetHeadscaleConfig() (*Config, error) {
}, nil
}

dnsConfig, baseDomain := GetDNSConfig()
dnsConfig, baseDomain, removeUserFromTaggedDNS := GetDNSConfig()
derpConfig := GetDERPConfig()
logConfig := GetLogTailConfig()
randomizeClientPort := viper.GetBool("randomize_client_port")
Expand Down Expand Up @@ -567,7 +575,8 @@ func GetHeadscaleConfig() (*Config, error) {
NoisePrivateKeyPath: AbsolutePathFromConfigPath(
viper.GetString("noise.private_key_path"),
),
BaseDomain: baseDomain,
BaseDomain: baseDomain,
RemoveUserFromTaggedDNS: removeUserFromTaggedDNS,

DERP: derpConfig,

Expand Down
31 changes: 21 additions & 10 deletions machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,13 @@ func (machines MachinesP) String() string {
func (h *Headscale) toNodes(
machines Machines,
baseDomain string,
removeUserFromTaggedDNS bool,
dnsConfig *tailcfg.DNSConfig,
) ([]*tailcfg.Node, error) {
nodes := make([]*tailcfg.Node, len(machines))

for index, machine := range machines {
node, err := h.toNode(machine, baseDomain, dnsConfig)
node, err := h.toNode(machine, baseDomain, removeUserFromTaggedDNS, dnsConfig)
if err != nil {
return nil, err
}
Expand All @@ -694,6 +695,7 @@ func (h *Headscale) toNodes(
func (h *Headscale) toNode(
machine Machine,
baseDomain string,
removeUserFromTaggedDNS bool,
dnsConfig *tailcfg.DNSConfig,
) (*tailcfg.Node, error) {
var nodeKey key.NodePublic
Expand Down Expand Up @@ -770,14 +772,26 @@ func (h *Headscale) toNode(
keyExpiry = time.Time{}
}

tags, _ := getTags(h.aclPolicy, machine, h.cfg.OIDC.StripEmaildomain)
tags = lo.Uniq(append(tags, machine.ForcedTags...))

var hostname string
if dnsConfig != nil && dnsConfig.Proxied { // MagicDNS
hostname = fmt.Sprintf(
"%s.%s.%s",
machine.GivenName,
machine.User.Name,
baseDomain,
)

if len(tags) > 0 && removeUserFromTaggedDNS {
hostname = fmt.Sprintf(
"%s.%s",
machine.GivenName,
baseDomain,
)
} else {
hostname = fmt.Sprintf(
"%s.%s.%s",
machine.GivenName,
machine.User.Name,
baseDomain,
)
}
if len(hostname) > maxHostnameLength {
return nil, fmt.Errorf(
"hostname %q is too long it cannot except 255 ASCII chars: %w",
Expand All @@ -793,9 +807,6 @@ func (h *Headscale) toNode(

online := machine.isOnline()

tags, _ := getTags(h.aclPolicy, machine, h.cfg.OIDC.StripEmaildomain)
tags = lo.Uniq(append(tags, machine.ForcedTags...))

node := tailcfg.Node{
ID: tailcfg.NodeID(machine.ID), // this is the actual ID
StableID: tailcfg.StableNodeID(
Expand Down
2 changes: 1 addition & 1 deletion routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ func (s *Suite) TestAllowedIPRoutes(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(len(enabledRoutes1), check.Equals, 3)

peer, err := app.toNode(machine1, "headscale.net", nil)
peer, err := app.toNode(machine1, "headscale.net", false, nil)
c.Assert(err, check.IsNil)

c.Assert(len(peer.AllowedIPs), check.Equals, 3)
Expand Down