Skip to content

Commit

Permalink
Merge pull request #13 from aojea/no_legacy
Browse files Browse the repository at this point in the history
drop iptables support
  • Loading branch information
aojea authored Apr 23, 2024
2 parents 7daf8bf + 88bdf40 commit 35dd163
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 99 deletions.
11 changes: 9 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/prometheus/client_golang/prometheus/promhttp"
"sigs.k8s.io/knftables"
"sigs.k8s.io/kube-network-policies/pkg/networkpolicy"

utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand All @@ -34,7 +35,7 @@ func init() {
flag.StringVar(&metricsBindAddress, "metrics-bind-address", ":9080", "The IP address and port for the metrics server to serve on")

flag.Usage = func() {
fmt.Fprint(os.Stderr, "Usage: kube-netpol [options]\n\n")
fmt.Fprint(os.Stderr, "Usage: kube-network-policies [options]\n\n")
flag.PrintDefaults()
}
}
Expand All @@ -43,7 +44,12 @@ func main() {
// enable logging
klog.InitFlags(nil)
flag.Parse()
//

nft, err := knftables.New(knftables.InetFamily, "kube-network-policies")
if err != nil {
klog.Fatalf("Error initializing nftables: %v", err)
}

if _, _, err := net.SplitHostPort(metricsBindAddress); err != nil {
klog.Fatalf("error parsing metrics bind address %s : %v", metricsBindAddress, err)
}
Expand Down Expand Up @@ -85,6 +91,7 @@ func main() {

networkPolicyController := networkpolicy.NewController(
clientset,
nft,
informersFactory.Networking().V1().NetworkPolicies(),
informersFactory.Core().V1().Namespaces(),
informersFactory.Core().V1().Pods(),
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module sigs.k8s.io/kube-network-policies
go 1.22.0

require (
github.com/coreos/go-iptables v0.7.0
github.com/florianl/go-nfqueue v1.3.1
github.com/mdlayher/netlink v1.7.2
github.com/prometheus/client_golang v1.19.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
105 changes: 11 additions & 94 deletions pkg/networkpolicy/controller.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package networkpolicy

import (
"bytes"
"context"
"fmt"
"os/exec"
"strconv"
"strings"
"time"

"github.com/coreos/go-iptables/iptables"
nfqueue "github.com/florianl/go-nfqueue"
"github.com/mdlayher/netlink"

Expand Down Expand Up @@ -47,7 +42,7 @@ import (
// https://netfilter.org/projects/libnetfilter_queue/doxygen/html/

const (
controllerName = "kube-netpol"
controllerName = "kube-network-policies"
podIPIndex = "podIPKeyIndex"
)

Expand All @@ -56,28 +51,9 @@ type Config struct {
QueueID int
}

// detect if the system uses iptables legacy
func iptablesLegacy() bool {
// only support IPv4 with iptables for simplicity
path, err := exec.LookPath("iptables")
if err != nil {
return false
}
cmd := exec.Command(path, "--version")
var out bytes.Buffer
cmd.Stdout = &out
err = cmd.Run()
if err != nil {
return false
}
if strings.Contains(out.String(), "legacy") {
return true
}
return false
}

// NewController returns a new *Controller.
func NewController(client clientset.Interface,
nft knftables.Interface,
networkpolicyInformer networkinginformers.NetworkPolicyInformer,
namespaceInformer coreinformers.NamespaceInformer,
podInformer coreinformers.PodInformer,
Expand All @@ -92,30 +68,7 @@ func NewController(client clientset.Interface,
c := &Controller{
client: client,
config: config,
}

if iptablesLegacy() {
ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
if err != nil {
klog.Fatalf("Error creating iptables: %v", err)
}
klog.Infof("Using iptables legacy")
c.ipt = ipt
} else {
nft, err := knftables.New(knftables.InetFamily, "kube-netpol")
if err != nil {
klog.Infof("Error initializing nftables: %v", err)
ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
if err != nil {
klog.Fatalf("Error creating iptables: %v", err)
}
klog.Infof("Using iptables")
c.ipt = ipt
} else {
klog.Infof("Using nftables")
c.nft = nft
}

nft: nft,
}

err := podInformer.Informer().AddIndexers(cache.Indexers{
Expand Down Expand Up @@ -211,7 +164,6 @@ type Controller struct {
getPodAssignedToIP func(podIP string) *v1.Pod

nft knftables.Interface // install the necessary nftables rules
ipt *iptables.IPTables // on old systems we need to support iptables
nfq *nfqueue.Nfqueue
flushed bool
}
Expand Down Expand Up @@ -250,21 +202,14 @@ func (c *Controller) Run(ctx context.Context) error {

}, 30*time.Second)

if c.ipt != nil {
// Start the workers after the repair loop to avoid races
klog.Info("Syncing iptables rules")
c.syncIptablesRules()
defer c.cleanIptablesRules()
go wait.Until(c.syncIptablesRules, 60*time.Second, ctx.Done())
} else {
klog.Info("Syncing nftables rules")
c.syncNFTablesRules(ctx)
defer c.cleanNFTablesRules()
// FIXME: there should be no need to ever resync our rules, but if we're going to
// do that, then knftables should provide us with an API to tell us when we need
// to resync (using `nft monitor` or direct netlink), rather than us polling.
go wait.Until(func() { c.syncNFTablesRules(ctx) }, 60*time.Second, ctx.Done())
}
// Start the workers after the repair loop to avoid races
klog.Info("Syncing nftables rules")
c.syncNFTablesRules(ctx)
defer c.cleanNFTablesRules()
// FIXME: there should be no need to ever resync our rules, but if we're going to
// do that, then knftables should provide us with an API to tell us when we need
// to resync (using `nft monitor` or direct netlink), rather than us polling.
go wait.Until(func() { c.syncNFTablesRules(ctx) }, 60*time.Second, ctx.Done())

var flags uint32
// https://netfilter.org/projects/libnetfilter_queue/doxygen/html/group__Queue.html
Expand Down Expand Up @@ -406,31 +351,3 @@ func (c *Controller) cleanNFTablesRules() {
klog.Infof("error deleting nftables rules %v", err)
}
}

func (c *Controller) syncIptablesRules() {
queueRule := []string{"-m", "conntrack", "--ctstate", "NEW", "-j", "NFQUEUE", "--queue-num", strconv.Itoa(c.config.QueueID)}
if c.config.FailOpen {
queueRule = append(queueRule, "--queue-bypass")
}

// kube-proxy install the reject rules for Services with Endpoints on the FORWARD hook
// nfqueue either accepts or drops https://netfilter-devel.vger.kernel.narkive.com/dGk9ZPzK/nfqueue-target-with-treat-accept-as-continue
// We can append the rule after the kube-proxy ones, but that will always depend on the order of the components
// to be installed so it will be racy.
// Since nftables does not seem to have that problem and we only offer iptables-legacy for backwards compatibility
// use the mangle table that happens before for filtering.
if err := c.ipt.InsertUnique("mangle", "FORWARD", 1, queueRule...); err != nil {
klog.Infof("error syncing iptables rule %v", err)
}
}

func (c *Controller) cleanIptablesRules() {
queueRule := []string{"-m", "conntrack", "--ctstate", "NEW", "-j", "NFQUEUE", "--queue-num", strconv.Itoa(c.config.QueueID)}
if c.config.FailOpen {
queueRule = append(queueRule, "--queue-bypass")
}

if err := c.ipt.Delete("mangle", "FORWARD", queueRule...); err != nil {
klog.Infof("error deleting iptables rule %v", err)
}
}
2 changes: 2 additions & 0 deletions pkg/networkpolicy/networkpolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"k8s.io/component-base/logs"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"
"sigs.k8s.io/knftables"
)

type netpolTweak func(networkPolicy *networkingv1.NetworkPolicy)
Expand Down Expand Up @@ -104,6 +105,7 @@ func newController() *networkpolicyController {
client := fake.NewSimpleClientset()
informersFactory := informers.NewSharedInformerFactory(client, 0)
controller := NewController(client,
&knftables.Fake{},
informersFactory.Networking().V1().NetworkPolicies(),
informersFactory.Core().V1().Namespaces(),
informersFactory.Core().V1().Pods(),
Expand Down

0 comments on commit 35dd163

Please sign in to comment.