mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-11-04 10:01:05 +01:00 
			
		
		
		
	Propagate dns config vales across Headscale
This commit is contained in:
		
							parent
							
								
									5dbf6b5127
								
							
						
					
					
						commit
						656237e167
					
				
							
								
								
									
										16
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								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").
 | 
				
			||||||
@ -242,17 +242,11 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Mac
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp := tailcfg.MapResponse{
 | 
						resp := tailcfg.MapResponse{
 | 
				
			||||||
		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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user