Skip to content

Commit

Permalink
Fixed some issues regarding ExternalCIDR traffic
Browse files Browse the repository at this point in the history
This PR adds ExternalCIDR network to WireGuard configuration (allowedIPs, the networks allowed to enter into a wg tunnel) and modifies the iptables module to allow the traffic toward ExternalCIDR of a remote cluster to correctly trigger the right SNAT rule.
  • Loading branch information
davidefalcone1 committed Jun 28, 2021
1 parent 383ceee commit cb610cb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 55 deletions.
5 changes: 3 additions & 2 deletions pkg/liqonet/iptables/iptables.go
Expand Up @@ -707,7 +707,7 @@ func getChainRulesPerCluster(tep *netv1alpha1.TunnelEndpoint) (map[string][]IPTa
}
clusterID := tep.Spec.ClusterID
localRemappedPodCIDR, remotePodCIDR := utils.GetPodCIDRS(tep)
localRemappedExternalCIDR, _ := utils.GetExternalCIDRS(tep)
localRemappedExternalCIDR, remoteExternalCIDR := utils.GetExternalCIDRS(tep)

// Init chain rules
chainRules := make(map[string][]IPTableRule)
Expand All @@ -719,7 +719,8 @@ func getChainRulesPerCluster(tep *netv1alpha1.TunnelEndpoint) (map[string][]IPTa
// For these rules, source in not necessary since
// the remotePodCIDR is unique in home cluster
chainRules[liqonetPostroutingChain] = append(chainRules[liqonetPostroutingChain],
IPTableRule{"-d", remotePodCIDR, "-j", getClusterPostRoutingChain(clusterID)})
IPTableRule{"-d", remotePodCIDR, "-j", getClusterPostRoutingChain(clusterID)},
IPTableRule{"-d", remoteExternalCIDR, "-j", getClusterPostRoutingChain(clusterID)})
chainRules[liqonetInputChain] = append(chainRules[liqonetInputChain],
IPTableRule{"-d", remotePodCIDR, "-j", getClusterInputChain(clusterID)})
chainRules[liqonetForwardingChain] = append(chainRules[liqonetForwardingChain],
Expand Down
55 changes: 17 additions & 38 deletions pkg/liqonet/iptables/iptables_test.go
Expand Up @@ -149,13 +149,15 @@ var _ = Describe("iptables", func() {

// Check existence of rule in LIQO-POSTROUTING chain
postRoutingRules, err := h.ListRulesInChain(liqonetPostroutingChain)
expectedRule := fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID))
Expect(expectedRule).To(Equal(postRoutingRules[0]))
expectedRules := []string{
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID)),
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATExternalCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID))}
Expect(postRoutingRules).To(ContainElements(expectedRules))

// Check existence of rules in LIQO-PREROUTING chain
// Rule for NAT-ting the PodCIDR should not be present
preRoutingRules, err := h.ListRulesInChain(liqonetPreroutingChain)
expectedRule = fmt.Sprintf("-s %s -d %s -j %s", tep.Status.RemoteNATPodCIDR, tep.Status.LocalNATExternalCIDR,
expectedRule := fmt.Sprintf("-s %s -d %s -j %s", tep.Status.RemoteNATPodCIDR, tep.Status.LocalNATExternalCIDR,
getClusterPreRoutingMappingChain(tep.Spec.ClusterID))
Expect(expectedRule).To(Equal(preRoutingRules[0]))

Expand All @@ -180,12 +182,14 @@ var _ = Describe("iptables", func() {

// Check existence of rule in LIQO-PREROUTING chain
postRoutingRules, err := h.ListRulesInChain(liqonetPostroutingChain)
expectedRule := fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID))
Expect(expectedRule).To(Equal(postRoutingRules[0]))
expectedRules := []string{
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID)),
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATExternalCIDR, getClusterPostRoutingChain(tep.Spec.ClusterID))}
Expect(postRoutingRules).To(ContainElements(expectedRules))

// Check existence of rule in LIQO-FORWARD chain
forwardRules, err := h.ListRulesInChain(liqonetForwardingChain)
expectedRule = fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterForwardChain(tep.Spec.ClusterID))
expectedRule := fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, getClusterForwardChain(tep.Spec.ClusterID))
Expect(expectedRule).To(Equal(forwardRules[0]))

// Check existence of rule in LIQO-INPUT chain
Expand All @@ -195,7 +199,7 @@ var _ = Describe("iptables", func() {

// Check existence of rule in LIQO-PREROUTING chain
preRoutingRules, err := h.ListRulesInChain(liqonetPreroutingChain)
expectedRules := []string{
expectedRules = []string{
fmt.Sprintf("-s %s -d %s -j %s", tep.Status.RemoteNATPodCIDR,
tep.Status.LocalNATPodCIDR, getClusterPreRoutingChain(tep.Spec.ClusterID)),
fmt.Sprintf("-s %s -d %s -j %s", tep.Status.RemoteNATPodCIDR, tep.Status.LocalNATExternalCIDR,
Expand Down Expand Up @@ -267,37 +271,12 @@ var _ = Describe("iptables", func() {
Expect(err).To(BeNil())
newPostRoutingRules, err := h.ListRulesInChain(liqonetPostroutingChain)

// Check if new rule has been added.
expectedRule := fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, clusterPostRoutingChain)
Expect(expectedRule).To(Equal(newPostRoutingRules[0]))

// Check if outdated rule has been removed
Expect(newPostRoutingRules).ToNot(ContainElement(outdatedRule))
})
})

Context("If there are already some rules in chains but they are not in new rules", func() {
It(`should remove existing rules that are not in the set of new rules and add new rules`, func() {
err := h.EnsureChainRulesPerCluster(tep)
Expect(err).To(BeNil())

clusterPostRoutingChain := strings.Join([]string{liqonetPostroutingClusterChainPrefix, strings.Split(tep.Spec.ClusterID, "-")[0]}, "")

// Get rule that will be removed
postRoutingRules, err := h.ListRulesInChain(liqonetPostroutingChain)
outdatedRule := postRoutingRules[0]

// Modify resource
tep.Status.RemoteNATPodCIDR = remoteNATPodCIDRValue

// Second call
err = h.EnsureChainRulesPerCluster(tep)
Expect(err).To(BeNil())
newPostRoutingRules, err := h.ListRulesInChain(liqonetPostroutingChain)

// Check if new rule has been added.
expectedRule := fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, clusterPostRoutingChain)
Expect(expectedRule).To(Equal(newPostRoutingRules[0]))
// Check if new rules has been added.
expectedRules := []string{
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATPodCIDR, clusterPostRoutingChain),
fmt.Sprintf("-d %s -j %s", tep.Status.RemoteNATExternalCIDR, clusterPostRoutingChain),
}
Expect(newPostRoutingRules).To(ContainElements(expectedRules))

// Check if outdated rule has been removed
Expect(newPostRoutingRules).ToNot(ContainElement(outdatedRule))
Expand Down
33 changes: 18 additions & 15 deletions pkg/liqonet/tunnel/wireguard/driver.go
Expand Up @@ -24,6 +24,7 @@ import (

netv1alpha1 "github.com/liqotech/liqo/apis/net/v1alpha1"
"github.com/liqotech/liqo/pkg/liqonet/tunnel"
"github.com/liqotech/liqo/pkg/liqonet/utils"
)

const (
Expand Down Expand Up @@ -144,7 +145,7 @@ func (w *Wireguard) Init() error {
// ConnectToEndpoint connects to a remote cluster described by the given tep.
func (w *Wireguard) ConnectToEndpoint(tep *netv1alpha1.TunnelEndpoint) (*netv1alpha1.Connection, error) {
// parse allowed IPs.
allowedIPs, err := getAllowedIPs(tep)
allowedIPs, stringAllowedIPs, err := getAllowedIPs(tep)
if err != nil {
return newConnectionOnError(err.Error()), err
}
Expand All @@ -165,7 +166,7 @@ func (w *Wireguard) ConnectToEndpoint(tep *netv1alpha1.TunnelEndpoint) (*netv1al
oldCon, found := w.connections[tep.Spec.ClusterID]
if found {
// check if the peer configuration is updated.
if allowedIPs.String() == oldCon.PeerConfiguration[AllowedIPs] && remoteKey.String() == oldCon.PeerConfiguration[PublicKey] &&
if stringAllowedIPs == oldCon.PeerConfiguration[AllowedIPs] && remoteKey.String() == oldCon.PeerConfiguration[PublicKey] &&
endpoint.IP.String() == oldCon.PeerConfiguration[EndpointIP] && strconv.Itoa(endpoint.Port) == oldCon.PeerConfiguration[ListeningPort] {
return oldCon, nil
}
Expand Down Expand Up @@ -193,7 +194,7 @@ func (w *Wireguard) ConnectToEndpoint(tep *netv1alpha1.TunnelEndpoint) (*netv1al
Endpoint: endpoint,
PersistentKeepaliveInterval: &ka,
ReplaceAllowedIPs: true,
AllowedIPs: []net.IPNet{*allowedIPs},
AllowedIPs: allowedIPs,
}}

err = w.client.ConfigureDevice(DeviceName, wgtypes.Config{
Expand All @@ -208,7 +209,7 @@ func (w *Wireguard) ConnectToEndpoint(tep *netv1alpha1.TunnelEndpoint) (*netv1al
Status: netv1alpha1.Connected,
StatusMessage: "Cluster peer connected",
PeerConfiguration: map[string]string{ListeningPort: strconv.Itoa(endpoint.Port), EndpointIP: endpoint.IP.String(),
AllowedIPs: allowedIPs.String(), PublicKey: remoteKey.String()},
AllowedIPs: stringAllowedIPs, PublicKey: remoteKey.String()},
}
w.connections[tep.Spec.ClusterID] = c
klog.V(4).Infof("Done connecting cluster peer %s@%s", tep.Spec.ClusterID, endpoint.String())
Expand Down Expand Up @@ -314,20 +315,22 @@ func (w *Wireguard) setWGLink() error {
return nil
}

func getAllowedIPs(tep *netv1alpha1.TunnelEndpoint) (*net.IPNet, error) {
var remoteSubnet string
// check if the remote podCIDR has been remapped.
if tep.Status.RemoteNATPodCIDR != "None" {
remoteSubnet = tep.Status.RemoteNATPodCIDR
} else {
remoteSubnet = tep.Spec.PodCIDR
}
// Function that receives a TunnelEndpoint resource and extracts
// wireguard allowedIPs. They are returned as []net.IPNet and
// as a string (to accommodate comparison/storing on TEP resource).
func getAllowedIPs(tep *netv1alpha1.TunnelEndpoint) ([]net.IPNet, string, error) {
_, remotePodCIDR := utils.GetPodCIDRS(tep)
_, remoteExternalCIDR := utils.GetExternalCIDRS(tep)

_, cidr, err := net.ParseCIDR(remoteSubnet)
_, podCIDR, err := net.ParseCIDR(remotePodCIDR)
if err != nil {
return nil, "", fmt.Errorf("unable to parse podCIDR %s for cluster %s: %w", remotePodCIDR, tep.Spec.ClusterID, err)
}
_, externalCIDR, err := net.ParseCIDR(remoteExternalCIDR)
if err != nil {
return nil, fmt.Errorf("unable to parse podCIDR %s for cluster %s: %w", remoteSubnet, tep.Spec.ClusterID, err)
return nil, "", fmt.Errorf("unable to parse externalCIDR %s for cluster %s: %w", remoteExternalCIDR, tep.Spec.ClusterID, err)
}
return cidr, nil
return []net.IPNet{*podCIDR, *externalCIDR}, fmt.Sprintf("%s,%s", remotePodCIDR, remoteExternalCIDR), nil
}

func getKey(tep *netv1alpha1.TunnelEndpoint) (*wgtypes.Key, error) {
Expand Down

0 comments on commit cb610cb

Please sign in to comment.