The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7240

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Fixes https://github.com/lxc/lxd/issues/7221

- Prevents using wildcard listen address in NAT mode.
- Prevents using proxy_protocol in NAT mode.
- Prevents mixing IP version addresses in NAT mode.
From b1ce57fa647512765633c81313d5f03694c533d4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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
 }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to