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