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 docker/docker#29184 Fixes docker/docker#23987 Related to docker/docker#24848 Signed-off-by: Jacob Wen <jian.w.wen@oracle.com>
This commit is contained in:
parent
37e20af882
commit
0067b3a8ec
|
@ -844,6 +844,10 @@ addToStore:
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
arrangeUserFilterRule()
|
||||||
|
c.Unlock()
|
||||||
|
|
||||||
return network, nil
|
return network, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ func setupIPChains(config *configuration) (*iptables.ChainInfo, *iptables.ChainI
|
||||||
return nil, nil, nil, fmt.Errorf("failed to create FILTER isolation chain: %v", err)
|
return nil, nil, nil, fmt.Errorf("failed to create FILTER isolation chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := addReturnRule(IsolationChain); err != nil {
|
if err := iptables.AddReturnRule(IsolationChain); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
err = ensureJumpRule("FORWARD", IsolationChain)
|
err = iptables.EnsureJumpRule("FORWARD", IsolationChain)
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -280,46 +280,6 @@ func setINC(iface1, iface2 string, enable bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addReturnRule(chain string) error {
|
|
||||||
var (
|
|
||||||
table = iptables.Filter
|
|
||||||
args = []string{"-j", "RETURN"}
|
|
||||||
)
|
|
||||||
|
|
||||||
if iptables.Exists(table, chain, args...) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := iptables.RawCombinedOutput(append([]string{"-I", chain}, args...)...)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to add return rule in %s chain: %s", chain, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the jump rule is on top
|
|
||||||
func ensureJumpRule(fromChain, toChain string) error {
|
|
||||||
var (
|
|
||||||
table = iptables.Filter
|
|
||||||
args = []string{"-j", toChain}
|
|
||||||
)
|
|
||||||
|
|
||||||
if iptables.Exists(table, fromChain, args...) {
|
|
||||||
err := iptables.RawCombinedOutput(append([]string{"-D", fromChain}, args...)...)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to remove jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := iptables.RawCombinedOutput(append([]string{"-I", fromChain}, args...)...)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to insert jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeIPChains() {
|
func removeIPChains() {
|
||||||
for _, chainInfo := range []iptables.ChainInfo{
|
for _, chainInfo := range []iptables.ChainInfo{
|
||||||
{Name: DockerChain, Table: iptables.Nat},
|
{Name: DockerChain, Table: iptables.Nat},
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package libnetwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/libnetwork/iptables"
|
||||||
|
)
|
||||||
|
|
||||||
|
const userChain = "DOCKER-USER"
|
||||||
|
|
||||||
|
// This chain 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.
|
||||||
|
func arrangeUserFilterRule() {
|
||||||
|
_, err := iptables.NewChain(userChain, iptables.Filter, false)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf("Failed to create %s chain: %v", userChain, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = iptables.AddReturnRule(userChain); err != nil {
|
||||||
|
logrus.Warnf("Failed to add the RETURN rule for %s: %v", userChain, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = iptables.EnsureJumpRule("FORWARD", userChain)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf("Failed to ensure the jump rule for %s: %v", userChain, err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package libnetwork
|
||||||
|
|
||||||
|
func arrangeUserFilterRule() {
|
||||||
|
}
|
|
@ -498,3 +498,44 @@ func parseVersionNumbers(input string) (major, minor, micro int) {
|
||||||
func supportsCOption(mj, mn, mc int) bool {
|
func supportsCOption(mj, mn, mc int) bool {
|
||||||
return mj > 1 || (mj == 1 && (mn > 4 || (mn == 4 && mc >= 11)))
|
return mj > 1 || (mj == 1 && (mn > 4 || (mn == 4 && mc >= 11)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddReturnRule adds a return rule for the chain in the filter table
|
||||||
|
func AddReturnRule(chain string) error {
|
||||||
|
var (
|
||||||
|
table = Filter
|
||||||
|
args = []string{"-j", "RETURN"}
|
||||||
|
)
|
||||||
|
|
||||||
|
if Exists(table, chain, args...) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := RawCombinedOutput(append([]string{"-A", chain}, args...)...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to add return rule in %s chain: %s", chain, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnsureJumpRule ensures the jump rule is on top
|
||||||
|
func EnsureJumpRule(fromChain, toChain string) error {
|
||||||
|
var (
|
||||||
|
table = Filter
|
||||||
|
args = []string{"-j", toChain}
|
||||||
|
)
|
||||||
|
|
||||||
|
if Exists(table, fromChain, args...) {
|
||||||
|
err := RawCombinedOutput(append([]string{"-D", fromChain}, args...)...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to remove jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := RawCombinedOutput(append([]string{"-I", fromChain}, args...)...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to insert jump to %s rule in %s chain: %s", toChain, fromChain, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue