Skip to content

Commit a60d046

Browse files
author
Jacob Wen
committed
Add a filter chain to allow persistent rules
Allow users to configure firewall policies in a way that persists docker operations/restarts. Docker will not delete or modify any pre-existing rules from the DOCKER-USER filter chain. This allows the user to create in advance any rules required to further restrict access from/to the containers. Fixes moby/moby#29184 Fixes moby/moby#23987 Related to moby/moby#24848 Signed-off-by: Jacob Wen <[email protected]>
1 parent 37e20af commit a60d046

File tree

5 files changed

+83
-42
lines changed

5 files changed

+83
-42
lines changed

controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,10 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
813813
}
814814
}()
815815

816+
c.Lock()
817+
arrangeUserFilterRule()
818+
c.Unlock()
819+
816820
addToStore:
817821
// First store the endpoint count, then the network. To avoid to
818822
// end up with a datastore containing a network and not an epCnt,
@@ -841,6 +845,7 @@ addToStore:
841845
if !c.isDistributedControl() {
842846
c.Lock()
843847
arrangeIngressFilterRule()
848+
arrangeUserFilterRule()
844849
c.Unlock()
845850
}
846851

drivers/bridge/setup_ip_tables.go

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func setupIPChains(config *configuration) (*iptables.ChainInfo, *iptables.ChainI
5353
return nil, nil, nil, fmt.Errorf("failed to create FILTER isolation chain: %v", err)
5454
}
5555

56-
if err := addReturnRule(IsolationChain); err != nil {
56+
if err := iptables.AddReturnRule(IsolationChain); err != nil {
5757
return nil, nil, nil, err
5858
}
5959

@@ -117,7 +117,7 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt
117117
}
118118

119119
d.Lock()
120-
err = ensureJumpRule("FORWARD", IsolationChain)
120+
err = iptables.EnsureJumpRule("FORWARD", IsolationChain)
121121
d.Unlock()
122122
if err != nil {
123123
return err
@@ -280,46 +280,6 @@ func setINC(iface1, iface2 string, enable bool) error {
280280
return nil
281281
}
282282

283-
func addReturnRule(chain string) error {
284-
var (
285-
table = iptables.Filter
286-
args = []string{"-j", "RETURN"}
287-
)
288-
289-
if iptables.Exists(table, chain, args...) {
290-
return nil
291-
}
292-
293-
err := iptables.RawCombinedOutput(append([]string{"-I", chain}, args...)...)
294-
if err != nil {
295-
return fmt.Errorf("unable to add return rule in %s chain: %s", chain, err.Error())
296-
}
297-
298-
return nil
299-
}
300-
301-
// Ensure the jump rule is on top
302-
func ensureJumpRule(fromChain, toChain string) error {
303-
var (
304-
table = iptables.Filter
305-
args = []string{"-j", toChain}
306-
)
307-
308-
if iptables.Exists(table, fromChain, args...) {
309-
err := iptables.RawCombinedOutput(append([]string{"-D", fromChain}, args...)...)
310-
if err != nil {
311-
return fmt.Errorf("unable to remove jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
312-
}
313-
}
314-
315-
err := iptables.RawCombinedOutput(append([]string{"-I", fromChain}, args...)...)
316-
if err != nil {
317-
return fmt.Errorf("unable to insert jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
318-
}
319-
320-
return nil
321-
}
322-
323283
func removeIPChains() {
324284
for _, chainInfo := range []iptables.ChainInfo{
325285
{Name: DockerChain, Table: iptables.Nat},

firewall_linux.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package libnetwork
2+
3+
import (
4+
"github.com/Sirupsen/logrus"
5+
"github.com/docker/libnetwork/iptables"
6+
)
7+
8+
const userChain = "DOCKER-USER"
9+
10+
// This chain allow users to configure firewall policies in a way that persists
11+
// docker operations/restarts. Docker will not delete or modify any pre-existing
12+
// rules from the DOCKER-USER filter chain.
13+
func arrangeUserFilterRule() {
14+
_, err := iptables.NewChain(userChain, iptables.Filter, false)
15+
if err != nil {
16+
logrus.Warnf("Failed to create %s chain: %v", userChain, err)
17+
return
18+
}
19+
20+
if err = iptables.AddReturnRule(userChain); err != nil {
21+
logrus.Warnf("Failed to add the RETURN rule for %s: %v", userChain, err)
22+
return
23+
}
24+
25+
err = iptables.EnsureJumpRule("FORWARD", userChain)
26+
if err != nil {
27+
logrus.Warnf("Failed to ensure the jump rule for %s: %v", userChain, err)
28+
}
29+
}

firewall_others.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// +build !linux
2+
3+
package libnetwork
4+
5+
func arrangeUserFilterRule() {
6+
}

iptables/iptables.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,44 @@ func parseVersionNumbers(input string) (major, minor, micro int) {
498498
func supportsCOption(mj, mn, mc int) bool {
499499
return mj > 1 || (mj == 1 && (mn > 4 || (mn == 4 && mc >= 11)))
500500
}
501+
502+
// AddReturnRule adds a return rule for the chain in the filter table
503+
func AddReturnRule(chain string) error {
504+
var (
505+
table = Filter
506+
args = []string{"-j", "RETURN"}
507+
)
508+
509+
if Exists(table, chain, args...) {
510+
return nil
511+
}
512+
513+
err := RawCombinedOutput(append([]string{"-A", chain}, args...)...)
514+
if err != nil {
515+
return fmt.Errorf("unable to add return rule in %s chain: %s", chain, err.Error())
516+
}
517+
518+
return nil
519+
}
520+
521+
// EnsureJumpRule ensures the jump rule is on top
522+
func EnsureJumpRule(fromChain, toChain string) error {
523+
var (
524+
table = Filter
525+
args = []string{"-j", toChain}
526+
)
527+
528+
if Exists(table, fromChain, args...) {
529+
err := RawCombinedOutput(append([]string{"-D", fromChain}, args...)...)
530+
if err != nil {
531+
return fmt.Errorf("unable to remove jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
532+
}
533+
}
534+
535+
err := RawCombinedOutput(append([]string{"-I", fromChain}, args...)...)
536+
if err != nil {
537+
return fmt.Errorf("unable to insert jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
538+
}
539+
540+
return nil
541+
}

0 commit comments

Comments
 (0)