[lxc-devel] [lxd/master] Proxy: Improves validation
tomponline on Github
lxc-bot at linuxcontainers.org
Wed Apr 22 13:39:21 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 501 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200422/c32f508d/attachment.bin>
-------------- next part --------------
From b1ce57fa647512765633c81313d5f03694c533d4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 22 Apr 2020 13:46:43 +0100
Subject: [PATCH 1/4] lxd/device/proxy: Dont allow proxy_protocol to be set
when in nat mode
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/proxy.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lxd/device/proxy.go b/lxd/device/proxy.go
index 4e25213b58..94ba00d614 100644
--- a/lxd/device/proxy.go
+++ b/lxd/device/proxy.go
@@ -96,8 +96,8 @@ func (d *proxy) validateConfig(instConf instance.ConfigReader) error {
return fmt.Errorf("Cannot map a single port to multiple ports")
}
- if shared.IsTrue(d.config["proxy_protocol"]) && !strings.HasPrefix(d.config["connect"], "tcp") {
- return fmt.Errorf("The PROXY header can only be sent to tcp servers")
+ if shared.IsTrue(d.config["proxy_protocol"]) && (!strings.HasPrefix(d.config["connect"], "tcp") || shared.IsTrue(d.config["nat"])) {
+ return fmt.Errorf("The PROXY header can only be sent to tcp servers in non-nat mode")
}
if (!strings.HasPrefix(d.config["listen"], "unix:") || strings.HasPrefix(d.config["listen"], "unix:@")) &&
From c9ba14de5f5f858ace3114b007551bf1c3082b94 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 22 Apr 2020 13:53:02 +0100
Subject: [PATCH 2/4] lxd/device/proxy: Dont wrap lines
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/proxy.go | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lxd/device/proxy.go b/lxd/device/proxy.go
index 94ba00d614..5ebf13845a 100644
--- a/lxd/device/proxy.go
+++ b/lxd/device/proxy.go
@@ -111,10 +111,8 @@ func (d *proxy) validateConfig(instConf instance.ConfigReader) error {
}
// Support TCP <-> TCP and UDP <-> UDP
- if listenAddr.ConnType == "unix" || connectAddr.ConnType == "unix" ||
- listenAddr.ConnType != connectAddr.ConnType {
- return fmt.Errorf("Proxying %s <-> %s is not supported when using NAT",
- listenAddr.ConnType, connectAddr.ConnType)
+ if listenAddr.ConnType == "unix" || connectAddr.ConnType == "unix" || listenAddr.ConnType != connectAddr.ConnType {
+ return fmt.Errorf("Proxying %s <-> %s is not supported when using NAT", listenAddr.ConnType, connectAddr.ConnType)
}
}
From 9ea65ca58f29f2fef8bf5d5b10b8dc777a2ddb58 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 22 Apr 2020 14:24:58 +0100
Subject: [PATCH 3/4] lxd/device/proxy: Improves validation
Prevents listening on wildcard addresses in NAT mode.
Prevents mixing different IP version addresses in listen and connect in NAT mode.
Fixes #7221
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/proxy.go | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/lxd/device/proxy.go b/lxd/device/proxy.go
index 5ebf13845a..0351c43100 100644
--- a/lxd/device/proxy.go
+++ b/lxd/device/proxy.go
@@ -114,6 +114,43 @@ func (d *proxy) validateConfig(instConf instance.ConfigReader) error {
if listenAddr.ConnType == "unix" || connectAddr.ConnType == "unix" || listenAddr.ConnType != connectAddr.ConnType {
return fmt.Errorf("Proxying %s <-> %s is not supported when using NAT", listenAddr.ConnType, connectAddr.ConnType)
}
+
+ var ipVersion uint // Records which IP version we are using, as these cannot be mixed in NAT mode.
+
+ for _, listenAddrStr := range listenAddr.Addr {
+ ipStr, _, err := net.SplitHostPort(listenAddrStr)
+ if err != nil {
+ return err
+ }
+
+ ip := net.ParseIP(ipStr)
+
+ if ip.Equal(net.IPv4zero) || ip.Equal(net.IPv6zero) {
+ return fmt.Errorf("Cannot listen on wildcard address %q when in nat mode", ip)
+ }
+
+ // Record the listen IP version if not record already.
+ if ipVersion == 0 {
+ if ip.To4() == nil {
+ ipVersion = 6
+ } else {
+ ipVersion = 4
+ }
+ }
+ }
+
+ // Check each connect address against the listen IP version and check they match.
+ for _, connectAddrStr := range connectAddr.Addr {
+ ipStr, _, err := net.SplitHostPort(connectAddrStr)
+ if err != nil {
+ return err
+ }
+
+ ipTo4 := net.ParseIP(ipStr).To4()
+ if ipTo4 == nil && ipVersion != 6 || ipTo4 != nil && ipVersion != 4 {
+ return fmt.Errorf("Cannot mix IP versions between listen and connect in nat mode")
+ }
+ }
}
return nil
From 8d093b1442d7214656c8590476587e3a720637e8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 22 Apr 2020 14:37:51 +0100
Subject: [PATCH 4/4] test/suites/container/devices/proxy: Updates tests with
new validation rules
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
test/suites/container_devices_proxy.sh | 27 ++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/test/suites/container_devices_proxy.sh b/test/suites/container_devices_proxy.sh
index 0b8eed5c5f..c71e2d1e7f 100644
--- a/test/suites/container_devices_proxy.sh
+++ b/test/suites/container_devices_proxy.sh
@@ -21,6 +21,32 @@ container_devices_proxy_validation() {
false
fi
+ # Check using wildcard addresses isn't allowed in NAT mode.
+ if lxc config device add proxyTester proxyDev proxy "listen=tcp:0.0.0.0:$HOST_TCP_PORT" connect=tcp:0.0.0.0:4321 nat=true ; then
+ echo "Proxy device shouldn't allow wildcard IPv4 listen addresses in NAT mode"
+ false
+ fi
+ if lxc config device add proxyTester proxyDev proxy "listen=tcp:[::]:$HOST_TCP_PORT" connect=tcp:0.0.0.0:4321 nat=true ; then
+ echo "Proxy device shouldn't allow wildcard IPv6 listen addresses in NAT mode"
+ false
+ fi
+
+ # Check using mixing IP versions in listen/connect addresses isn't allowed in NAT mode.
+ if lxc config device add proxyTester proxyDev proxy "listen=tcp:127.0.0.1:$HOST_TCP_PORT" connect=tcp:[::]:4321 nat=true ; then
+ echo "Proxy device shouldn't allow mixing IP address versions in NAT mode"
+ false
+ fi
+ if lxc config device add proxyTester proxyDev proxy "listen=tcp:[::1]:$HOST_TCP_PORT" connect=tcp:0.0.0.0:4321 nat=true ; then
+ echo "Proxy device shouldn't allow mixing IP address versions in NAT mode"
+ false
+ fi
+
+ # Check user proxy_protocol isn't allowed in NAT mode.
+ if lxc config device add proxyTester proxyDev proxy "listen=tcp:[::1]:$HOST_TCP_PORT" connect=tcp:[::]:4321 nat=true proxy_protocol=true ; then
+ echo "Proxy device shouldn't allow proxy_protocol in NAT mode"
+ false
+ fi
+
# Check that old invalid config doesn't prevent device being stopped and removed cleanly.
lxc config device add proxyTester proxyDev proxy "listen=tcp:127.0.0.1:$HOST_TCP_PORT" connect=tcp:127.0.0.1:4321 bind=host
lxd sql global "UPDATE instances_devices_config SET value='tcp:localhost:4321' WHERE value='tcp:127.0.0.1:4321';"
@@ -29,6 +55,7 @@ container_devices_proxy_validation() {
# Add the device again with the same listen param so if the old process hasn't been stopped it will fail to start.
lxc config device add proxyTester proxyDev proxy "listen=tcp:127.0.0.1:$HOST_TCP_PORT" connect=tcp:127.0.0.1:4321 bind=host
+
lxc delete -f proxyTester
}
More information about the lxc-devel
mailing list