Add a new integration test suite checking network behaviors#45850
Add a new integration test suite checking network behaviors#45850akerouanton wants to merge 9 commits intomoby:masterfrom
Conversation
9dbbec0 to
a477f71
Compare
corhere
left a comment
There was a problem hiding this comment.
I would like to see the libnetwork testutils package moved under libnetwork/internal/ so we don't have to worry about some third party importing it.
We can't move testutils into
|
59b4203 to
0fc8c2d
Compare
8bdf860 to
b26b1ce
Compare
Fine, |
c20dadf to
b28358c
Compare
This commit introduces a new integration test suite aimed at testing networking features like inter-container communication, network isolation, port mapping, etc... and how they interact with daemon-level and network-level parameters. So far, there's pretty much no tests making sure our networks are well configured: 1. there're a few tests for port mapping, but they don't cover all use cases ; 2. there're a few tests that check if a specific iptables rule exist, but that doesn't prevent that specific iptables rule to be wrong in the first place. As we're planning to refactor how iptables rules are written, and change some of them to fix known security issues, we need a way to test all combinations of parameters. So far, this was done by hand, which is particularly painful and time consuming. As such, this new test suite is foundational to upcoming work. Following tests are implemented in this specific commit: - Inter-container communications for internal and non-internal bridge networks, over IPv4 and IPv6. - Inter-container communications using IPv6 link-local addresses for internal and non-internal bridge networks. - Inter-network communications for internal and non-internal bridge networks, over IPv4 and IPv6, are disallowed. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit adds a test to the new networking test suite that makes sure we can connect to ports published on local host, from loopback address or another local address. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
903a916 to
593ec82
Compare
These tests use a SYN prober to check whether mapped ports are reachable when they should not. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The tests introduced in "integration: Test port mapping security" check victim hosts don't send a SYN-ACK when it should not to. This could happen for two reasons: 1. because the right security measures are effectively dropping the SYN packet ; or 2. because the SYN packet was never received by the victim host. The latter case could be a potential source of false positives, which are pretty bad since we're testing security features. To alleviate this risk, this commit adds the ability to capture packets on the victim's host interface and leverage that to make sure the SYN packet is well received. If it's not, the test fails. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
593ec82 to
397b812
Compare
thaJeztah
left a comment
There was a problem hiding this comment.
Just some comments after making a first pass / glance over the changes 😅
| type RunResult struct { | ||
| ContainerID string | ||
| ExitCode int | ||
| Stdout *bytes.Buffer | ||
| Stderr *bytes.Buffer | ||
| } |
There was a problem hiding this comment.
Starting to think if we could use icmd.Result for these, but it looks like it would need some contributing to upstream because the outBuffer and errBuffer are not exported.
Could be nice though to use that type for this as well 🤔
moby/vendor/gotest.tools/v3/icmd/command.go
Lines 43 to 52 in 7baab8b
I think some of this code also shows that we need to improve some of the client to not having to write utilities like this (e.g. the demultiplexing). Perhaps something to work on (separately) to move code from the CLI, and/or provide better utilities in the client code 🤔
There was a problem hiding this comment.
I disagree on all counts.
Starting to think if we could use
icmd.Resultfor these
While there are a lot of similarities, this is not the result of an *exec.Cmd run. The gotest.tools module is Apache2 licensed so there's nothing preventing us from copying that code and modifying it to fit the needs of asserting on the result of attaching to a container or running an exec.
I think some of this code also shows that we need to improve some of the client to not having to write utilities like this (e.g. the demultiplexing).
Demultiplex into what? Buffering the whole demuxed output into an in-memory buffer is rarely the right thing to do in general as the output of an arbitrary command may be unbounded. We shouldn't provide utilities in the client code which make it easier to do the wrong thing than to do the right thing. By only providing stdcopy the consumer of the client is forced to choose which io.Writer to demux the streams into, giving them the opportunity to consider which choice would best fit their use case.
| if err != nil && !os.IsNotExist(err) { | ||
| assert.NilError(t, err) | ||
| } |
There was a problem hiding this comment.
Does this assert actually do anything? It would always be a non-nil error? Should this be a t.Fatal(err)?
| if err == nil { | ||
| if reusePrevious { | ||
| return newNs | ||
| } | ||
| t.Fatalf("Network namespace %s already exists whereas TEST_REUSE_L2SEGMENT is empty.", newNs.name) | ||
| } |
There was a problem hiding this comment.
This part is a bit confusing ... no error, and producing a t.Fatal() 🤔
| if err := netns.Set(orig.handle); err != nil { | ||
| t.Fatalf("could not switch back to the original netns: %v", err) | ||
| } | ||
| runtime.UnlockOSThread() |
There was a problem hiding this comment.
It's ok to skip the runtime.UnlockOSThread() if we fail? (I guess it is if we os.Exit()
There was a problem hiding this comment.
Not only is it okay, it's mandatory. See #45850 (comment)
| if err := syscall.Unmount(ns.Path(), 0); err != nil { | ||
| logger.Logf("failed to unmount netns %s: %v", ns, err) | ||
| } | ||
| if err := os.Remove(ns.Path()); err != nil { | ||
| logger.Logf("failed to remove netns mountpoint %s: %v", ns, err) | ||
| } |
There was a problem hiding this comment.
Just double checking; we should remove the path even if we failed to unmount?
| } | ||
|
|
||
| daddr := &packet.Addr{HardwareAddr: p.DstMAC} | ||
| fmt.Printf("Sending Ethernet frame to %s (%d bytes).\n%s\n", daddr.String(), len(buf.Bytes()), hex.Dump(buf.Bytes())) |
There was a problem hiding this comment.
Wondering if we need a context passed so allow us to past a test-logger (instead of fmt.Printf 🤔
corhere
left a comment
There was a problem hiding this comment.
Please break this up into smaller PRs; this is way too much to review at once.
| if t.Failed() { | ||
| t.Logf("Logs from %s:\n%s", ctr2Name, logs) | ||
| } |
There was a problem hiding this comment.
The test runner is perfectly capable of suppressing log output on passing tests. All you're doing by making this log conditional is breaking the -test.v flag. Don't break the -test.v flag.
| if err := netns.Set(orig.handle); err != nil { | ||
| t.Fatalf("could not switch back to the original netns: %v", err) | ||
| } | ||
| runtime.UnlockOSThread() |
There was a problem hiding this comment.
Not only is it okay, it's mandatory. See #45850 (comment)
| type RunResult struct { | ||
| ContainerID string | ||
| ExitCode int | ||
| Stdout *bytes.Buffer | ||
| Stderr *bytes.Buffer | ||
| } |
There was a problem hiding this comment.
I disagree on all counts.
Starting to think if we could use
icmd.Resultfor these
While there are a lot of similarities, this is not the result of an *exec.Cmd run. The gotest.tools module is Apache2 licensed so there's nothing preventing us from copying that code and modifying it to fit the needs of asserting on the result of attaching to a container or running an exec.
I think some of this code also shows that we need to improve some of the client to not having to write utilities like this (e.g. the demultiplexing).
Demultiplex into what? Buffering the whole demuxed output into an in-memory buffer is rarely the right thing to do in general as the output of an arbitrary command may be unbounded. We shouldn't provide utilities in the client code which make it easier to do the wrong thing than to do the right thing. By only providing stdcopy the consumer of the client is forced to choose which io.Writer to demux the streams into, giving them the opportunity to consider which choice would best fit their use case.
|
A similar Most / all the test cases in this PR should be covered by newer tests, so let me close it. |
- What I did
This PR introduces a new integration test suite aimed at testing networking features like inter-container communication, network isolation, port mapping, what happens when the userland proxy is enabled or disabled, etc... and how these features interact with daemon-level and network-level parameters.
So far, there's pretty much no tests making sure our networks are working as expected. For instance, there's a few tests for port mapping, but they don't cover all cases (eg. like IPv6, disabling the userland proxy, etc...); 2. there're a few tests that check if a specific iptables rule exists, but that doesn't prevent that specific rule from be wrong in the first place.
As we're planning to refactor how iptables rules are written and change some of them to fix known security issues, we need a way to test all parameter combinations (at least, the important ones). So far, this was done by hand which is a particularly painful and time consuming experience. As such, this new test suite is foundational to upcoming work.
This test suite should help:
Following tests are implemented in this PR:
I plan to write some more tests in the near future (eg. for CVE-2020-13401).
- How to verify it
CI is green.
- A picture of a cute animal (not mandatory but encouraged)