forked from moby/moby
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Some configuration in a container depends on whether it has support for IPv6 (including default entries for '::1' etc in '/etc/hosts'). Before this change, the container's support for IPv6 was determined by whether it was connected to any IPv6-enabled networks. But, that can change over time, it isn't a property of the container itself. So, instead, detect IPv6 support by looking for '::1' on the container's loopback interface. It will not be present if the kernel does not have IPv6 support, or the user has disabled it in new namespaces by other means. Once IPv6 support has been determined for the container, its '/etc/hosts' is re-generated accordingly. The daemon no longer disables IPv6 on all interfaces during initialisation. It now disables IPv6 only for interfaces that have not been assigned an IPv6 address. (But, even if IPv6 is disabled for the container using the sysctl 'net.ipv6.conf.all.disable_ipv6=1', interfaces connected to IPv6 networks still get IPv6 addresses that appear in the internal DNS. There's more to-do!) Signed-off-by: Rob Murray <rob.murray@docker.com>
- Loading branch information
Showing
11 changed files
with
330 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package networking | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
containertypes "github.com/docker/docker/api/types/container" | ||
"github.com/docker/docker/integration/internal/container" | ||
"github.com/docker/docker/testutil" | ||
"github.com/docker/docker/testutil/daemon" | ||
"gotest.tools/v3/assert" | ||
is "gotest.tools/v3/assert/cmp" | ||
"gotest.tools/v3/skip" | ||
) | ||
|
||
// Check that the '/etc/hosts' file in a container is created according to | ||
// whether the container supports IPv6. | ||
// Regression test for https://github.com/moby/moby/issues/35954 | ||
func TestEtcHostsIpv6(t *testing.T) { | ||
skip.If(t, testEnv.DaemonInfo.OSType == "windows") | ||
|
||
ctx := setupTest(t) | ||
d := daemon.New(t) | ||
d.StartWithBusybox(ctx, t, | ||
"--ipv6", | ||
"--ip6tables", | ||
"--experimental", | ||
"--fixed-cidr-v6=fdc8:ffe2:d8d7:1234::/64") | ||
defer d.Stop(t) | ||
|
||
c := d.NewClientT(t) | ||
defer c.Close() | ||
|
||
testcases := []struct { | ||
name string | ||
sysctls map[string]string | ||
expIPv6Enabled bool | ||
expEtcHosts string | ||
}{ | ||
{ | ||
// Create a container with no overrides, on the IPv6-enabled default bridge. | ||
// Expect the container to have a working '::1' address, on the assumption | ||
// the test host's kernel supports IPv6 - and for its '/etc/hosts' file to | ||
// include IPv6 addresses. | ||
name: "IPv6 enabled", | ||
expIPv6Enabled: true, | ||
expEtcHosts: `127.0.0.1 localhost | ||
::1 localhost ip6-localhost ip6-loopback | ||
fe00::0 ip6-localnet | ||
ff00::0 ip6-mcastprefix | ||
ff02::1 ip6-allnodes | ||
ff02::2 ip6-allrouters | ||
`, | ||
}, | ||
{ | ||
// Create a container in the same network, with IPv6 disabled. Expect '::1' | ||
// not to be pingable, and no IPv6 addresses in its '/etc/hosts'. | ||
name: "IPv6 disabled", | ||
sysctls: map[string]string{"net.ipv6.conf.all.disable_ipv6": "1"}, | ||
expIPv6Enabled: false, | ||
expEtcHosts: "127.0.0.1\tlocalhost\n", | ||
}, | ||
} | ||
|
||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
ctx := testutil.StartSpan(ctx, t) | ||
ctrId := container.Run(ctx, t, c, | ||
container.WithName("etchosts_"+sanitizeCtrName(t.Name())), | ||
container.WithImage("busybox:latest"), | ||
container.WithCmd("top"), | ||
container.WithSysctls(tc.sysctls), | ||
) | ||
defer func() { | ||
c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true}) | ||
}() | ||
|
||
runCmd := func(ctrId string, cmd []string, expExitCode int) string { | ||
t.Helper() | ||
execCtx, cancel := context.WithTimeout(ctx, 5*time.Second) | ||
defer cancel() | ||
res, err := container.Exec(execCtx, c, ctrId, cmd) | ||
assert.Check(t, is.Nil(err)) | ||
assert.Check(t, is.Equal(res.ExitCode, expExitCode)) | ||
return res.Stdout() | ||
} | ||
|
||
// Check that IPv6 is/isn't enabled, as expected. | ||
var expPingExitStatus int | ||
if !tc.expIPv6Enabled { | ||
expPingExitStatus = 1 | ||
} | ||
runCmd(ctrId, []string{"ping", "-6", "-c1", "-W3", "::1"}, expPingExitStatus) | ||
|
||
// Check the contents of /etc/hosts. | ||
stdout := runCmd(ctrId, []string{"cat", "/etc/hosts"}, 0) | ||
// Append the container's own addresses/name to the expected hosts file content. | ||
inspect := container.Inspect(ctx, t, c, ctrId) | ||
exp := tc.expEtcHosts + inspect.NetworkSettings.IPAddress + "\t" + inspect.Config.Hostname + "\n" | ||
if tc.expIPv6Enabled { | ||
exp += inspect.NetworkSettings.GlobalIPv6Address + "\t" + inspect.Config.Hostname + "\n" | ||
} | ||
assert.Check(t, is.Equal(stdout, exp)) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.