Make IP prefix configurable

This commit makes the IP prefix used to generate addresses configurable
to users. This can be useful if you would like to use a smaller range or
if your current setup is overlapping with the current range.

The current range is left as a default
This commit is contained in:
Kristoffer Dalby 2021-08-02 20:06:26 +01:00
parent 6c903d4a2f
commit 309f868a21
4 changed files with 15 additions and 5 deletions

2
app.go
View file

@ -13,6 +13,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"gorm.io/gorm" "gorm.io/gorm"
"inet.af/netaddr"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
"tailscale.com/types/wgkey" "tailscale.com/types/wgkey"
) )
@ -24,6 +25,7 @@ type Config struct {
PrivateKeyPath string PrivateKeyPath string
DerpMap *tailcfg.DERPMap DerpMap *tailcfg.DERPMap
EphemeralNodeInactivityTimeout time.Duration EphemeralNodeInactivityTimeout time.Duration
IPPrefix netaddr.IPPrefix
DBtype string DBtype string
DBpath string DBpath string

View file

@ -6,6 +6,7 @@ import (
"testing" "testing"
"gopkg.in/check.v1" "gopkg.in/check.v1"
"inet.af/netaddr"
) )
func Test(t *testing.T) { func Test(t *testing.T) {
@ -36,7 +37,9 @@ func (s *Suite) ResetDB(c *check.C) {
if err != nil { if err != nil {
c.Fatal(err) c.Fatal(err)
} }
cfg := Config{} cfg := Config{
IPPrefix: netaddr.MustParseIPPrefix("127.0.0.1/32"),
}
h = Headscale{ h = Headscale{
cfg: cfg, cfg: cfg,

View file

@ -14,6 +14,7 @@ import (
"github.com/juanfont/headscale" "github.com/juanfont/headscale"
"github.com/spf13/viper" "github.com/spf13/viper"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"inet.af/netaddr"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
) )
@ -36,6 +37,8 @@ func LoadConfig(path string) error {
viper.SetDefault("tls_letsencrypt_cache_dir", "/var/www/.cache") viper.SetDefault("tls_letsencrypt_cache_dir", "/var/www/.cache")
viper.SetDefault("tls_letsencrypt_challenge_type", "HTTP-01") viper.SetDefault("tls_letsencrypt_challenge_type", "HTTP-01")
viper.SetDefault("ip_prefix", "100.64.0.0/10")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
return fmt.Errorf("Fatal error reading config file: %s \n", err) return fmt.Errorf("Fatal error reading config file: %s \n", err)
@ -97,6 +100,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
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")),
EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"), EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"),

View file

@ -19,6 +19,7 @@ import (
"golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/box"
"gorm.io/gorm" "gorm.io/gorm"
"inet.af/netaddr"
"tailscale.com/types/wgkey" "tailscale.com/types/wgkey"
) )
@ -80,7 +81,7 @@ func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, err
func (h *Headscale) getAvailableIP() (*net.IP, error) { func (h *Headscale) getAvailableIP() (*net.IP, error) {
i := 0 i := 0
for { for {
ip, err := getRandomIP() ip, err := getRandomIP(h.cfg.IPPrefix)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -93,12 +94,12 @@ func (h *Headscale) getAvailableIP() (*net.IP, error) {
break break
} }
} }
return nil, errors.New("Could not find an available IP address in 100.64.0.0/10") return nil, errors.New(fmt.Sprintf("Could not find an available IP address in %s", h.cfg.IPPrefix.String()))
} }
func getRandomIP() (*net.IP, error) { func getRandomIP(ipPrefix netaddr.IPPrefix) (*net.IP, error) {
mathrand.Seed(time.Now().Unix()) mathrand.Seed(time.Now().Unix())
ipo, ipnet, err := net.ParseCIDR("100.64.0.0/10") ipo, ipnet, err := net.ParseCIDR(ipPrefix.String())
if err == nil { if err == nil {
ip := ipo.To4() ip := ipo.To4()
// fmt.Println("In Randomize IPAddr: IP ", ip, " IPNET: ", ipnet) // fmt.Println("In Randomize IPAddr: IP ", ip, " IPNET: ", ipnet)