diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-04-15 14:16:34 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-08-19 16:16:06 +0200 |
commit | 99983e20bbd6af8b88ae11ba53110438d666046b (patch) | |
tree | 895c7029f2924621cf028ace13cff182e20124a5 /pkg | |
parent | bd0b05f13860b62de389ec67eadd0df6b44d4f4f (diff) | |
download | podman-99983e20bbd6af8b88ae11ba53110438d666046b.tar.gz podman-99983e20bbd6af8b88ae11ba53110438d666046b.tar.bz2 podman-99983e20bbd6af8b88ae11ba53110438d666046b.zip |
networking: use firewall plugin
drop the pkg/firewall module and start using the firewall CNI plugin.
It requires an updated package for CNI plugins.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/firewall/common.go | 55 | ||||
-rw-r--r-- | pkg/firewall/firewall_linux.go | 47 | ||||
-rw-r--r-- | pkg/firewall/firewall_none.go | 43 | ||||
-rw-r--r-- | pkg/firewall/firewall_unsupported.go | 27 | ||||
-rw-r--r-- | pkg/firewall/firewalld.go | 122 | ||||
-rw-r--r-- | pkg/firewall/iptables.go | 195 |
6 files changed, 0 insertions, 489 deletions
diff --git a/pkg/firewall/common.go b/pkg/firewall/common.go deleted file mode 100644 index a65d4f03d..000000000 --- a/pkg/firewall/common.go +++ /dev/null @@ -1,55 +0,0 @@ -package firewall - -// Copyright 2016 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "net" - - "github.com/containernetworking/cni/pkg/types/current" -) - -// FirewallNetConf represents the firewall configuration. -// Nolint applied for firewall.Firewall... name duplication notice. -//nolint -type FirewallNetConf struct { - //types.NetConf - - // IptablesAdminChainName is an optional name to use instead of the default - // admin rules override chain name that includes the interface name. - IptablesAdminChainName string - - // FirewalldZone is an optional firewalld zone to place the interface into. If - // the firewalld backend is used but the zone is not given, it defaults - // to 'trusted' - FirewalldZone string - - PrevResult *current.Result -} - -// FirewallBackend is an interface to the system firewall, allowing addition and -// removal of firewall rules. -// Nolint applied for firewall.Firewall... name duplication notice. -//nolint -type FirewallBackend interface { - Add(*FirewallNetConf) error - Del(*FirewallNetConf) error -} - -func ipString(ip net.IPNet) string { - if ip.IP.To4() == nil { - return ip.IP.String() + "/128" - } - return ip.IP.String() + "/32" -} diff --git a/pkg/firewall/firewall_linux.go b/pkg/firewall/firewall_linux.go deleted file mode 100644 index 4ac45427b..000000000 --- a/pkg/firewall/firewall_linux.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build linux - -// Copyright 2016 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package firewall - -import ( - "fmt" -) - -// GetBackend retrieves a firewall backend for adding or removing firewall rules -// on the system. -// Valid backend names are firewalld, iptables, and none. -// If the empty string is given, a firewalld backend will be returned if -// firewalld is running, and an iptables backend will be returned otherwise. -func GetBackend(backend string) (FirewallBackend, error) { - switch backend { - case "firewalld": - return newFirewalldBackend() - case "iptables": - return newIptablesBackend() - case "none": - return newNoneBackend() - case "": - // Default to firewalld if it's running - if isFirewalldRunning() { - return newFirewalldBackend() - } - - // Otherwise iptables - return newIptablesBackend() - default: - return nil, fmt.Errorf("unrecognized firewall backend %q", backend) - } -} diff --git a/pkg/firewall/firewall_none.go b/pkg/firewall/firewall_none.go deleted file mode 100644 index 9add24842..000000000 --- a/pkg/firewall/firewall_none.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package firewall - -import ( - "fmt" -) - -// FirewallNone is a firewall backend for environments where manipulating the -// system firewall is unsupported (for example, when running without root). -// Nolint applied to avoid firewall.FirewallNone name duplication notes. -//nolint -type FirewallNone struct{} - -func newNoneBackend() (FirewallBackend, error) { - return &FirewallNone{}, nil -} - -// Add adds a rule to the system firewall. -// No action is taken and an error is unconditionally returned as this backend -// does not support manipulating the firewall. -func (f *FirewallNone) Add(conf *FirewallNetConf) error { - return fmt.Errorf("cannot modify system firewall rules") -} - -// Del deletes a rule from the system firewall. -// No action is taken and an error is unconditionally returned as this backend -// does not support manipulating the firewall. -func (f *FirewallNone) Del(conf *FirewallNetConf) error { - return fmt.Errorf("cannot modify system firewall rules") -} diff --git a/pkg/firewall/firewall_unsupported.go b/pkg/firewall/firewall_unsupported.go deleted file mode 100644 index 24c07a8a9..000000000 --- a/pkg/firewall/firewall_unsupported.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build !linux - -// Copyright 2016 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package firewall - -import ( - "fmt" -) - -// GetBackend retrieves a firewall backend for adding or removing firewall rules -// on the system. -func GetBackend(backend string) (FirewallBackend, error) { - return nil, fmt.Errorf("firewall backends are not presently supported on this OS") -} diff --git a/pkg/firewall/firewalld.go b/pkg/firewall/firewalld.go deleted file mode 100644 index 15e845cb7..000000000 --- a/pkg/firewall/firewalld.go +++ /dev/null @@ -1,122 +0,0 @@ -// +build linux - -// Copyright 2018 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package firewall - -import ( - "fmt" - "github.com/sirupsen/logrus" - "strings" - - "github.com/godbus/dbus" -) - -const ( - dbusName = "org.freedesktop.DBus" - dbusPath = "/org/freedesktop/DBus" - dbusGetNameOwnerMethod = "GetNameOwner" - - firewalldName = "org.fedoraproject.FirewallD1" - firewalldPath = "/org/fedoraproject/FirewallD1" - firewalldZoneInterface = "org.fedoraproject.FirewallD1.zone" - firewalldAddSourceMethod = "addSource" - firewalldRemoveSourceMethod = "removeSource" - - errZoneAlreadySet = "ZONE_ALREADY_SET" -) - -// Only used for testcases to override the D-Bus connection -var testConn *dbus.Conn - -type fwdBackend struct { - conn *dbus.Conn -} - -// fwdBackend implements the FirewallBackend interface -var _ FirewallBackend = &fwdBackend{} - -func getConn() (*dbus.Conn, error) { - if testConn != nil { - return testConn, nil - } - return dbus.SystemBus() -} - -// isFirewalldRunning checks whether firewalld is running. -func isFirewalldRunning() bool { - conn, err := getConn() - if err != nil { - return false - } - - dbusObj := conn.Object(dbusName, dbusPath) - var res string - if err := dbusObj.Call(dbusName+"."+dbusGetNameOwnerMethod, 0, firewalldName).Store(&res); err != nil { - return false - } - - return true -} - -func newFirewalldBackend() (FirewallBackend, error) { - conn, err := getConn() - if err != nil { - return nil, err - } - - backend := &fwdBackend{ - conn: conn, - } - return backend, nil -} - -func getFirewalldZone(conf *FirewallNetConf) string { - if conf.FirewalldZone != "" { - return conf.FirewalldZone - } - - return "trusted" -} - -func (fb *fwdBackend) Add(conf *FirewallNetConf) error { - zone := getFirewalldZone(conf) - - for _, ip := range conf.PrevResult.IPs { - ipStr := ipString(ip.Address) - // Add a firewalld rule which assigns the given source IP to the given zone - firewalldObj := fb.conn.Object(firewalldName, firewalldPath) - var res string - if err := firewalldObj.Call(firewalldZoneInterface+"."+firewalldAddSourceMethod, 0, zone, ipStr).Store(&res); err != nil { - if !strings.Contains(err.Error(), errZoneAlreadySet) { - return fmt.Errorf("failed to add the address %v to %v zone: %v", ipStr, zone, err) - } - } - } - return nil -} - -func (fb *fwdBackend) Del(conf *FirewallNetConf) error { - for _, ip := range conf.PrevResult.IPs { - ipStr := ipString(ip.Address) - // Remove firewalld rules which assigned the given source IP to the given zone - firewalldObj := fb.conn.Object(firewalldName, firewalldPath) - var res string - if err := firewalldObj.Call(firewalldZoneInterface+"."+firewalldRemoveSourceMethod, 0, getFirewalldZone(conf), ipStr).Store(&res); err != nil { - logrus.Errorf("unable to store firewallobj") - } - } - return nil -} diff --git a/pkg/firewall/iptables.go b/pkg/firewall/iptables.go deleted file mode 100644 index 169ddc1d7..000000000 --- a/pkg/firewall/iptables.go +++ /dev/null @@ -1,195 +0,0 @@ -// +build linux - -// Copyright 2016 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This is a "meta-plugin". It reads in its own netconf, it does not create -// any network interface but just changes the network sysctl. - -package firewall - -import ( - "fmt" - "github.com/sirupsen/logrus" - "net" - - "github.com/coreos/go-iptables/iptables" -) - -func getPrivChainRules(ip string) [][]string { - var rules [][]string - rules = append(rules, []string{"-d", ip, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}) - rules = append(rules, []string{"-s", ip, "-j", "ACCEPT"}) - return rules -} - -func ensureChain(ipt *iptables.IPTables, table, chain string) error { - chains, err := ipt.ListChains(table) - if err != nil { - return fmt.Errorf("failed to list iptables chains: %v", err) - } - for _, ch := range chains { - if ch == chain { - return nil - } - } - - return ipt.NewChain(table, chain) -} - -func generateFilterRule(privChainName string) []string { - return []string{"-m", "comment", "--comment", "CNI firewall plugin rules", "-j", privChainName} -} - -func cleanupRules(ipt *iptables.IPTables, privChainName string, rules [][]string) { - for _, rule := range rules { - if err := ipt.Delete("filter", privChainName, rule...); err != nil { - logrus.Errorf("failed to delete iptables rule %s", privChainName) - } - } -} - -func ensureFirstChainRule(ipt *iptables.IPTables, chain string, rule []string) error { - exists, err := ipt.Exists("filter", chain, rule...) - if !exists && err == nil { - err = ipt.Insert("filter", chain, 1, rule...) - } - return err -} - -func (ib *iptablesBackend) setupChains(ipt *iptables.IPTables) error { - privRule := generateFilterRule(ib.privChainName) - adminRule := generateFilterRule(ib.adminChainName) - - // Ensure our private chains exist - if err := ensureChain(ipt, "filter", ib.privChainName); err != nil { - return err - } - if err := ensureChain(ipt, "filter", ib.adminChainName); err != nil { - return err - } - - // Ensure our filter rule exists in the forward chain - if err := ensureFirstChainRule(ipt, "FORWARD", privRule); err != nil { - return err - } - - // Ensure our admin override chain rule exists in our private chain - if err := ensureFirstChainRule(ipt, ib.privChainName, adminRule); err != nil { - return err - } - - return nil -} - -func protoForIP(ip net.IPNet) iptables.Protocol { - if ip.IP.To4() != nil { - return iptables.ProtocolIPv4 - } - return iptables.ProtocolIPv6 -} - -func (ib *iptablesBackend) addRules(conf *FirewallNetConf, ipt *iptables.IPTables, proto iptables.Protocol) error { - rules := make([][]string, 0) - for _, ip := range conf.PrevResult.IPs { - if protoForIP(ip.Address) == proto { - rules = append(rules, getPrivChainRules(ipString(ip.Address))...) - } - } - - if len(rules) > 0 { - if err := ib.setupChains(ipt); err != nil { - return err - } - - // Clean up on any errors - var err error - defer func() { - if err != nil { - cleanupRules(ipt, ib.privChainName, rules) - } - }() - - for _, rule := range rules { - err = ipt.AppendUnique("filter", ib.privChainName, rule...) - if err != nil { - return err - } - } - } - - return nil -} - -func (ib *iptablesBackend) delRules(conf *FirewallNetConf, ipt *iptables.IPTables, proto iptables.Protocol) error { - rules := make([][]string, 0) - for _, ip := range conf.PrevResult.IPs { - if protoForIP(ip.Address) == proto { - rules = append(rules, getPrivChainRules(ipString(ip.Address))...) - } - } - - if len(rules) > 0 { - cleanupRules(ipt, ib.privChainName, rules) - } - - return nil -} - -type iptablesBackend struct { - protos map[iptables.Protocol]*iptables.IPTables - privChainName string - adminChainName string -} - -// iptablesBackend implements the FirewallBackend interface -var _ FirewallBackend = &iptablesBackend{} - -func newIptablesBackend() (FirewallBackend, error) { - adminChainName := "CNI-ADMIN" - - backend := &iptablesBackend{ - privChainName: "CNI-FORWARD", - adminChainName: adminChainName, - protos: make(map[iptables.Protocol]*iptables.IPTables), - } - - for _, proto := range []iptables.Protocol{iptables.ProtocolIPv4, iptables.ProtocolIPv6} { - ipt, err := iptables.NewWithProtocol(proto) - if err != nil { - return nil, fmt.Errorf("could not initialize iptables protocol %v: %v", proto, err) - } - backend.protos[proto] = ipt - } - - return backend, nil -} - -func (ib *iptablesBackend) Add(conf *FirewallNetConf) error { - for proto, ipt := range ib.protos { - if err := ib.addRules(conf, ipt, proto); err != nil { - return err - } - } - return nil -} - -func (ib *iptablesBackend) Del(conf *FirewallNetConf) error { - for proto, ipt := range ib.protos { - if err := ib.delRules(conf, ipt, proto); err != nil { - logrus.Errorf("failed to delete iptables backend rule %s", conf.IptablesAdminChainName) - } - } - return nil -} |