github.com/yggdrasil-network/yggdrasil-go@v0.5.6/contrib/ansible/genkeys.go (about) 1 /* 2 This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/) 3 */ 4 package main 5 6 import ( 7 "crypto/ed25519" 8 "encoding/hex" 9 "flag" 10 "fmt" 11 "net" 12 "os" 13 14 "github.com/cheggaaa/pb/v3" 15 "github.com/yggdrasil-network/yggdrasil-go/src/address" 16 ) 17 18 var numHosts = flag.Int("hosts", 1, "number of host vars to generate") 19 var keyTries = flag.Int("tries", 1000, "number of tries before taking the best keys") 20 21 type keySet struct { 22 priv []byte 23 pub []byte 24 ip string 25 } 26 27 func main() { 28 flag.Parse() 29 30 bar := pb.StartNew(*keyTries*2 + *numHosts) 31 32 if *numHosts > *keyTries { 33 println("Can't generate less keys than hosts.") 34 return 35 } 36 37 var keys []keySet 38 for i := 0; i < *numHosts+1; i++ { 39 keys = append(keys, newKey()) 40 bar.Increment() 41 } 42 keys = sortKeySetArray(keys) 43 for i := 0; i < *keyTries-*numHosts-1; i++ { 44 keys[0] = newKey() 45 keys = bubbleUpTo(keys, 0) 46 bar.Increment() 47 } 48 49 os.MkdirAll("host_vars", 0755) 50 51 for i := 1; i <= *numHosts; i++ { 52 os.MkdirAll(fmt.Sprintf("host_vars/%x", i), 0755) 53 file, err := os.Create(fmt.Sprintf("host_vars/%x/vars", i)) 54 if err != nil { 55 return 56 } 57 defer file.Close() 58 file.WriteString(fmt.Sprintf("yggdrasil_public_key: %v\n", hex.EncodeToString(keys[i].pub))) 59 file.WriteString("yggdrasil_private_key: \"{{ vault_yggdrasil_private_key }}\"\n") 60 file.WriteString(fmt.Sprintf("ansible_host: %v\n", keys[i].ip)) 61 62 file, err = os.Create(fmt.Sprintf("host_vars/%x/vault", i)) 63 if err != nil { 64 return 65 } 66 defer file.Close() 67 file.WriteString(fmt.Sprintf("vault_yggdrasil_private_key: %v\n", hex.EncodeToString(keys[i].priv))) 68 bar.Increment() 69 } 70 bar.Finish() 71 } 72 73 func newKey() keySet { 74 pub, priv, err := ed25519.GenerateKey(nil) 75 if err != nil { 76 panic(err) 77 } 78 ip := net.IP(address.AddrForKey(pub)[:]).String() 79 return keySet{priv[:], pub[:], ip} 80 } 81 82 func isBetter(oldID, newID []byte) bool { 83 for idx := range oldID { 84 if newID[idx] < oldID[idx] { 85 return true 86 } 87 if newID[idx] > oldID[idx] { 88 return false 89 } 90 } 91 return false 92 } 93 94 func sortKeySetArray(sets []keySet) []keySet { 95 for i := 0; i < len(sets); i++ { 96 sets = bubbleUpTo(sets, i) 97 } 98 return sets 99 } 100 101 func bubbleUpTo(sets []keySet, num int) []keySet { 102 for i := 0; i < len(sets)-num-1; i++ { 103 if isBetter(sets[i+1].pub, sets[i].pub) { 104 var tmp = sets[i] 105 sets[i] = sets[i+1] 106 sets[i+1] = tmp 107 } else { 108 break 109 } 110 } 111 return sets 112 }