diff --git a/app.go b/app.go index 917d32b8..c3f7c12a 100644 --- a/app.go +++ b/app.go @@ -71,12 +71,15 @@ const ( // Headscale represents the base app of the service. type Headscale struct { - cfg *Config - db *gorm.DB - dbString string - dbType string - dbDebug bool - privateKey *key.MachinePrivate + cfg *Config + db *gorm.DB + dbString string + dbType string + dbDebug bool + privateKey *key.MachinePrivate + noisePrivateKey *key.MachinePrivate + + noiseRouter *gin.Engine DERPMap *tailcfg.DERPMap DERPServer *DERPServer @@ -116,11 +119,20 @@ func LookupTLSClientAuthMode(mode string) (tls.ClientAuthType, bool) { } func NewHeadscale(cfg *Config) (*Headscale, error) { - privKey, err := readOrCreatePrivateKey(cfg.PrivateKeyPath) + privateKey, err := readOrCreatePrivateKey(cfg.PrivateKeyPath) if err != nil { return nil, fmt.Errorf("failed to read or create private key: %w", err) } + noisePrivateKey, err := readOrCreatePrivateKey(cfg.NoisePrivateKeyPath) + if err != nil { + return nil, fmt.Errorf("failed to read or create noise private key: %w", err) + } + + if privateKey.Equal(*noisePrivateKey) { + return nil, fmt.Errorf("private key and noise private key are the same") + } + var dbString string switch cfg.DBtype { case Postgres: @@ -147,7 +159,8 @@ func NewHeadscale(cfg *Config) (*Headscale, error) { cfg: cfg, dbType: cfg.DBtype, dbString: dbString, - privateKey: privKey, + privateKey: privateKey, + noisePrivateKey: noisePrivateKey, aclRules: tailcfg.FilterAllowAll, // default allowall registrationCache: registrationCache, } diff --git a/config-example.yaml b/config-example.yaml index 9740f3ad..039f9ed0 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -41,6 +41,13 @@ grpc_allow_insecure: false # autogenerated if it's missing private_key_path: /var/lib/headscale/private.key +# The Noise private key is used to encrypt the +# traffic between headscale and Tailscale clients when +# using the new Noise-based TS2021 protocol. +# The noise private key file which will be +# autogenerated if it's missing +noise_private_key_path: /var/lib/headscale/noise_private.key + # List of IP prefixes to allocate tailaddresses from. # Each prefix consists of either an IPv4 or IPv6 address, # and the associated prefix length, delimited by a slash. diff --git a/config.go b/config.go index 917b4734..10a5d120 100644 --- a/config.go +++ b/config.go @@ -28,6 +28,7 @@ type Config struct { EphemeralNodeInactivityTimeout time.Duration IPPrefixes []netaddr.IPPrefix PrivateKeyPath string + NoisePrivateKeyPath string BaseDomain string LogLevel zerolog.Level DisableUpdateCheck bool @@ -455,6 +456,9 @@ func GetHeadscaleConfig() (*Config, error) { PrivateKeyPath: AbsolutePathFromConfigPath( viper.GetString("private_key_path"), ), + NoisePrivateKeyPath: AbsolutePathFromConfigPath( + viper.GetString("noise_private_key_path"), + ), BaseDomain: baseDomain, DERP: derpConfig,