Skip to content

Commit 419f5a6

Browse files
committed
Make 'internal' bridge networks accessible from host
Prior to release 25.0.0, the bridge in an internal network was assigned an IP address - making the internal network accessible from the host, giving containers on the network access to anything listening on the bridge's address (or INADDR_ANY on the host). This change restores that behaviour. It does not restore the default route that was configured in the container, because packets sent outside the internal network's subnet have always been dropped. So, a 'connect()' to an address outside the subnet will still fail fast. Signed-off-by: Rob Murray <rob.murray@docker.com>
1 parent 9e075f3 commit 419f5a6

File tree

3 files changed

+63
-8
lines changed

3 files changed

+63
-8
lines changed

integration/networking/bridge_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,3 +477,60 @@ func TestDefaultBridgeAddresses(t *testing.T) {
477477
})
478478
}
479479
}
480+
481+
// Test that a container on an 'internal' network has IP connectivity with
482+
// the host (on its own subnet, because the n/w bridge has an address on that
483+
// subnet, and it's in the host's namespace).
484+
// Regression test for https://github.com/moby/moby/issues/47329
485+
func TestInternalNwConnectivity(t *testing.T) {
486+
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
487+
488+
ctx := setupTest(t)
489+
490+
d := daemon.New(t)
491+
d.StartWithBusybox(ctx, t, "-D", "--experimental", "--ip6tables")
492+
defer d.Stop(t)
493+
494+
c := d.NewClientT(t)
495+
defer c.Close()
496+
497+
const bridgeName = "intnw"
498+
const gw4 = "172.30.0.1"
499+
const gw6 = "fda9:4130:4715::1234"
500+
network.CreateNoError(ctx, t, c, bridgeName,
501+
network.WithInternal(),
502+
network.WithIPv6(),
503+
network.WithIPAM("172.30.0.0/24", gw4),
504+
network.WithIPAM("fda9:4130:4715::/64", gw6),
505+
network.WithDriver("bridge"),
506+
network.WithOption("com.docker.network.bridge.name", bridgeName),
507+
)
508+
defer network.RemoveNoError(ctx, t, c, bridgeName)
509+
510+
const ctrName = "intctr"
511+
id := container.Run(ctx, t, c,
512+
container.WithName(ctrName),
513+
container.WithImage("busybox:latest"),
514+
container.WithCmd("top"),
515+
container.WithNetworkMode(bridgeName),
516+
)
517+
defer c.ContainerRemove(ctx, id, containertypes.RemoveOptions{Force: true})
518+
519+
execCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
520+
defer cancel()
521+
522+
res := container.ExecT(execCtx, t, c, id, []string{"ping", "-c1", "-W3", gw4})
523+
assert.Check(t, is.Equal(res.ExitCode, 0))
524+
assert.Check(t, is.Equal(res.Stderr(), ""))
525+
assert.Check(t, is.Contains(res.Stdout(), "1 packets transmitted, 1 packets received"))
526+
527+
res = container.ExecT(execCtx, t, c, id, []string{"ping6", "-c1", "-W3", gw6})
528+
assert.Check(t, is.Equal(res.ExitCode, 0))
529+
assert.Check(t, is.Equal(res.Stderr(), ""))
530+
assert.Check(t, is.Contains(res.Stdout(), "1 packets transmitted, 1 packets received"))
531+
532+
// Addresses outside the internal subnet must not be accessible.
533+
res = container.ExecT(execCtx, t, c, id, []string{"ping", "-c1", "-W3", "8.8.8.8"})
534+
assert.Check(t, is.Equal(res.ExitCode, 1))
535+
assert.Check(t, is.Contains(res.Stderr(), "Network is unreachable"))
536+
}

libnetwork/drivers/bridge/setup_ipv4_linux.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
3232
// are decoupled, we should assign it only when it's really needed.
3333
i.bridgeIPv4 = config.AddressIPv4
3434

35-
if config.Internal {
36-
return nil
37-
}
38-
3935
if !config.InhibitIPv4 {
4036
addrv4List, err := i.addresses(netlink.FAMILY_V4)
4137
if err != nil {
@@ -57,8 +53,10 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
5753
}
5854
}
5955

60-
// Store the default gateway
61-
i.gatewayIPv4 = config.AddressIPv4.IP
56+
if !config.Internal {
57+
// Store the default gateway
58+
i.gatewayIPv4 = config.AddressIPv4.IP
59+
}
6260

6361
return nil
6462
}

libnetwork/drivers/bridge/setup_verify_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ func setupVerifyAndReconcileIPv4(config *networkConfiguration, i *bridgeInterfac
2020
addrv4, _ := selectIPv4Address(addrsv4, config.AddressIPv4)
2121

2222
// Verify that the bridge has an IPv4 address.
23-
if !config.Internal && addrv4.IPNet == nil {
23+
if addrv4.IPNet == nil {
2424
return &ErrNoIPAddr{}
2525
}
2626

2727
// Verify that the bridge IPv4 address matches the requested configuration.
28-
if config.AddressIPv4 != nil && addrv4.IPNet != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
28+
if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
2929
return &IPv4AddrNoMatchError{IP: addrv4.IP, CfgIP: config.AddressIPv4.IP}
3030
}
3131

0 commit comments

Comments
 (0)