mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Propagate dns config vales across Headscale
This commit is contained in:
		
							parent
							
								
									5dbf6b5127
								
							
						
					
					
						commit
						656237e167
					
				
							
								
								
									
										10
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								api.go
									
									
									
									
									
								
							| @ -218,7 +218,7 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Mac | |||||||
| 		Str("func", "getMapResponse"). | 		Str("func", "getMapResponse"). | ||||||
| 		Str("machine", req.Hostinfo.Hostname). | 		Str("machine", req.Hostinfo.Hostname). | ||||||
| 		Msg("Creating Map response") | 		Msg("Creating Map response") | ||||||
| 	node, err := m.toNode(true) | 	node, err := h.toNode(m, true) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error(). | 		log.Error(). | ||||||
| 			Str("func", "getMapResponse"). | 			Str("func", "getMapResponse"). | ||||||
| @ -245,14 +245,8 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Mac | |||||||
| 		KeepAlive:    false, | 		KeepAlive:    false, | ||||||
| 		Node:         node, | 		Node:         node, | ||||||
| 		Peers:        *peers, | 		Peers:        *peers, | ||||||
| 		//TODO(kradalby): As per tailscale docs, if DNSConfig is nil,
 |  | ||||||
| 		// it means its not updated, maybe we can have some logic
 |  | ||||||
| 		// to check and only pass updates when its updates.
 |  | ||||||
| 		// This is probably more relevant if we try to implement
 |  | ||||||
| 		// "MagicDNS"
 |  | ||||||
| 		DNSConfig:    h.cfg.DNSConfig, | 		DNSConfig:    h.cfg.DNSConfig, | ||||||
| 		SearchPaths:  []string{}, | 		Domain:       h.cfg.BaseDomain, | ||||||
| 		Domain:       "headscale.net", |  | ||||||
| 		PacketFilter: *h.aclRules, | 		PacketFilter: *h.aclRules, | ||||||
| 		DERPMap:      h.cfg.DerpMap, | 		DERPMap:      h.cfg.DerpMap, | ||||||
| 		UserProfiles: []tailcfg.UserProfile{profile}, | 		UserProfiles: []tailcfg.UserProfile{profile}, | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								app.go
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ type Config struct { | |||||||
| 	DerpMap                        *tailcfg.DERPMap | 	DerpMap                        *tailcfg.DERPMap | ||||||
| 	EphemeralNodeInactivityTimeout time.Duration | 	EphemeralNodeInactivityTimeout time.Duration | ||||||
| 	IPPrefix                       netaddr.IPPrefix | 	IPPrefix                       netaddr.IPPrefix | ||||||
|  | 	BaseDomain                     string | ||||||
| 
 | 
 | ||||||
| 	DBtype string | 	DBtype string | ||||||
| 	DBpath string | 	DBpath string | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ func LoadConfig(path string) error { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func GetDNSConfig() *tailcfg.DNSConfig { | func GetDNSConfig() (*tailcfg.DNSConfig, string) { | ||||||
| 	if viper.IsSet("dns_config") { | 	if viper.IsSet("dns_config") { | ||||||
| 		dnsConfig := &tailcfg.DNSConfig{} | 		dnsConfig := &tailcfg.DNSConfig{} | ||||||
| 
 | 
 | ||||||
| @ -112,11 +112,16 @@ func GetDNSConfig() *tailcfg.DNSConfig { | |||||||
| 			dnsConfig.Proxied = viper.GetBool("dns_config.magic_dns") | 			dnsConfig.Proxied = viper.GetBool("dns_config.magic_dns") | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return dnsConfig | 		var baseDomain string | ||||||
| 
 | 		if viper.IsSet("dns_config.base_domain") { | ||||||
|  | 			baseDomain = viper.GetString("dns_config.base_domain") | ||||||
|  | 		} else { | ||||||
|  | 			baseDomain = "headscale.net" // does not really matter when MagicDNS is not enabled
 | ||||||
|  | 		} | ||||||
|  | 		return dnsConfig, baseDomain | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil, "" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func absPath(path string) string { | func absPath(path string) string { | ||||||
| @ -149,12 +154,15 @@ func getHeadscaleApp() (*headscale.Headscale, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	dnsConfig, baseDomain := GetDNSConfig() | ||||||
|  | 
 | ||||||
| 	cfg := headscale.Config{ | 	cfg := headscale.Config{ | ||||||
| 		ServerURL:      viper.GetString("server_url"), | 		ServerURL:      viper.GetString("server_url"), | ||||||
| 		Addr:           viper.GetString("listen_addr"), | 		Addr:           viper.GetString("listen_addr"), | ||||||
| 		PrivateKeyPath: absPath(viper.GetString("private_key_path")), | 		PrivateKeyPath: absPath(viper.GetString("private_key_path")), | ||||||
| 		DerpMap:        derpMap, | 		DerpMap:        derpMap, | ||||||
| 		IPPrefix:       netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), | 		IPPrefix:       netaddr.MustParseIPPrefix(viper.GetString("ip_prefix")), | ||||||
|  | 		BaseDomain:     baseDomain, | ||||||
| 
 | 
 | ||||||
| 		EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"), | 		EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"), | ||||||
| 
 | 
 | ||||||
| @ -174,7 +182,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { | |||||||
| 		TLSCertPath: absPath(viper.GetString("tls_cert_path")), | 		TLSCertPath: absPath(viper.GetString("tls_cert_path")), | ||||||
| 		TLSKeyPath:  absPath(viper.GetString("tls_key_path")), | 		TLSKeyPath:  absPath(viper.GetString("tls_key_path")), | ||||||
| 
 | 
 | ||||||
| 		DNSConfig: GetDNSConfig(), | 		DNSConfig: dnsConfig, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	h, err := headscale.NewHeadscale(cfg) | 	h, err := headscale.NewHeadscale(cfg) | ||||||
|  | |||||||
| @ -642,6 +642,19 @@ func (s *IntegrationTestSuite) TestTailDrop() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // func (s *IntegrationTestSuite) TestMagicDNS() {
 | ||||||
|  | // 	for _, scales := range s.namespaces {
 | ||||||
|  | // 		ips, err := getIPs(scales.tailscales)
 | ||||||
|  | // 		assert.Nil(s.T(), err)
 | ||||||
|  | // 		apiURLs, err := getAPIURLs(scales.tailscales)
 | ||||||
|  | // 		assert.Nil(s.T(), err)
 | ||||||
|  | 
 | ||||||
|  | // 		for hostname, tailscale := range scales.tailscales {
 | ||||||
|  | 
 | ||||||
|  | // 		}
 | ||||||
|  | // 	}
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
| func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, error) { | func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, error) { | ||||||
| 	ips := make(map[string]netaddr.IP) | 	ips := make(map[string]netaddr.IP) | ||||||
| 	for hostname, tailscale := range tailscales { | 	for hostname, tailscale := range tailscales { | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								machine.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								machine.go
									
									
									
									
									
								
							| @ -52,7 +52,7 @@ func (m Machine) isAlreadyRegistered() bool { | |||||||
| 
 | 
 | ||||||
| // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes
 | // toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes
 | ||||||
| // as per the expected behaviour in the official SaaS
 | // as per the expected behaviour in the official SaaS
 | ||||||
| func (m Machine) toNode(includeRoutes bool) (*tailcfg.Node, error) { | func (h *Headscale) toNode(m Machine, includeRoutes bool) (*tailcfg.Node, error) { | ||||||
| 	nKey, err := wgkey.ParseHex(m.NodeKey) | 	nKey, err := wgkey.ParseHex(m.NodeKey) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @ -147,10 +147,12 @@ func (m Machine) toNode(includeRoutes bool) (*tailcfg.Node, error) { | |||||||
| 		keyExpiry = time.Time{} | 		keyExpiry = time.Time{} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	hostname := fmt.Sprintf("%s.%s.%s", m.Name, m.Namespace.Name, h.cfg.BaseDomain) | ||||||
|  | 
 | ||||||
| 	n := tailcfg.Node{ | 	n := tailcfg.Node{ | ||||||
| 		ID:         tailcfg.NodeID(m.ID),                               // this is the actual ID
 | 		ID:         tailcfg.NodeID(m.ID),                               // this is the actual ID
 | ||||||
| 		StableID:   tailcfg.StableNodeID(strconv.FormatUint(m.ID, 10)), // in headscale, unlike tailcontrol server, IDs are permanent
 | 		StableID:   tailcfg.StableNodeID(strconv.FormatUint(m.ID, 10)), // in headscale, unlike tailcontrol server, IDs are permanent
 | ||||||
| 		Name:       hostinfo.Hostname, | 		Name:       hostname, | ||||||
| 		User:       tailcfg.UserID(m.NamespaceID), | 		User:       tailcfg.UserID(m.NamespaceID), | ||||||
| 		Key:        tailcfg.NodeKey(nKey), | 		Key:        tailcfg.NodeKey(nKey), | ||||||
| 		KeyExpiry:  keyExpiry, | 		KeyExpiry:  keyExpiry, | ||||||
| @ -169,6 +171,8 @@ func (m Machine) toNode(includeRoutes bool) (*tailcfg.Node, error) { | |||||||
| 		MachineAuthorized: m.Registered, | 		MachineAuthorized: m.Registered, | ||||||
| 		Capabilities:      []string{tailcfg.CapabilityFileSharing}, | 		Capabilities:      []string{tailcfg.CapabilityFileSharing}, | ||||||
| 	} | 	} | ||||||
|  | 	// TODO(juanfont): Node also has Sharer when is a shared node with info on the profile
 | ||||||
|  | 
 | ||||||
| 	return &n, nil | 	return &n, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -179,7 +183,7 @@ func (h *Headscale) getPeers(m Machine) (*[]*tailcfg.Node, error) { | |||||||
| 		Msg("Finding peers") | 		Msg("Finding peers") | ||||||
| 
 | 
 | ||||||
| 	machines := []Machine{} | 	machines := []Machine{} | ||||||
| 	if err := h.db.Where("namespace_id = ? AND machine_key <> ? AND registered", | 	if err := h.db.Preload("Namespace").Where("namespace_id = ? AND machine_key <> ? AND registered", | ||||||
| 		m.NamespaceID, m.MachineKey).Find(&machines).Error; err != nil { | 		m.NamespaceID, m.MachineKey).Find(&machines).Error; err != nil { | ||||||
| 		log.Error().Err(err).Msg("Error accessing db") | 		log.Error().Err(err).Msg("Error accessing db") | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @ -194,14 +198,14 @@ func (h *Headscale) getPeers(m Machine) (*[]*tailcfg.Node, error) { | |||||||
| 
 | 
 | ||||||
| 	peers := []*tailcfg.Node{} | 	peers := []*tailcfg.Node{} | ||||||
| 	for _, mn := range machines { | 	for _, mn := range machines { | ||||||
| 		peer, err := mn.toNode(true) | 		peer, err := h.toNode(mn, true) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		peers = append(peers, peer) | 		peers = append(peers, peer) | ||||||
| 	} | 	} | ||||||
| 	for _, sharedMachine := range sharedMachines { | 	for _, sharedMachine := range sharedMachines { | ||||||
| 		peer, err := sharedMachine.Machine.toNode(false) // shared nodes do not expose their routes
 | 		peer, err := h.toNode(sharedMachine.Machine, false) // shared nodes do not expose their routes
 | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								poll.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								poll.go
									
									
									
									
									
								
							| @ -440,7 +440,7 @@ func (h *Headscale) scheduledPollWorker( | |||||||
| 		case <-updateCheckerTicker.C: | 		case <-updateCheckerTicker.C: | ||||||
| 			// Send an update request regardless of outdated or not, if data is sent
 | 			// Send an update request regardless of outdated or not, if data is sent
 | ||||||
| 			// to the node is determined in the updateChan consumer block
 | 			// to the node is determined in the updateChan consumer block
 | ||||||
| 			n, _ := m.toNode(true) | 			n, _ := h.toNode(m, true) | ||||||
| 			err := h.sendRequestOnUpdateChannel(n) | 			err := h.sendRequestOnUpdateChannel(n) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error(). | 				log.Error(). | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user