Skip to content

Commit 531bb7c

Browse files
committed
Fix bridge connection reset due to invalid packets
Add drop of conntrack INVALID packets in input such that invalid packets due to TCP window overflow do not cause a connection reset. Due to some netfilter/conntrack limitations, invalid packets are never treated as NAT'ed but reassigned to the host and considered martians. This causes a RST response from the host and resets the connection. As soon as NAT is setup, for bridge networks for instance, invalid packets have to be dropped in input. The implementation adds a generic DOCKER-INPUT chain prefilled with a rule for dropping invalid packets and a return rule. As soon as some bridge network is setup, the DOCKER-INPUT chain call is inserted in the filter table INPUT chain. Fixes #1090. Signed-off-by: Christophe Guillon <[email protected]>
1 parent 20461b8 commit 531bb7c

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

drivers/bridge/setup_ip_tables.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
// DockerChain: DOCKER iptable chain name
1414
const (
1515
DockerChain = "DOCKER"
16+
DockerInputChain = "DOCKER-INPUT"
1617
// Isolation between bridge networks is achieved in two stages by means
1718
// of the following two chains in the filter table. The first chain matches
1819
// on the source interface being a bridge network's bridge and the
@@ -58,6 +59,18 @@ func setupIPChains(config *configuration) (*iptables.ChainInfo, *iptables.ChainI
5859
}
5960
}()
6061

62+
_, err = iptables.NewChain(DockerInputChain, iptables.Filter, false)
63+
if err != nil {
64+
return nil, nil, nil, nil, fmt.Errorf("failed to create INPUT chain %s: %v", DockerInputChain, err)
65+
}
66+
defer func() {
67+
if err != nil {
68+
if err := iptables.RemoveExistingChain(DockerInputChain, iptables.Filter); err != nil {
69+
logrus.Warnf("failed on removing iptables INPUT chain %s on cleanup: %v", DockerInputChain, err)
70+
}
71+
}
72+
}()
73+
6174
isolationChain1, err := iptables.NewChain(IsolationChain1, iptables.Filter, false)
6275
if err != nil {
6376
return nil, nil, nil, nil, fmt.Errorf("failed to create FILTER isolation chain: %v", err)
@@ -82,14 +95,22 @@ func setupIPChains(config *configuration) (*iptables.ChainInfo, *iptables.ChainI
8295
}
8396
}()
8497

85-
if err := iptables.AddReturnRule(IsolationChain1); err != nil {
98+
if err := iptables.AddReturnRule(DockerInputChain); err != nil {
99+
return nil, nil, nil, nil, err
100+
}
101+
102+
if err := iptables.AddReturnRule(IsolationChain1); err != nil {
86103
return nil, nil, nil, nil, err
87104
}
88105

89106
if err := iptables.AddReturnRule(IsolationChain2); err != nil {
90107
return nil, nil, nil, nil, err
91108
}
92109

110+
if err := iptables.ProgramRule(iptables.Filter, DockerInputChain, iptables.Insert, []string{"-m", "conntrack", "--ctstate", "INVALID", "-j", "DROP"}); err != nil {
111+
return nil, nil, nil, nil, err
112+
}
113+
93114
return natChain, filterChain, isolationChain1, isolationChain2, nil
94115
}
95116

@@ -149,6 +170,13 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt
149170
n.portMapper.SetIptablesChain(natChain, n.getNetworkBridgeName())
150171
}
151172

173+
d.Lock()
174+
err = iptables.EnsureJumpRule("INPUT", DockerInputChain)
175+
d.Unlock()
176+
if err != nil {
177+
return err
178+
}
179+
152180
d.Lock()
153181
err = iptables.EnsureJumpRule("FORWARD", IsolationChain1)
154182
d.Unlock()
@@ -321,10 +349,14 @@ func removeIPChains() {
321349
// Remove obsolete rules from default chains
322350
iptables.ProgramRule(iptables.Filter, "FORWARD", iptables.Delete, []string{"-j", oldIsolationChain})
323351

352+
// Remove possibly installed references to chains
353+
iptables.ProgramRule(iptables.Filter, "INPUT", iptables.Delete, []string{"-j", DockerInputChain})
354+
324355
// Remove chains
325356
for _, chainInfo := range []iptables.ChainInfo{
326357
{Name: DockerChain, Table: iptables.Nat},
327358
{Name: DockerChain, Table: iptables.Filter},
359+
{Name: DockerInputChain, Table: iptables.Filter},
328360
{Name: IsolationChain1, Table: iptables.Filter},
329361
{Name: IsolationChain2, Table: iptables.Filter},
330362
{Name: oldIsolationChain, Table: iptables.Filter},

0 commit comments

Comments
 (0)