Explorar el Código

pkg/k8s/apis: support for preshared keys in peers

This commit adds support for defining preshared keys when declaring a
new Peer CRD. This preshared key will be used whenever the nodes in the
Kilo mesh communicate with that peer.

Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
Lucas Servén Marín hace 6 años
padre
commit
0a10dc921c

+ 6 - 1
cmd/kgctl/showconf.go

@@ -299,6 +299,10 @@ func translatePeer(peer *wireguard.Peer) *v1alpha1.Peer {
 	if len(peer.PublicKey) > 0 {
 		key = string(peer.PublicKey)
 	}
+	var psk string
+	if len(peer.PresharedKey) > 0 {
+		psk = string(peer.PresharedKey)
+	}
 	var pka int
 	if peer.PersistentKeepalive > 0 {
 		pka = peer.PersistentKeepalive
@@ -311,8 +315,9 @@ func translatePeer(peer *wireguard.Peer) *v1alpha1.Peer {
 		Spec: v1alpha1.PeerSpec{
 			AllowedIPs:          aips,
 			Endpoint:            endpoint,
-			PublicKey:           key,
 			PersistentKeepalive: pka,
+			PresharedKey:        psk,
+			PublicKey:           key,
 		},
 	}
 }

+ 8 - 1
pkg/k8s/apis/kilo/v1alpha1/openapi_generated.go

@@ -304,9 +304,16 @@ func schema_k8s_apis_kilo_v1alpha1_PeerSpec(ref common.ReferenceCallback) common
 							Format:      "int32",
 						},
 					},
+					"presharedKey": {
+						SchemaProps: spec.SchemaProps{
+							Description: "PresharedKey is the optional symmetric encryption key for the peer.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
 					"publicKey": {
 						SchemaProps: spec.SchemaProps{
-							Description: "PublicKey is the WireGuard public key for the node.",
+							Description: "PublicKey is the WireGuard public key for the peer.",
 							Type:        []string{"string"},
 							Format:      "",
 						},

+ 4 - 1
pkg/k8s/apis/kilo/v1alpha1/types.go

@@ -72,7 +72,10 @@ type PeerSpec struct {
 	// disables the feature.
 	// +optional
 	PersistentKeepalive int `json:"persistentKeepalive,omitempty"`
-	// PublicKey is the WireGuard public key for the node.
+	// PresharedKey is the optional symmetric encryption key for the peer.
+	// +optional
+	PresharedKey string `json:"presharedKey"`
+	// PublicKey is the WireGuard public key for the peer.
 	PublicKey string `json:"publicKey"`
 }
 

+ 7 - 1
pkg/k8s/backend.go

@@ -336,6 +336,10 @@ func translatePeer(peer *v1alpha1.Peer) *mesh.Peer {
 	if len(peer.Spec.PublicKey) > 0 {
 		key = []byte(peer.Spec.PublicKey)
 	}
+	var psk []byte
+	if len(peer.Spec.PresharedKey) > 0 {
+		psk = []byte(peer.Spec.PresharedKey)
+	}
 	var pka int
 	if peer.Spec.PersistentKeepalive > 0 {
 		pka = peer.Spec.PersistentKeepalive
@@ -345,8 +349,9 @@ func translatePeer(peer *v1alpha1.Peer) *mesh.Peer {
 		Peer: wireguard.Peer{
 			AllowedIPs:          aips,
 			Endpoint:            endpoint,
-			PublicKey:           key,
 			PersistentKeepalive: pka,
+			PresharedKey:        psk,
+			PublicKey:           key,
 		},
 	}
 }
@@ -465,6 +470,7 @@ func (pb *peerBackend) Set(name string, peer *mesh.Peer) error {
 		}
 	}
 	p.Spec.PersistentKeepalive = peer.PersistentKeepalive
+	p.Spec.PresharedKey = string(peer.PresharedKey)
 	p.Spec.PublicKey = string(peer.PublicKey)
 	if _, err = pb.client.KiloV1alpha1().Peers().Update(p); err != nil {
 		return fmt.Errorf("failed to update peer: %v", err)

+ 11 - 0
pkg/k8s/backend_test.go

@@ -299,6 +299,17 @@ func TestTranslatePeer(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "valid preshared key",
+			spec: v1alpha1.PeerSpec{
+				PresharedKey: "psk",
+			},
+			out: &mesh.Peer{
+				Peer: wireguard.Peer{
+					PresharedKey: []byte("psk"),
+				},
+			},
+		},
 	} {
 		p := &v1alpha1.Peer{}
 		p.Spec = tc.spec

+ 1 - 1
pkg/mesh/mesh.go

@@ -821,7 +821,7 @@ func peersAreEqual(a, b *Peer) bool {
 			return false
 		}
 	}
-	return string(a.PublicKey) == string(b.PublicKey) && a.PersistentKeepalive == b.PersistentKeepalive
+	return string(a.PublicKey) == string(b.PublicKey) && string(a.PresharedKey) == string(b.PresharedKey) && a.PersistentKeepalive == b.PersistentKeepalive
 }
 
 func ipNetsEqual(a, b *net.IPNet) bool {

+ 7 - 2
pkg/mesh/topology.go

@@ -366,17 +366,18 @@ func (t *Topology) Conf() *wireguard.Conf {
 		peer := &wireguard.Peer{
 			AllowedIPs:          s.allowedIPs,
 			Endpoint:            s.endpoint,
-			PublicKey:           s.key,
 			PersistentKeepalive: t.persistentKeepalive,
+			PublicKey:           s.key,
 		}
 		c.Peers = append(c.Peers, peer)
 	}
 	for _, p := range t.peers {
 		peer := &wireguard.Peer{
 			AllowedIPs:          p.AllowedIPs,
+			Endpoint:            p.Endpoint,
 			PersistentKeepalive: t.persistentKeepalive,
+			PresharedKey:        p.PresharedKey,
 			PublicKey:           p.PublicKey,
-			Endpoint:            p.Endpoint,
 		}
 		c.Peers = append(c.Peers, peer)
 	}
@@ -402,9 +403,11 @@ func (t *Topology) AsPeer() *wireguard.Peer {
 // PeerConf generates a WireGuard configuration file for a given peer in a Topology.
 func (t *Topology) PeerConf(name string) *wireguard.Conf {
 	var pka int
+	var psk []byte
 	for i := range t.peers {
 		if t.peers[i].Name == name {
 			pka = t.peers[i].PersistentKeepalive
+			psk = t.peers[i].PresharedKey
 			break
 		}
 	}
@@ -414,6 +417,7 @@ func (t *Topology) PeerConf(name string) *wireguard.Conf {
 			AllowedIPs:          s.allowedIPs,
 			Endpoint:            s.endpoint,
 			PersistentKeepalive: pka,
+			PresharedKey:        psk,
 			PublicKey:           s.key,
 		}
 		c.Peers = append(c.Peers, peer)
@@ -502,6 +506,7 @@ func deduplicatePeerIPs(peers []*Peer) []*Peer {
 			Peer: wireguard.Peer{
 				Endpoint:            peer.Endpoint,
 				PersistentKeepalive: peer.PersistentKeepalive,
+				PresharedKey:        peer.PresharedKey,
 				PublicKey:           peer.PublicKey,
 			},
 		}

+ 8 - 1
pkg/wireguard/conf.go

@@ -37,6 +37,7 @@ const (
 	allowedIPsKey          key     = "AllowedIPs"
 	endpointKey            key     = "Endpoint"
 	persistentKeepaliveKey key     = "PersistentKeepalive"
+	presharedKeyKey        key     = "PresharedKey"
 	privateKeyKey          key     = "PrivateKey"
 	publicKeyKey           key     = "PublicKey"
 )
@@ -58,6 +59,7 @@ type Peer struct {
 	AllowedIPs          []*net.IPNet
 	Endpoint            *Endpoint
 	PersistentKeepalive int
+	PresharedKey        []byte
 	PublicKey           []byte
 }
 
@@ -220,6 +222,8 @@ func Parse(buf []byte) *Conf {
 					continue
 				}
 				peer.PersistentKeepalive = i
+			case presharedKeyKey:
+				peer.PresharedKey = []byte(v)
 			case publicKeyKey:
 				peer.PublicKey = []byte(v)
 			}
@@ -269,6 +273,9 @@ func (c *Conf) Bytes() ([]byte, error) {
 		if err = writeValue(buf, persistentKeepaliveKey, strconv.Itoa(p.PersistentKeepalive)); err != nil {
 			return nil, fmt.Errorf("failed to write persistent keepalive: %v", err)
 		}
+		if err = writePKey(buf, presharedKeyKey, p.PresharedKey); err != nil {
+			return nil, fmt.Errorf("failed to write preshared key: %v", err)
+		}
 		if err = writePKey(buf, publicKeyKey, p.PublicKey); err != nil {
 			return nil, fmt.Errorf("failed to write public key: %v", err)
 		}
@@ -318,7 +325,7 @@ func (c *Conf) Equal(b *Conf) bool {
 				return false
 			}
 		}
-		if c.Peers[i].PersistentKeepalive != b.Peers[i].PersistentKeepalive || !bytes.Equal(c.Peers[i].PublicKey, b.Peers[i].PublicKey) {
+		if c.Peers[i].PersistentKeepalive != b.Peers[i].PersistentKeepalive || !bytes.Equal(c.Peers[i].PresharedKey, b.Peers[i].PresharedKey) || !bytes.Equal(c.Peers[i].PublicKey, b.Peers[i].PublicKey) {
 			return false
 		}
 	}

+ 11 - 0
pkg/wireguard/conf_test.go

@@ -39,6 +39,7 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey = key
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),
@@ -49,6 +50,7 @@ func TestCompareConf(t *testing.T) {
 		[Peer]
 		PublicKey = key
 		AllowedIPs = 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32, 10.2.2.0/24
+		PresharedKey = psk
 		Endpoint = 10.1.0.2:51820
 		`),
 			out: true,
@@ -61,6 +63,7 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey = key
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),
@@ -69,6 +72,7 @@ func TestCompareConf(t *testing.T) {
 		ListenPort=51820
 		[Peer]
 		Endpoint=10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey=key
 		AllowedIPs=10.2.2.0/24,192.168.0.1/32,10.2.3.0/24,192.168.0.2/32,10.4.0.2/32
 		`),
@@ -125,11 +129,13 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey = key
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),
 			b: []byte(`[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey = key
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 
@@ -147,11 +153,13 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk2
 		PublicKey = key2
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk1
 		PublicKey = key1
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),
@@ -161,11 +169,13 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk1
 		PublicKey = key1
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk2
 		PublicKey = key2
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),
@@ -179,6 +189,7 @@ func TestCompareConf(t *testing.T) {
 
 		[Peer]
 		Endpoint = 10.1.0.2:51820
+		PresharedKey = psk
 		PublicKey = key
 		AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
 		`),