From 0c67f144ec2ea8cc321c504c164c3581caa4390588072c12f5cf6327ce77f92a Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 23 Nov 2020 06:29:36 +0000 Subject: [PATCH] Accepting request 848862 from home:mrostecki:branches:Virtualization:containers - Add a patch which makes Docker compatible with firewalld with nftables backend. Backport of https://github.com/moby/libnetwork/pull/2548 (boo#1178801, SLE-16460) * boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch OBS-URL: https://build.opensuse.org/request/show/848862 OBS-URL: https://build.opensuse.org/package/show/Virtualization:containers/docker?expand=0&rev=344 --- ...-interfaces-to-firewalld-docker-zone.patch | 230 ++++++++++++++++++ docker.changes | 8 + docker.spec | 3 + 3 files changed, 241 insertions(+) create mode 100644 boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch diff --git a/boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch b/boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch new file mode 100644 index 0000000..176d9a5 --- /dev/null +++ b/boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch @@ -0,0 +1,230 @@ +From ea920fbc29225a71c9e07ffeeba00bc71423d839 Mon Sep 17 00:00:00 2001 +From: Arko Dasgupta +Date: Mon, 4 May 2020 13:51:42 -0700 +Subject: [PATCH] Add docker interfaces to firewalld docker zone + +If firewalld is running, create a new docker zone and +add the docker interfaces to the docker zone to allow +container networking for distros with firewalld enabled + +Fixes: https://github.com/moby/libnetwork/issues/2496 + +Signed-off-by: Arko Dasgupta +(cherry picked from commit 7a7209221542dc99b316748c97608dfc276c40f6) +Signed-off-by: Sebastiaan van Stijn +--- + .../docker/libnetwork/iptables/firewalld.go | 136 ++++++++++++++++-- + .../docker/libnetwork/iptables/iptables.go | 13 ++ + 2 files changed, 139 insertions(+), 10 deletions(-) + +diff --git a/components/engine/vendor/github.com/docker/libnetwork/iptables/firewalld.go b/components/engine/vendor/github.com/docker/libnetwork/iptables/firewalld.go +index 8f13c86448..33eb749ab0 100644 +--- a/components/engine/vendor/github.com/docker/libnetwork/iptables/firewalld.go ++++ b/components/engine/vendor/github.com/docker/libnetwork/iptables/firewalld.go +@@ -19,20 +19,46 @@ const ( + // Ebtables point to bridge table + Ebtables IPV = "eb" + ) ++ + const ( +- dbusInterface = "org.fedoraproject.FirewallD1" +- dbusPath = "/org/fedoraproject/FirewallD1" ++ dbusInterface = "org.fedoraproject.FirewallD1" ++ dbusPath = "/org/fedoraproject/FirewallD1" ++ dbusConfigPath = "/org/fedoraproject/FirewallD1/config" ++ dockerZone = "docker" + ) + + // Conn is a connection to firewalld dbus endpoint. + type Conn struct { +- sysconn *dbus.Conn +- sysobj dbus.BusObject +- signal chan *dbus.Signal ++ sysconn *dbus.Conn ++ sysObj dbus.BusObject ++ sysConfObj dbus.BusObject ++ signal chan *dbus.Signal ++} ++ ++// ZoneSettings holds the firewalld zone settings, documented in ++// https://firewalld.org/documentation/man-pages/firewalld.dbus.html ++type ZoneSettings struct { ++ version string ++ name string ++ description string ++ unused bool ++ target string ++ services []string ++ ports [][]interface{} ++ icmpBlocks []string ++ masquerade bool ++ forwardPorts [][]interface{} ++ interfaces []string ++ sourceAddresses []string ++ richRules []string ++ protocols []string ++ sourcePorts [][]interface{} ++ icmpBlockInversion bool + } + + var ( +- connection *Conn ++ connection *Conn ++ + firewalldRunning bool // is Firewalld service running + onReloaded []*func() // callbacks when Firewalld has been reloaded + ) +@@ -51,6 +77,9 @@ func FirewalldInit() error { + } + if connection != nil { + go signalHandler() ++ if err := setupDockerZone(); err != nil { ++ return err ++ } + } + + return nil +@@ -76,8 +105,8 @@ func (c *Conn) initConnection() error { + } + + // This never fails, even if the service is not running atm. +- c.sysobj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusPath)) +- ++ c.sysObj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusPath)) ++ c.sysConfObj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusConfigPath)) + rule := fmt.Sprintf("type='signal',path='%s',interface='%s',sender='%s',member='Reloaded'", + dbusPath, dbusInterface, dbusInterface) + c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule) +@@ -150,7 +179,7 @@ func checkRunning() bool { + var err error + + if connection != nil { +- err = connection.sysobj.Call(dbusInterface+".getDefaultZone", 0).Store(&zone) ++ err = connection.sysObj.Call(dbusInterface+".getDefaultZone", 0).Store(&zone) + return err == nil + } + return false +@@ -160,8 +189,95 @@ func checkRunning() bool { + func Passthrough(ipv IPV, args ...string) ([]byte, error) { + var output string + logrus.Debugf("Firewalld passthrough: %s, %s", ipv, args) +- if err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil { ++ if err := connection.sysObj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil { + return nil, err + } + return []byte(output), nil + } ++ ++// getDockerZoneSettings converts the ZoneSettings struct into a interface slice ++func getDockerZoneSettings() map[string]string { ++ return map[string]string{ ++ "version": "1.0", ++ "name": dockerZone, ++ "description": "zone for docker bridge network interfaces", ++ "target": "ACCEPT", ++ } ++} ++ ++// setupDockerZone creates a zone called docker in firewalld which includes docker interfaces to allow ++// container networking ++func setupDockerZone() error { ++ var zones []string ++ // Check if zone exists ++ if err := connection.sysObj.Call(dbusInterface+".zone.getZones", 0).Store(&zones); err != nil { ++ return err ++ } ++ if contains(zones, dockerZone) { ++ logrus.Infof("Firewalld: %s zone already exists, returning", dockerZone) ++ return nil ++ } ++ logrus.Debugf("Firewalld: creating %s zone", dockerZone) ++ ++ settings := getDockerZoneSettings() ++ // Permanent ++ if err := connection.sysConfObj.Call(dbusInterface+".config.addZone", 0, dockerZone, settings).Err; err != nil { ++ return err ++ } ++ // Reload for change to take effect ++ if err := connection.sysObj.Call(dbusInterface+".reload", 0).Err; err != nil { ++ return err ++ } ++ ++ return nil ++} ++ ++// AddInterfaceFirewalld adds the interface to the trusted zone ++func AddInterfaceFirewalld(intf string) error { ++ var intfs []string ++ // Check if interface is already added to the zone ++ if err := connection.sysObj.Call(dbusInterface+".zone.getInterfaces", 0, dockerZone).Store(&intfs); err != nil { ++ return err ++ } ++ // Return if interface is already part of the zone ++ if contains(intfs, intf) { ++ logrus.Infof("Firewalld: interface %s already part of %s zone, returning", intf, dockerZone) ++ return nil ++ } ++ ++ logrus.Debugf("Firewalld: adding %s interface to %s zone", intf, dockerZone) ++ // Runtime ++ if err := connection.sysObj.Call(dbusInterface+".zone.addInterface", 0, dockerZone, intf).Err; err != nil { ++ return err ++ } ++ return nil ++} ++ ++// DelInterfaceFirewalld removes the interface from the trusted zone ++func DelInterfaceFirewalld(intf string) error { ++ var intfs []string ++ // Check if interface is part of the zone ++ if err := connection.sysObj.Call(dbusInterface+".zone.getInterfaces", 0, dockerZone).Store(&intfs); err != nil { ++ return err ++ } ++ // Remove interface if it exists ++ if !contains(intfs, intf) { ++ return fmt.Errorf("Firewalld: unable to find interface %s in %s zone", intf, dockerZone) ++ } ++ ++ logrus.Debugf("Firewalld: removing %s interface from %s zone", intf, dockerZone) ++ // Runtime ++ if err := connection.sysObj.Call(dbusInterface+".zone.removeInterface", 0, dockerZone, intf).Err; err != nil { ++ return err ++ } ++ return nil ++} ++ ++func contains(list []string, val string) bool { ++ for _, v := range list { ++ if v == val { ++ return true ++ } ++ } ++ return false ++} +diff --git a/components/engine/vendor/github.com/docker/libnetwork/iptables/iptables.go b/components/engine/vendor/github.com/docker/libnetwork/iptables/iptables.go +index 5523c4858c..bd262eb86c 100644 +--- a/components/engine/vendor/github.com/docker/libnetwork/iptables/iptables.go ++++ b/components/engine/vendor/github.com/docker/libnetwork/iptables/iptables.go +@@ -146,6 +146,19 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err + return errors.New("Could not program chain, missing chain name") + } + ++ // Either add or remove the interface from the firewalld zone ++ if firewalldRunning { ++ if enable { ++ if err := AddInterfaceFirewalld(bridgeName); err != nil { ++ return err ++ } ++ } else { ++ if err := DelInterfaceFirewalld(bridgeName); err != nil { ++ return err ++ } ++ } ++ } ++ + switch c.Table { + case Nat: + preroute := []string{ +-- +2.29.2 + diff --git a/docker.changes b/docker.changes index d147d91..c05d356 100644 --- a/docker.changes +++ b/docker.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Nov 12 18:36:26 UTC 2020 - MichaƂ Rostecki + +- Add a patch which makes Docker compatible with firewalld with + nftables backend. Backport of https://github.com/moby/libnetwork/pull/2548 + (boo#1178801, SLE-16460) + * boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch + ------------------------------------------------------------------- Mon Aug 3 16:58:07 UTC 2020 - Callum Farmer diff --git a/docker.spec b/docker.spec index 5bd6c64..2cada94 100644 --- a/docker.spec +++ b/docker.spec @@ -86,6 +86,8 @@ Patch402: bsc1122469-0001-apparmor-allow-readby-and-tracedby.patch # SUSE-FEATURE: Add support to mirror inofficial/private registries # (https://github.com/docker/docker/pull/34319) Patch500: private-registry-0001-Add-private-registry-mirror-support.patch +# SUSE-BACKPORT: Backport of https://github.com/moby/libnetwork/pull/2548. boo#1178801, SLE-16460 +Patch600: boo1178801-0001-Add-docker-interfaces-to-firewalld-docker-zone.patch BuildRequires: audit BuildRequires: bash-completion BuildRequires: ca-certificates @@ -272,6 +274,7 @@ docker container runtime configuration for kubeadm # PATCH-SUSE: Mirror patch. %patch500 -p1 %endif +%patch600 -p1 cp %{SOURCE7} .