mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Merge pull request #42 from juanfont/tailscale-1.8.x
Update Headscale to Tailscale 1.10
This commit is contained in:
		
						commit
						ba87ade9c5
					
				
							
								
								
									
										27
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								api.go
									
									
									
									
									
								
							@ -16,7 +16,7 @@ import (
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
	"inet.af/netaddr"
 | 
			
		||||
	"tailscale.com/tailcfg"
 | 
			
		||||
	"tailscale.com/wgengine/wgcfg"
 | 
			
		||||
	"tailscale.com/types/wgkey"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// KeyHandler provides the Headscale pub key
 | 
			
		||||
@ -61,7 +61,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) {
 | 
			
		||||
func (h *Headscale) RegistrationHandler(c *gin.Context) {
 | 
			
		||||
	body, _ := io.ReadAll(c.Request.Body)
 | 
			
		||||
	mKeyStr := c.Param("id")
 | 
			
		||||
	mKey, err := wgcfg.ParseHexKey(mKeyStr)
 | 
			
		||||
	mKey, err := wgkey.ParseHex(mKeyStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("Cannot parse machine key: %s", err)
 | 
			
		||||
		c.String(http.StatusInternalServerError, "Sad!")
 | 
			
		||||
@ -89,7 +89,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
 | 
			
		||||
			Expiry:     &req.Expiry,
 | 
			
		||||
			MachineKey: mKey.HexString(),
 | 
			
		||||
			Name:       req.Hostinfo.Hostname,
 | 
			
		||||
			NodeKey:    wgcfg.Key(req.NodeKey).HexString(),
 | 
			
		||||
			NodeKey:    wgkey.Key(req.NodeKey).HexString(),
 | 
			
		||||
		}
 | 
			
		||||
		if err := db.Create(&m).Error; err != nil {
 | 
			
		||||
			log.Printf("Could not create row: %s", err)
 | 
			
		||||
@ -105,7 +105,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
 | 
			
		||||
	resp := tailcfg.RegisterResponse{}
 | 
			
		||||
 | 
			
		||||
	// We have the updated key!
 | 
			
		||||
	if m.NodeKey == wgcfg.Key(req.NodeKey).HexString() {
 | 
			
		||||
	if m.NodeKey == wgkey.Key(req.NodeKey).HexString() {
 | 
			
		||||
		if m.Registered {
 | 
			
		||||
			log.Printf("[%s] Client is registered and we have the current NodeKey. All clear to /map", m.Name)
 | 
			
		||||
			resp.AuthURL = ""
 | 
			
		||||
@ -135,9 +135,9 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// The NodeKey we have matches OldNodeKey, which means this is a refresh after an key expiration
 | 
			
		||||
	if m.NodeKey == wgcfg.Key(req.OldNodeKey).HexString() {
 | 
			
		||||
	if m.NodeKey == wgkey.Key(req.OldNodeKey).HexString() {
 | 
			
		||||
		log.Printf("[%s] We have the OldNodeKey in the database. This is a key refresh", m.Name)
 | 
			
		||||
		m.NodeKey = wgcfg.Key(req.NodeKey).HexString()
 | 
			
		||||
		m.NodeKey = wgkey.Key(req.NodeKey).HexString()
 | 
			
		||||
		db.Save(&m)
 | 
			
		||||
 | 
			
		||||
		resp.AuthURL = ""
 | 
			
		||||
@ -192,7 +192,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
 | 
			
		||||
func (h *Headscale) PollNetMapHandler(c *gin.Context) {
 | 
			
		||||
	body, _ := io.ReadAll(c.Request.Body)
 | 
			
		||||
	mKeyStr := c.Param("id")
 | 
			
		||||
	mKey, err := wgcfg.ParseHexKey(mKeyStr)
 | 
			
		||||
	mKey, err := wgkey.ParseHex(mKeyStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("Cannot parse client key: %s", err)
 | 
			
		||||
		return
 | 
			
		||||
@ -218,7 +218,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
 | 
			
		||||
	hostinfo, _ := json.Marshal(req.Hostinfo)
 | 
			
		||||
	m.Name = req.Hostinfo.Hostname
 | 
			
		||||
	m.HostInfo = datatypes.JSON(hostinfo)
 | 
			
		||||
	m.DiscoKey = wgcfg.Key(req.DiscoKey).HexString()
 | 
			
		||||
	m.DiscoKey = wgkey.Key(req.DiscoKey).HexString()
 | 
			
		||||
	now := time.Now().UTC()
 | 
			
		||||
 | 
			
		||||
	// From Tailscale client:
 | 
			
		||||
@ -334,7 +334,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) {
 | 
			
		||||
func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgkey.Key, req tailcfg.MapRequest, m Machine) {
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-cancel:
 | 
			
		||||
@ -355,7 +355,7 @@ func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgc
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) {
 | 
			
		||||
func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) {
 | 
			
		||||
	node, err := m.toNode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("Cannot convert to node: %s", err)
 | 
			
		||||
@ -376,7 +376,6 @@ func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Mac
 | 
			
		||||
		PacketFilter: tailcfg.FilterAllowAll,
 | 
			
		||||
		DERPMap:      h.cfg.DerpMap,
 | 
			
		||||
		UserProfiles: []tailcfg.UserProfile{},
 | 
			
		||||
		Roles:        []tailcfg.Role{},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var respBody []byte
 | 
			
		||||
@ -402,7 +401,7 @@ func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Mac
 | 
			
		||||
	return &data, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Headscale) getMapKeepAliveResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) {
 | 
			
		||||
func (h *Headscale) getMapKeepAliveResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) {
 | 
			
		||||
	resp := tailcfg.MapResponse{
 | 
			
		||||
		KeepAlive: true,
 | 
			
		||||
	}
 | 
			
		||||
@ -428,7 +427,7 @@ func (h *Headscale) getMapKeepAliveResponse(mKey wgcfg.Key, req tailcfg.MapReque
 | 
			
		||||
	return &data, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgcfg.Key, req tailcfg.RegisterRequest, m Machine) {
 | 
			
		||||
func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, req tailcfg.RegisterRequest, m Machine) {
 | 
			
		||||
	resp := tailcfg.RegisterResponse{}
 | 
			
		||||
	pak, err := h.checkKeyValidity(req.Auth.AuthKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -452,7 +451,7 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgcfg.Key,
 | 
			
		||||
	m.AuthKeyID = uint(pak.ID)
 | 
			
		||||
	m.IPAddress = ip.String()
 | 
			
		||||
	m.NamespaceID = pak.NamespaceID
 | 
			
		||||
	m.NodeKey = wgcfg.Key(req.NodeKey).HexString() // we update it just in case
 | 
			
		||||
	m.NodeKey = wgkey.Key(req.NodeKey).HexString() // we update it just in case
 | 
			
		||||
	m.Registered = true
 | 
			
		||||
	m.RegisterMethod = "authKey"
 | 
			
		||||
	db.Save(&m)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								app.go
									
									
									
									
									
								
							@ -13,7 +13,7 @@ import (
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"golang.org/x/crypto/acme/autocert"
 | 
			
		||||
	"tailscale.com/tailcfg"
 | 
			
		||||
	"tailscale.com/wgengine/wgcfg"
 | 
			
		||||
	"tailscale.com/types/wgkey"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Config contains the initial Headscale configuration
 | 
			
		||||
@ -46,8 +46,8 @@ type Headscale struct {
 | 
			
		||||
	dbString   string
 | 
			
		||||
	dbType     string
 | 
			
		||||
	dbDebug    bool
 | 
			
		||||
	publicKey  *wgcfg.Key
 | 
			
		||||
	privateKey *wgcfg.PrivateKey
 | 
			
		||||
	publicKey  *wgkey.Key
 | 
			
		||||
	privateKey *wgkey.Private
 | 
			
		||||
 | 
			
		||||
	pollMu         sync.Mutex
 | 
			
		||||
	clientsPolling map[uint64]chan []byte // this is by all means a hackity hack
 | 
			
		||||
@ -59,7 +59,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	privKey, err := wgcfg.ParsePrivateKey(string(content))
 | 
			
		||||
	privKey, err := wgkey.ParsePrivate(string(content))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								cli.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cli.go
									
									
									
									
									
								
							@ -5,7 +5,7 @@ import (
 | 
			
		||||
	"log"
 | 
			
		||||
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
	"tailscale.com/wgengine/wgcfg"
 | 
			
		||||
	"tailscale.com/types/wgkey"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey
 | 
			
		||||
@ -14,7 +14,7 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	mKey, err := wgcfg.ParseHexKey(key)
 | 
			
		||||
	mKey, err := wgkey.ParseHex(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								go.mod
									
									
									
									
									
								
							@ -3,28 +3,20 @@ module github.com/juanfont/headscale
 | 
			
		||||
go 1.16
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/fsnotify/fsnotify v1.4.9 // indirect
 | 
			
		||||
	github.com/gin-gonic/gin v1.7.1
 | 
			
		||||
	github.com/hako/durafmt v0.0.0-20210316092057-3a2c319c1acd
 | 
			
		||||
	github.com/json-iterator/go v1.1.11 // indirect
 | 
			
		||||
	github.com/klauspost/compress v1.12.2
 | 
			
		||||
	github.com/kr/text v0.2.0 // indirect
 | 
			
		||||
	github.com/lib/pq v1.10.1 // indirect
 | 
			
		||||
	github.com/gin-gonic/gin v1.7.2
 | 
			
		||||
	github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b
 | 
			
		||||
	github.com/klauspost/compress v1.13.1
 | 
			
		||||
	github.com/lib/pq v1.10.2 // indirect
 | 
			
		||||
	github.com/mattn/go-sqlite3 v1.14.7 // indirect
 | 
			
		||||
	github.com/spf13/cobra v1.1.3
 | 
			
		||||
	github.com/spf13/viper v1.7.1
 | 
			
		||||
	github.com/stretchr/testify v1.7.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
 | 
			
		||||
	golang.org/x/text v0.3.6 // indirect
 | 
			
		||||
	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
 | 
			
		||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
			
		||||
	github.com/spf13/viper v1.8.1
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
 | 
			
		||||
	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
 | 
			
		||||
	gopkg.in/yaml.v2 v2.4.0
 | 
			
		||||
	gorm.io/datatypes v1.0.1
 | 
			
		||||
	gorm.io/driver/postgres v1.0.8
 | 
			
		||||
	gorm.io/driver/postgres v1.1.0
 | 
			
		||||
	gorm.io/driver/sqlite v1.1.4
 | 
			
		||||
	gorm.io/gorm v1.21.6
 | 
			
		||||
	inet.af/netaddr v0.0.0-20210511181906-37180328850c
 | 
			
		||||
	tailscale.com v1.6.0
 | 
			
		||||
 | 
			
		||||
	gorm.io/gorm v1.21.11
 | 
			
		||||
	inet.af/netaddr v0.0.0-20210603230628-bf05d8b52dda
 | 
			
		||||
	tailscale.com v1.10.0
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								machine.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								machine.go
									
									
									
									
									
								
							@ -11,7 +11,7 @@ import (
 | 
			
		||||
	"gorm.io/datatypes"
 | 
			
		||||
	"inet.af/netaddr"
 | 
			
		||||
	"tailscale.com/tailcfg"
 | 
			
		||||
	"tailscale.com/wgengine/wgcfg"
 | 
			
		||||
	"tailscale.com/types/wgkey"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Machine is a Headscale client
 | 
			
		||||
@ -23,7 +23,7 @@ type Machine struct {
 | 
			
		||||
	IPAddress   string
 | 
			
		||||
	Name        string
 | 
			
		||||
	NamespaceID uint
 | 
			
		||||
	Namespace   Namespace
 | 
			
		||||
	Namespace   Namespace `gorm:"foreignKey:NamespaceID"`
 | 
			
		||||
 | 
			
		||||
	Registered     bool // temp
 | 
			
		||||
	RegisterMethod string
 | 
			
		||||
@ -48,18 +48,18 @@ func (m Machine) isAlreadyRegistered() bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m Machine) toNode() (*tailcfg.Node, error) {
 | 
			
		||||
	nKey, err := wgcfg.ParseHexKey(m.NodeKey)
 | 
			
		||||
	nKey, err := wgkey.ParseHex(m.NodeKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	mKey, err := wgcfg.ParseHexKey(m.MachineKey)
 | 
			
		||||
	mKey, err := wgkey.ParseHex(m.MachineKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var discoKey tailcfg.DiscoKey
 | 
			
		||||
	if m.DiscoKey != "" {
 | 
			
		||||
		dKey, err := wgcfg.ParseHexKey(m.DiscoKey)
 | 
			
		||||
		dKey, err := wgkey.ParseHex(m.DiscoKey)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -144,7 +144,6 @@ func (n *Namespace) toUser() *tailcfg.User {
 | 
			
		||||
		ProfilePicURL: "",
 | 
			
		||||
		Domain:        "",
 | 
			
		||||
		Logins:        []tailcfg.LoginID{},
 | 
			
		||||
		Roles:         []tailcfg.RoleID{},
 | 
			
		||||
		Created:       time.Time{},
 | 
			
		||||
	}
 | 
			
		||||
	return &u
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								utils.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								utils.go
									
									
									
									
									
								
							@ -19,7 +19,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/crypto/nacl/box"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
	"tailscale.com/wgengine/wgcfg"
 | 
			
		||||
	"tailscale.com/types/wgkey"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors
 | 
			
		||||
@ -27,11 +27,11 @@ type Error string
 | 
			
		||||
 | 
			
		||||
func (e Error) Error() string { return string(e) }
 | 
			
		||||
 | 
			
		||||
func decode(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) error {
 | 
			
		||||
func decode(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error {
 | 
			
		||||
	return decodeMsg(msg, v, pubKey, privKey)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeMsg(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) error {
 | 
			
		||||
func decodeMsg(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error {
 | 
			
		||||
	decrypted, err := decryptMsg(msg, pubKey, privKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@ -43,7 +43,7 @@ func decodeMsg(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.Priv
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decryptMsg(msg []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) {
 | 
			
		||||
func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) {
 | 
			
		||||
	var nonce [24]byte
 | 
			
		||||
	if len(msg) < len(nonce)+1 {
 | 
			
		||||
		return nil, fmt.Errorf("response missing nonce, len=%d", len(msg))
 | 
			
		||||
@ -59,7 +59,7 @@ func decryptMsg(msg []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byt
 | 
			
		||||
	return decrypted, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func encode(v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) {
 | 
			
		||||
func encode(v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) {
 | 
			
		||||
	b, err := json.Marshal(v)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
@ -67,7 +67,7 @@ func encode(v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte
 | 
			
		||||
	return encodeMsg(b, pubKey, privKey)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func encodeMsg(b []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) {
 | 
			
		||||
func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) {
 | 
			
		||||
	var nonce [24]byte
 | 
			
		||||
	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user