WIP on PreAuthKeys

This commit is contained in:
Juan Font Alonso 2021-04-23 00:25:01 +02:00
parent 2555220a57
commit 176eea4a84
3 changed files with 121 additions and 1 deletions

View file

@ -169,6 +169,43 @@ var enableRouteCmd = &cobra.Command{
}, },
} }
var preauthkeysCmd = &cobra.Command{
Use: "preauthkey",
Short: "Handle the preauthkeys in Headscale",
}
var listPreAuthKeys = &cobra.Command{
Use: "list NAMESPACE",
Short: "List the preauthkeys for this namespace",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("Missing parameters")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
h, err := getHeadscaleApp()
if err != nil {
log.Fatalf("Error initializing: %s", err)
}
keys, err := h.GetPreAuthKeys(args[0])
if err != nil {
fmt.Println(err)
return
}
for _, k := range *keys {
fmt.Printf(
"key: %s, namespace: %s, reusable: %v, expiration: %s, created_at: %s",
k.Key,
k.Namespace.Name,
k.Reusable,
k.Expiration.Format("2006-01-02 15:04:05"),
k.CreatedAt.Format("2006-01-02 15:04:05"),
)
}
},
}
func main() { func main() {
viper.SetConfigName("config") viper.SetConfigName("config")
viper.AddConfigPath("/etc/headscale/") viper.AddConfigPath("/etc/headscale/")
@ -183,14 +220,18 @@ func main() {
headscaleCmd.AddCommand(versionCmd) headscaleCmd.AddCommand(versionCmd)
headscaleCmd.AddCommand(serveCmd) headscaleCmd.AddCommand(serveCmd)
headscaleCmd.AddCommand(registerCmd) headscaleCmd.AddCommand(registerCmd)
headscaleCmd.AddCommand(preauthkeysCmd)
headscaleCmd.AddCommand(namespaceCmd) headscaleCmd.AddCommand(namespaceCmd)
headscaleCmd.AddCommand(nodeCmd)
namespaceCmd.AddCommand(createNamespaceCmd) namespaceCmd.AddCommand(createNamespaceCmd)
namespaceCmd.AddCommand(listNamespacesCmd) namespaceCmd.AddCommand(listNamespacesCmd)
headscaleCmd.AddCommand(nodeCmd)
nodeCmd.AddCommand(listRoutesCmd) nodeCmd.AddCommand(listRoutesCmd)
nodeCmd.AddCommand(enableRouteCmd) nodeCmd.AddCommand(enableRouteCmd)
preauthkeysCmd.AddCommand(listPreAuthKeys)
if err := headscaleCmd.Execute(); err != nil { if err := headscaleCmd.Execute(); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(-1) os.Exit(-1)

1
db.go
View file

@ -24,6 +24,7 @@ func (h *Headscale) initDB() error {
db.AutoMigrate(&Machine{}) db.AutoMigrate(&Machine{})
db.AutoMigrate(&KV{}) db.AutoMigrate(&KV{})
db.AutoMigrate(&Namespace{}) db.AutoMigrate(&Namespace{})
db.AutoMigrate(&PreAuthKey{})
db.Close() db.Close()
h.setValue("db_version", dbVersion) h.setValue("db_version", dbVersion)

78
preauth_keys.go Normal file
View file

@ -0,0 +1,78 @@
package headscale
import (
"crypto/rand"
"encoding/hex"
"log"
"time"
)
type PreAuthKey struct {
ID uint64 `gorm:"primary_key"`
Key string
NamespaceID uint
Namespace Namespace
Reusable bool
CreatedAt *time.Time
Expiration *time.Time
}
func (h *Headscale) CreatePreAuthKey(namespaceName string, reusable bool, expiration *time.Time) (*PreAuthKey, error) {
n, err := h.GetNamespace(namespaceName)
if err != nil {
return nil, err
}
db, err := h.db()
if err != nil {
log.Printf("Cannot open DB: %s", err)
return nil, err
}
defer db.Close()
now := time.Now().UTC()
kstr, err := h.generateKey()
if err != nil {
return nil, err
}
k := PreAuthKey{
Key: kstr,
NamespaceID: n.ID,
Reusable: reusable,
CreatedAt: &now,
Expiration: expiration,
}
db.Save(&k)
return &k, nil
}
func (h *Headscale) GetPreAuthKeys(namespaceName string) (*[]PreAuthKey, error) {
n, err := h.GetNamespace(namespaceName)
if err != nil {
return nil, err
}
db, err := h.db()
if err != nil {
log.Printf("Cannot open DB: %s", err)
return nil, err
}
defer db.Close()
keys := []PreAuthKey{}
if err := db.Where(&PreAuthKey{NamespaceID: n.ID}).Find(&keys).Error; err != nil {
return nil, err
}
return &keys, nil
}
func (h *Headscale) generateKey() (string, error) {
size := 24
bytes := make([]byte, size)
if _, err := rand.Read(bytes); err != nil {
return "", err
}
return hex.EncodeToString(bytes), nil
}