[lxc-devel] [lxd/master] NIC Bridged: Allow use of security.ipv6_filtering when no IPv6 allocation available

tomponline on Github lxc-bot at linuxcontainers.org
Fri Mar 27 10:04:39 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200327/c5b1bcdb/attachment.bin>
-------------- next part --------------
From c345988eca772a976ddd2d3a22807bfbd628609e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 27 Mar 2020 10:00:41 +0000
Subject: [PATCH 1/3] lxd/firewall/drivers/drivers/consts: Adds FilterIPv6All
 constant

Indicator for allowing all IPv6 traffic to be blocked.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/firewall/drivers/drivers_consts.go | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 lxd/firewall/drivers/drivers_consts.go

diff --git a/lxd/firewall/drivers/drivers_consts.go b/lxd/firewall/drivers/drivers_consts.go
new file mode 100644
index 0000000000..aecb2c0ca8
--- /dev/null
+++ b/lxd/firewall/drivers/drivers_consts.go
@@ -0,0 +1,4 @@
+package drivers
+
+// FilterIPv6All used to indicate to firewall package to filter all IPv6 traffic.
+const FilterIPv6All = "::"

From 5dbcb040e00566b7ac82c5ec76be8ab7c184e15e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 27 Mar 2020 10:02:08 +0000
Subject: [PATCH 2/3] lxd/device/nic/bridged: Allow security.ipv6_filtering to
 be used on networks without IPv6

If no static or dynamic IPv6 addresses are available to the instance, with security.ipv6_filtering=true, all IPv6 traffic will be blocked.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/device/nic_bridged.go | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index fde4ba269c..a72fd13053 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -21,6 +21,7 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	deviceConfig "github.com/lxc/lxd/lxd/device/config"
 	"github.com/lxc/lxd/lxd/dnsmasq"
+	firewallDrivers "github.com/lxc/lxd/lxd/firewall/drivers"
 	"github.com/lxc/lxd/lxd/instance"
 	"github.com/lxc/lxd/lxd/instance/instancetype"
 	"github.com/lxc/lxd/lxd/network"
@@ -475,6 +476,11 @@ func (d *nicBridged) removeFilters(m deviceConfig.Device) {
 		IPv6 = net.ParseIP(m["ipv6.address"])
 	}
 
+	// If no static IPv6 assigned, try removing the filter all rule in case it was setup.
+	if IPv6 == nil {
+		IPv6 = net.ParseIP(firewallDrivers.FilterIPv6All)
+	}
+
 	// Remove filters for static MAC and IPs (if specified above).
 	// This covers the case when filtering is used with an unmanaged bridge.
 	err := d.state.Firewall.InstanceClearBridgeFilter(d.inst.Project(), d.inst.Name(), d.name, m["parent"], m["host_name"], m["hwaddr"], IPv4, IPv6)
@@ -570,8 +576,9 @@ func (d *nicBridged) setFilters() (err error) {
 		IPv4 = nil
 	}
 
-	if !shared.IsTrue(d.config["security.ipv6_filtering"]) {
-		IPv6 = nil
+	// If no allocated IPv6 address for filtering and filtering enabled, then block all IPv6 traffic.
+	if shared.IsTrue(d.config["security.ipv6_filtering"]) && IPv6 == nil {
+		IPv6 = net.ParseIP(firewallDrivers.FilterIPv6All)
 	}
 
 	return d.state.Firewall.InstanceSetupBridgeFilter(d.inst.Project(), d.inst.Name(), d.name, d.config["parent"], d.config["host_name"], d.config["hwaddr"], IPv4, IPv6)
@@ -612,7 +619,7 @@ func (d *nicBridged) allocateFilterIPs(n *network.Network) (net.IP, net.IP, erro
 
 	// Check DHCPv6 is enabled on parent if dynamic IPv6 allocation is needed.
 	if shared.IsTrue(d.config["security.ipv6_filtering"]) && IPv6 == nil && !canIPv6Allocate {
-		return nil, nil, fmt.Errorf("Cannot use security.ipv6_filtering as DHCPv6 is disabled or no IPv6 on parent %s and no static IPv6 address set", d.config["parent"])
+		logger.Warnf("IPv6 filtering enabled on %q device %q without a static IPv6 specified or dynamic allocation enabled, all IPv6 traffic will be blocked", d.inst.Name(), d.name)
 	}
 
 	dnsmasq.ConfigMutex.Lock()

From 7d8ad23340154069e7a78dc7e27ba3baae609e2b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 27 Mar 2020 10:03:07 +0000
Subject: [PATCH 3/3] lxd/firewall/drivers/drivers/xtables: Adds FilterIPv6All
 support

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/firewall/drivers/drivers_xtables.go | 26 +++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/lxd/firewall/drivers/drivers_xtables.go b/lxd/firewall/drivers/drivers_xtables.go
index dd7ff16635..7cdad1259c 100644
--- a/lxd/firewall/drivers/drivers_xtables.go
+++ b/lxd/firewall/drivers/drivers_xtables.go
@@ -450,14 +450,24 @@ func (d Xtables) generateFilterEbtablesRules(hostName, hwAddr string, IPv4, IPv6
 	}
 
 	if IPv6 != nil {
-		rules = append(rules,
-			// Allow DHCPv6 and Router Solicitation to the host only. This must come before the IP source filtering rules below.
-			[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-s", hwAddr, "-i", hostName, "--ip6-src", "fe80::/ffc0::", "--ip6-dst", "ff02::1:2/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "--ip6-proto", "udp", "--ip6-dport", "547", "-j", "ACCEPT"},
-			[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-s", hwAddr, "-i", hostName, "--ip6-src", "fe80::/ffc0::", "--ip6-dst", "ff02::2/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "--ip6-proto", "ipv6-icmp", "--ip6-icmp-type", "router-solicitation", "-j", "ACCEPT"},
-			// IP source filtering rules. Blocks any packet coming from instance with an incorrect IP source address.
-			[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-i", hostName, "--ip6-src", "!", fmt.Sprintf("%s/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", IPv6.String()), "-j", "DROP"},
-			[]string{"ebtables", "-t", "filter", "-A", "FORWARD", "-p", "IPv6", "-i", hostName, "--ip6-src", "!", fmt.Sprintf("%s/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", IPv6.String()), "-j", "DROP"},
-		)
+		if IPv6.String() == FilterIPv6All {
+			rules = append(rules,
+				[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-i", hostName, "-j", "DROP"},
+				[]string{"ebtables", "-t", "filter", "-A", "FORWARD", "-p", "IPv6", "-i", hostName, "-j", "DROP"},
+			)
+		} else {
+			rules = append(rules,
+				// Allow DHCPv6 and Router Solicitation to the host only. This must come before the IP source filtering rules below.
+				[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-s", hwAddr, "-i", hostName, "--ip6-src", "fe80::/ffc0::", "--ip6-dst", "ff02::1:2/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "--ip6-proto", "udp", "--ip6-dport", "547", "-j", "ACCEPT"},
+				[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-s", hwAddr, "-i", hostName, "--ip6-src", "fe80::/ffc0::", "--ip6-dst", "ff02::2/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "--ip6-proto", "ipv6-icmp", "--ip6-icmp-type", "router-solicitation", "-j", "ACCEPT"},
+				// IP source filtering rules. Blocks any packet coming from instance with an incorrect IP source address.
+				[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-i", hostName, "--ip6-src", "!", fmt.Sprintf("%s/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", IPv6.String()), "-j", "DROP"},
+				[]string{"ebtables", "-t", "filter", "-A", "FORWARD", "-p", "IPv6", "-i", hostName, "--ip6-src", "!", fmt.Sprintf("%s/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", IPv6.String()), "-j", "DROP"},
+				// Block any IPv6 router advertisement packets from instance.
+				[]string{"ebtables", "-t", "filter", "-A", "INPUT", "-p", "IPv6", "-i", hostName, "--ip6-proto", "ipv6-icmp", "--ip6-icmp-type", "router-advertisement", "-j", "DROP"},
+				[]string{"ebtables", "-t", "filter", "-A", "FORWARD", "-p", "IPv6", "-i", hostName, "--ip6-proto", "ipv6-icmp", "--ip6-icmp-type", "router-advertisement", "-j", "DROP"},
+			)
+		}
 	}
 
 	return rules


More information about the lxc-devel mailing list