Skip to content

Commit 4c19680

Browse files
authored
Merge pull request #48854 from robmry/12632_noproxy_masquerade
Only masquerade access to own published ports for userland-proxy=false
2 parents cd8d2c5 + bf251c3 commit 4c19680

File tree

7 files changed

+19
-6
lines changed

7 files changed

+19
-6
lines changed

integration/network/bridge/iptablesdoc/generated/usernet-portmap-noicc.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ And the corresponding nat table:
111111
num pkts bytes target prot opt in out source destination
112112
1 0 0 MASQUERADE 0 -- * !bridge1 192.0.2.0/24 0.0.0.0/0
113113
2 0 0 MASQUERADE 0 -- * !docker0 172.17.0.0/16 0.0.0.0/0
114-
3 0 0 MASQUERADE 6 -- * * 192.0.2.2 192.0.2.2 tcp dpt:80
115114

116115
Chain DOCKER (2 references)
117116
num pkts bytes target prot opt in out source destination
@@ -132,7 +131,6 @@ And the corresponding nat table:
132131
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
133132
-A POSTROUTING -s 192.0.2.0/24 ! -o bridge1 -j MASQUERADE
134133
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
135-
-A POSTROUTING -s 192.0.2.2/32 -d 192.0.2.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
136134
-A DOCKER -i bridge1 -j RETURN
137135
-A DOCKER -i docker0 -j RETURN
138136
-A DOCKER ! -i bridge1 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.0.2.2:80

integration/network/bridge/iptablesdoc/generated/usernet-portmap-noproxy.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ Differences from [running with the proxy][0] are:
138138
[ProgramChain][1].
139139
- The "SKIP DNAT" RETURN rule for packets routed to the bridge is omitted from
140140
the DOCKER chain [setupIPTablesInternal][2].
141+
- A MASQUERADE rule is added for packets sent from the container to one of its
142+
own published ports on the host.
141143
- A MASQUERADE rule for packets from a LOCAL source address is included in
142144
POSTROUTING [setupIPTablesInternal][3].
143145
- In the DOCKER chain's DNAT rule, there's no destination bridge [setPerPortNAT][4].

integration/network/bridge/iptablesdoc/generated/usernet-portmap.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ And the corresponding nat table:
123123
num pkts bytes target prot opt in out source destination
124124
1 0 0 MASQUERADE 0 -- * !bridge1 192.0.2.0/24 0.0.0.0/0
125125
2 0 0 MASQUERADE 0 -- * !docker0 172.17.0.0/16 0.0.0.0/0
126-
3 0 0 MASQUERADE 6 -- * * 192.0.2.2 192.0.2.2 tcp dpt:80
127126

128127
Chain DOCKER (2 references)
129128
num pkts bytes target prot opt in out source destination
@@ -144,7 +143,6 @@ And the corresponding nat table:
144143
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
145144
-A POSTROUTING -s 192.0.2.0/24 ! -o bridge1 -j MASQUERADE
146145
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
147-
-A POSTROUTING -s 192.0.2.2/32 -d 192.0.2.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
148146
-A DOCKER -i bridge1 -j RETURN
149147
-A DOCKER -i docker0 -j RETURN
150148
-A DOCKER ! -i bridge1 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.0.2.2:80

integration/network/bridge/iptablesdoc/templates/usernet-portmap-noproxy.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Differences from [running with the proxy][0] are:
3636
[ProgramChain][1].
3737
- The "SKIP DNAT" RETURN rule for packets routed to the bridge is omitted from
3838
the DOCKER chain [setupIPTablesInternal][2].
39+
- A MASQUERADE rule is added for packets sent from the container to one of its
40+
own published ports on the host.
3941
- A MASQUERADE rule for packets from a LOCAL source address is included in
4042
POSTROUTING [setupIPTablesInternal][3].
4143
- In the DOCKER chain's DNAT rule, there's no destination bridge [setPerPortNAT][4].

integration/networking/port_mapping_linux_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,13 @@ func TestAccessPublishedPortFromRemoteHost(t *testing.T) {
459459
}
460460
}
461461

462+
// TestAccessPublishedPortFromCtr checks that a container's published ports can
463+
// be reached from the container that published the ports, and a neighbouring
464+
// container on the same network. It runs in three modes:
465+
//
466+
// - userland proxy enabled (default behaviour).
467+
// - proxy disabled (https://github.com/moby/moby/issues/12632)
468+
// - proxy disabled, 'bridge-nf-call-iptables=0' (https://github.com/moby/moby/issues/48664)
462469
func TestAccessPublishedPortFromCtr(t *testing.T) {
463470
// This test makes changes to the host's "/proc/sys/net/bridge/bridge-nf-call-iptables",
464471
// which would have no effect on rootlesskit's netns.
@@ -543,6 +550,12 @@ func TestAccessPublishedPortFromCtr(t *testing.T) {
543550
)
544551
defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})
545552
assert.Check(t, is.Contains(res.Stderr.String(), "404 Not Found"))
553+
554+
// Also check that the container can reach its own published port.
555+
clientCtx2, cancel2 := context.WithTimeout(ctx, 5*time.Second)
556+
defer cancel2()
557+
execRes := container.ExecT(clientCtx2, t, c, serverId, []string{"wget", "http://" + net.JoinHostPort(hostAddr, hostPort)})
558+
assert.Check(t, is.Contains(execRes.Stderr(), "404 Not Found"))
546559
})
547560
}
548561
}

libnetwork/drivers/bridge/port_mapping_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ func setPerPortNAT(b portBinding, ipv iptables.IPVersion, proxyPath string, brid
821821
"-j", "MASQUERADE",
822822
}
823823
rule = iptRule{ipv: ipv, table: iptables.Nat, chain: "POSTROUTING", args: args}
824-
if err := appendOrDelChainRule(rule, "MASQUERADE", enable); err != nil {
824+
if err := appendOrDelChainRule(rule, "MASQUERADE", hairpinMode && enable); err != nil {
825825
return err
826826
}
827827

libnetwork/drivers/bridge/port_mapping_linux_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ func TestAddPortMappings(t *testing.T) {
904904
masqRule := fmt.Sprintf("-s %s -d %s -p %s -m %s --dport %d -j MASQUERADE",
905905
addrM, addrM, expPB.Proto, expPB.Proto, expPB.Port)
906906
ir := iptRule{ipv: ipv, table: iptables.Nat, chain: "POSTROUTING", args: strings.Split(masqRule, " ")}
907-
if disableNAT {
907+
if disableNAT || tc.proxyPath != "" {
908908
assert.Check(t, !ir.Exists(), fmt.Sprintf("unexpected rule %s", ir))
909909
} else {
910910
assert.Check(t, ir.Exists(), fmt.Sprintf("expected rule %s", ir))

0 commit comments

Comments
 (0)