mirror of
https://github.com/moby/moby.git
synced 2026-08-04 15:11:00 +00:00
Restore iptables for current networks on firewalld reload
Using iptables.OnReloaded to restore individual per-network rules on firewalld reload means rules for deleted networks pop back in to existence (because there was no way to delete the callbacks on network-delete). So, on firewalld reload, walk over current networks and ask them to restore their iptables rules. Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
@@ -544,6 +544,7 @@ func (d *driver) configure(option map[string]interface{}) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iptables.OnReloaded(d.handleFirewalldReload)
|
||||||
|
|
||||||
var pdc portDriverClient
|
var pdc portDriverClient
|
||||||
if config.Rootless {
|
if config.Rootless {
|
||||||
@@ -899,13 +900,6 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) {
|
|||||||
// Setup Loopback Addresses Routing
|
// Setup Loopback Addresses Routing
|
||||||
{!d.config.EnableUserlandProxy, setupLoopbackAddressesRouting},
|
{!d.config.EnableUserlandProxy, setupLoopbackAddressesRouting},
|
||||||
|
|
||||||
// We want to track firewalld configuration so that
|
|
||||||
// if it is started/reloaded, the rules can be applied correctly
|
|
||||||
{
|
|
||||||
(config.EnableIPv4 && d.config.EnableIPTables) || (config.EnableIPv6 && d.config.EnableIP6Tables),
|
|
||||||
network.setupFirewalld,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Setup DefaultGatewayIPv4
|
// Setup DefaultGatewayIPv4
|
||||||
{config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
|
{config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
|
||||||
|
|
||||||
@@ -1475,6 +1469,11 @@ func (d *driver) ProgramExternalConnectivity(ctx context.Context, nid, eid strin
|
|||||||
attribute.String("eid", eid)))
|
attribute.String("eid", eid)))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
// Make sure the network isn't deleted, or in the middle of a firewalld reload, while
|
||||||
|
// updating its iptables rules.
|
||||||
|
d.configNetwork.Lock()
|
||||||
|
defer d.configNetwork.Unlock()
|
||||||
|
|
||||||
network, err := d.getNetwork(nid)
|
network, err := d.getNetwork(nid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1535,6 +1534,11 @@ func (d *driver) ProgramExternalConnectivity(ctx context.Context, nid, eid strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
|
func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
|
||||||
|
// Make sure this function isn't deleting iptables rules while handleFirewalldReloadNw
|
||||||
|
// is restoring those same rules.
|
||||||
|
d.configNetwork.Lock()
|
||||||
|
defer d.configNetwork.Unlock()
|
||||||
|
|
||||||
network, err := d.getNetwork(nid)
|
network, err := d.getNetwork(nid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1568,6 +1572,72 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *driver) handleFirewalldReload() {
|
||||||
|
if !d.config.EnableIPTables && !d.config.EnableIP6Tables {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Lock()
|
||||||
|
nids := make([]string, 0, len(d.networks))
|
||||||
|
for _, nw := range d.networks {
|
||||||
|
nids = append(nids, nw.id)
|
||||||
|
}
|
||||||
|
d.Unlock()
|
||||||
|
|
||||||
|
for _, nid := range nids {
|
||||||
|
d.handleFirewalldReloadNw(nid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *driver) handleFirewalldReloadNw(nid string) {
|
||||||
|
d.Lock()
|
||||||
|
defer d.Unlock()
|
||||||
|
|
||||||
|
if !d.config.EnableIPTables && !d.config.EnableIP6Tables {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the network isn't being deleted, and ProgramExternalConnectivity/RevokeExternalConnectivity
|
||||||
|
// aren't modifying iptables rules, while restoring the rules.
|
||||||
|
d.configNetwork.Lock()
|
||||||
|
defer d.configNetwork.Unlock()
|
||||||
|
|
||||||
|
nw, ok := d.networks[nid]
|
||||||
|
if !ok {
|
||||||
|
// Network deleted since the reload started, not an error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := nw.iptablesNetwork.reapplyNetworkLevelRules(); err != nil {
|
||||||
|
log.G(context.Background()).WithFields(log.Fields{
|
||||||
|
"nid": nw.id,
|
||||||
|
"error": err,
|
||||||
|
}).Error("Failed to re-create packet filter on firewalld reload")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-add legacy links - only added during ProgramExternalConnectivity, but legacy
|
||||||
|
// links are default-bridge-only, and it's not possible to connect a container to
|
||||||
|
// the default bridge and a user-defined network. So, the default bridge is always
|
||||||
|
// the gateway and, if there are legacy links configured they need to be set up.
|
||||||
|
if !nw.config.EnableICC {
|
||||||
|
for _, ep := range nw.endpoints {
|
||||||
|
if err := d.link(nw, ep, true); err != nil {
|
||||||
|
log.G(context.Background()).WithFields(log.Fields{
|
||||||
|
"nid": nw.id,
|
||||||
|
"eid": ep.id,
|
||||||
|
"error": err,
|
||||||
|
}).Error("Failed to re-create link on firewalld reload")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up per-port rules. These are also only set up during ProgramExternalConnectivity
|
||||||
|
// but the network's port bindings are only configured when it's acting as the
|
||||||
|
// gateway network. So, this is a no-op for networks that aren't providing endpoints
|
||||||
|
// with the gateway.
|
||||||
|
nw.reapplyPerPortIptables()
|
||||||
|
}
|
||||||
|
|
||||||
func LegacyContainerLinkOptions(parentEndpoints, childEndpoints []string) map[string]interface{} {
|
func LegacyContainerLinkOptions(parentEndpoints, childEndpoints []string) map[string]interface{} {
|
||||||
return options.Generic{
|
return options.Generic{
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
//go:build linux
|
|
||||||
|
|
||||||
package bridge
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/docker/docker/libnetwork/iptables"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *bridgeNetwork) setupFirewalld(config *networkConfiguration, i *bridgeInterface) error {
|
|
||||||
// FIXME(robmry) - these reload functions aren't deleted when the network is deleted.
|
|
||||||
// So, a firewalld reload leads to creation of zombie rules belonging to those networks.
|
|
||||||
iptables.OnReloaded(func() { n.iptablesNetwork.reapplyNetworkLevelRules() })
|
|
||||||
iptables.OnReloaded(n.reapplyPerPortIptables)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user