Compare commits

...

5 Commits

Author SHA1 Message Date
Antonio Ojea 59e6939b4a
Merge 1e48c1007e into e2fedeb355 2025-03-13 11:38:04 +01:00
Jan Schär e2fedeb355
Improve safety of ID allocation (#307)
There was an existing mechanism to allocate IDs for sets, but this was
using a global counter without any synchronization to prevent data
races. I replaced this by a new mechanism which uses a connection-scoped
counter, protected by the Conn.mu Mutex. This can then also be used in
other places where IDs need to be allocated.

As an additional safeguard, it will panic instead of allocating the same
ID twice in a transaction. Most likely, your program will run out of
memory before reaching this point.
2025-03-13 10:38:46 +01:00
Michael Stapelberg a24f918d08 go.{mod,sum}: update to latest x/ packages 2025-03-13 09:42:41 +01:00
Michael Stapelberg 3163cd89a9 go.mod: bump language version to go1.23
Our dependencies like golang.org/x/net use go1.23 (the oldest still-supported
version, latest is go1.24), so it is time for us to upgrade, too.
2025-03-13 09:41:52 +01:00
Antonio Ojea 1e48c1007e nf2go: convert nftables rules to golang code
One of the biggest barriers to adopt the netlink format for nftables is
the complexity of writing bytecode.

This commits adds a tool that allows to take an nftables dump and
generate the corresponding golang code and validating that the generated
code produces the exact same output.

Change-Id: I491b35e0d8062de33c67091dd4126d843b231838
Signed-off-by: Antonio Ojea <aojea@google.com>
2025-02-03 15:16:57 +00:00
7 changed files with 901 additions and 17 deletions

33
conn.go
View File

@ -17,6 +17,7 @@ package nftables
import (
"errors"
"fmt"
"math"
"os"
"sync"
"syscall"
@ -38,12 +39,14 @@ type Conn struct {
TestDial nltest.Func // for testing only; passed to nltest.Dial
NetNS int // fd referencing the network namespace netlink will interact with.
lasting bool // establish a lasting connection to be used across multiple netlink operations.
mu sync.Mutex // protects the following state
messages []netlink.Message
err error
nlconn *netlink.Conn // netlink socket using NETLINK_NETFILTER protocol.
sockOptions []SockOption
lasting bool // establish a lasting connection to be used across multiple netlink operations.
mu sync.Mutex // protects the following state
messages []netlink.Message
err error
nlconn *netlink.Conn // netlink socket using NETLINK_NETFILTER protocol.
sockOptions []SockOption
lastID uint32
allocatedIDs uint32
}
// ConnOption is an option to change the behavior of the nftables Conn returned by Open.
@ -244,6 +247,7 @@ func (cc *Conn) Flush() error {
cc.mu.Lock()
defer func() {
cc.messages = nil
cc.allocatedIDs = 0
cc.mu.Unlock()
}()
if len(cc.messages) == 0 {
@ -369,3 +373,20 @@ func batch(messages []netlink.Message) []netlink.Message {
return batch
}
// allocateTransactionID allocates an identifier which is only valid in the
// current transaction.
func (cc *Conn) allocateTransactionID() uint32 {
if cc.allocatedIDs == math.MaxUint32 {
panic(fmt.Sprintf("trying to allocate more than %d IDs in a single nftables transaction", math.MaxUint32))
}
// To make it more likely to catch when a transaction ID is erroneously used
// in a later transaction, cc.lastID is not reset after each transaction;
// instead it is only reset once it rolls over from math.MaxUint32 to 0.
cc.allocatedIDs++
cc.lastID++
if cc.lastID == 0 {
cc.lastID = 1
}
return cc.lastID
}

6
go.mod
View File

@ -1,17 +1,17 @@
module github.com/google/nftables
go 1.21
go 1.23.0
require (
github.com/google/go-cmp v0.6.0
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42
github.com/vishvananda/netlink v1.3.0
github.com/vishvananda/netns v0.0.4
golang.org/x/sys v0.28.0
golang.org/x/sys v0.31.0
)
require (
github.com/mdlayher/socket v0.5.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/net v0.37.0 // indirect
golang.org/x/sync v0.6.0 // indirect
)

8
go.sum
View File

@ -8,11 +8,11 @@ github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQ
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=

299
internal/nf2go/main.go Normal file
View File

@ -0,0 +1,299 @@
package main
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/nftables"
"github.com/vishvananda/netns"
)
func main() {
args := os.Args[1:]
if len(args) != 1 {
log.Fatalf("need to specify the file to read the \"nft list ruleset\" dump")
}
filename := args[0]
runtime.LockOSThread()
defer runtime.UnlockOSThread()
// Create a new network namespace
ns, err := netns.New()
if err != nil {
log.Fatalf("netns.New() failed: %v", err)
}
n, err := nftables.New(nftables.WithNetNSFd(int(ns)))
if err != nil {
log.Fatalf("nftables.New() failed: %v", err)
}
scriptOutput, err := applyNFTRuleset(filename)
if err != nil {
log.Fatalf("Failed to apply nftables script: %v\noutput:%s", err, scriptOutput)
}
var buf bytes.Buffer
// Helper function to print to the file
pf := func(format string, a ...interface{}) {
_, err := fmt.Fprintf(&buf, format, a...)
if err != nil {
log.Fatal(err)
}
}
pf("// Code generated by nft2go. DO NOT EDIT.\n")
pf("package main\n\n")
pf("import (\n")
pf("\t\"fmt\"\n")
pf("\t\"log\"\n")
pf("\t\"github.com/google/nftables\"\n")
pf("\t\"github.com/google/nftables/expr\"\n")
pf(")\n\n")
pf("func main() {\n")
pf("\tn, err:= nftables.New()\n")
pf("\tif err!= nil {\n")
pf("\t\tlog.Fatal(err)\n")
pf("\t}\n\n")
pf("\n")
pf("\tvar expressions []expr.Any\n")
pf("\tvar chain *nftables.Chain\n")
pf("\tvar table *nftables.Table\n")
tables, err := n.ListTables()
if err != nil {
log.Fatalf("ListTables failed: %v", err)
}
chains, err := n.ListChains()
if err != nil {
log.Fatal(err)
}
for _, table := range tables {
log.Printf("processing table: %s", table.Name)
pf("\ttable = n.AddTable(&nftables.Table{Family: %s,Name: \"%s\"})\n", TableFamilyString(table.Family), table.Name)
for _, chain := range chains {
if chain.Table.Name != table.Name {
continue
}
sets, err := n.GetSets(table)
if err != nil {
log.Fatal(err)
}
for _, set := range sets {
// TODO datatype and the other options
pf("\tn.AddSet(&nftables.Set{\n")
pf("\t\tTable: table,\n")
pf("\t\tName: \"%s\",\n", set.Name)
pf("\t}, nil)\n")
}
pf("\tchain = n.AddChain(&nftables.Chain{Name: \"%s\", Table: table, Type: %s, Hooknum: %s, Priority: %s})\n",
chain.Name, ChainTypeString(chain.Type), ChainHookRef(chain.Hooknum), ChainPrioRef(chain.Priority))
rules, err := n.GetRules(table, chain)
if err != nil {
log.Fatal(err)
}
for _, rule := range rules {
pf("\texpressions = []expr.Any{\n")
for _, exp := range rule.Exprs {
pf("\t\t%#v,\n", exp)
}
pf("\t\t}\n")
pf("\tn.AddRule(&nftables.Rule{\n")
pf("\t\tTable: table,\n")
pf("\t\tChain: chain,\n")
pf("\t\tExprs: expressions,\n")
pf("\t})\n")
}
}
}
pf("\n\tif err:= n.Flush(); err!= nil {\n")
pf("\t\tlog.Fatal(err)\n")
pf("\t}\n\n")
pf("\tfmt.Println(\"nft ruleset applied.\")\n")
pf("}\n")
// Program nftables using your Go code
if err := flushNFTRuleset(); err != nil {
log.Fatalf("Failed to flush nftables ruleset: %v", err)
}
// Create the output file
// Create a temporary directory
tempDir, err := ioutil.TempDir("", "nftables_gen")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(tempDir) // Clean up the temporary directory
// Create the temporary Go file
tempGoFile := filepath.Join(tempDir, "nftables_recreate.go")
f, err := os.Create(tempGoFile)
if err != nil {
log.Fatal(err)
}
defer f.Close()
mw := io.MultiWriter(f, os.Stdout)
buf.WriteTo(mw)
// Format the generated code
log.Printf("formating file: %s", tempGoFile)
cmd := exec.Command("gofmt", "-w", "-s", tempGoFile)
output, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("gofmt error: %v\nOutput: %s", err, output)
}
// Run the generated code
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
log.Printf("executing file: %s", tempGoFile)
cmd = exec.CommandContext(ctx, "go", "run", tempGoFile)
output, err = cmd.CombinedOutput()
if err != nil {
log.Fatalf("Execution error: %v\nOutput: %s", err, output)
}
// Retrieve nftables state using nft
log.Printf("obtain current ruleset: %s", tempGoFile)
actualOutput, err := listNFTRuleset()
if err != nil {
log.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, actualOutput)
}
expectedOutput, err := os.ReadFile(filename)
if err != nil {
log.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, actualOutput)
}
if !compareMultilineStringsIgnoreIndentation(string(expectedOutput), actualOutput) {
log.Printf("Expected output:\n%s", string(expectedOutput))
log.Printf("Actual output:\n%s", actualOutput)
log.Fatalf("nftables ruleset mismatch:\n%s", cmp.Diff(string(expectedOutput), actualOutput))
}
if err := flushNFTRuleset(); err != nil {
log.Fatalf("Failed to flush nftables ruleset: %v", err)
}
}
func applyNFTRuleset(scriptPath string) (string, error) {
cmd := exec.Command("nft", "--debug=netlink", "-f", scriptPath)
out, err := cmd.CombinedOutput()
if err != nil {
return string(out), err
}
return strings.TrimSpace(string(out)), nil
}
func listNFTRuleset() (string, error) {
cmd := exec.Command("nft", "list", "ruleset")
out, err := cmd.CombinedOutput()
if err != nil {
return string(out), err
}
return strings.TrimSpace(string(out)), nil
}
func flushNFTRuleset() error {
cmd := exec.Command("nft", "flush", "ruleset")
return cmd.Run()
}
func ChainHookRef(hookNum *nftables.ChainHook) string {
i := uint32(0)
if hookNum != nil {
i = uint32(*hookNum)
}
switch i {
case 0:
return "nftables.ChainHookPrerouting"
case 1:
return "nftables.ChainHookInput"
case 2:
return "nftables.ChainHookForward"
case 3:
return "nftables.ChainHookOutput"
case 4:
return "nftables.ChainHookPostrouting"
case 5:
return "nftables.ChainHookIngress"
case 6:
return "nftables.ChainHookEgress"
}
return ""
}
func ChainPrioRef(priority *nftables.ChainPriority) string {
i := int32(0)
if priority != nil {
i = int32(*priority)
}
return fmt.Sprintf("nftables.ChainPriorityRef(%d)", i)
}
func ChainTypeString(chaintype nftables.ChainType) string {
switch chaintype {
case nftables.ChainTypeFilter:
return "nftables.ChainTypeFilter"
case nftables.ChainTypeRoute:
return "nftables.ChainTypeRoute"
case nftables.ChainTypeNAT:
return "nftables.ChainTypeNAT"
default:
return "nftables.ChainTypeFilter"
}
}
func TableFamilyString(family nftables.TableFamily) string {
switch family {
case nftables.TableFamilyUnspecified:
return "nftables.TableFamilyUnspecified"
case nftables.TableFamilyINet:
return "nftables.TableFamilyINet"
case nftables.TableFamilyIPv4:
return "nftables.TableFamilyIPv4"
case nftables.TableFamilyIPv6:
return "nftables.TableFamilyIPv6"
case nftables.TableFamilyARP:
return "nftables.TableFamilyARP"
case nftables.TableFamilyNetdev:
return "nftables.TableFamilyNetdev"
case nftables.TableFamilyBridge:
return "nftables.TableFamilyBridge"
default:
return "nftables.TableFamilyIPv4"
}
}
func compareMultilineStringsIgnoreIndentation(str1, str2 string) bool {
// Remove all indentation from both strings
re := regexp.MustCompile(`(?m)^\s+`)
str1 = re.ReplaceAllString(str1, "")
str2 = re.ReplaceAllString(str2, "")
return str1 == str2
}

550
internal/nf2go/rules.txt Normal file
View File

@ -0,0 +1,550 @@
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
counter packets 769 bytes 46239 jump KUBE-SERVICES
ip daddr 192.168.8.1 counter packets 0 bytes 0 jump DOCKER_OUTPUT
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
counter packets 245348 bytes 14721139 jump KUBE-SERVICES
ip daddr 192.168.8.1 counter packets 122 bytes 9151 jump DOCKER_OUTPUT
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
counter packets 246110 bytes 14766910 jump KUBE-POSTROUTING
ip daddr 192.168.8.1 counter packets 0 bytes 0 jump DOCKER_POSTROUTING
}
chain DOCKER_OUTPUT {
ip daddr 192.168.8.1 tcp dport 53 counter packets 0 bytes 0 dnat to 127.0.0.11:36405
ip daddr 192.168.8.1 udp dport 53 counter packets 122 bytes 9151 dnat to 127.0.0.11:39066
}
chain DOCKER_POSTROUTING {
ip saddr 127.0.0.11 tcp sport 36405 counter packets 0 bytes 0 snat to 192.168.8.1:53
ip saddr 127.0.0.11 udp sport 39066 counter packets 0 bytes 0 snat to 192.168.8.1:53
}
chain KUBE-KUBELET-CANARY {
}
chain KUBE-PROXY-CANARY {
}
chain KUBE-SERVICES {
meta l4proto tcp ip daddr 10.96.0.10 tcp dport 9153 counter packets 0 bytes 0 jump KUBE-SVC-JD5MR3NA4I4DYORP
meta l4proto udp ip daddr 10.96.0.10 udp dport 53 counter packets 0 bytes 0 jump KUBE-SVC-TCOU7JCQXEZGVUNU
meta l4proto tcp ip daddr 10.96.106.185 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-D5JKTLXOFYHV5HQZ
meta l4proto tcp ip daddr 10.96.70.203 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-IB3WK5BQ64FMB5FP
meta l4proto tcp ip daddr 10.96.0.10 tcp dport 53 counter packets 13 bytes 780 jump KUBE-SVC-ERIFXISQEP7F7OF4
meta l4proto tcp ip daddr 10.96.86.60 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-QUBDBT4PCRU7S2PI
meta l4proto tcp ip daddr 10.96.184.88 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-ZD23KKVZJDKFKTCE
meta l4proto tcp ip daddr 10.96.149.162 tcp dport 443 counter packets 0 bytes 0 jump KUBE-SVC-WHNIZNLB5XFXIX2C
meta l4proto tcp ip daddr 10.96.225.221 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-ROH4UCJ7RVN2OSM4
meta l4proto tcp ip daddr 10.96.50.119 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-SB7WEE53EMIXFNKY
meta l4proto tcp ip daddr 10.96.230.205 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-OJLEMCF5KYSTXAAJ
meta l4proto tcp ip daddr 10.96.149.162 tcp dport 15014 counter packets 0 bytes 0 jump KUBE-SVC-XHUBMW47Y5G3ICIS
meta l4proto tcp ip daddr 10.96.83.127 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-4MYBDLPZ2DFGC5Z6
meta l4proto tcp ip daddr 10.96.245.249 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-53SQRANQXVHTJ6HK
meta l4proto tcp ip daddr 10.96.85.31 tcp dport 9090 counter packets 0 bytes 0 jump KUBE-SVC-VVO7BBXOSCJQDQML
meta l4proto tcp ip daddr 10.96.0.1 tcp dport 443 counter packets 0 bytes 0 jump KUBE-SVC-NPX46M4PTMTKRN6Y
meta l4proto tcp ip daddr 10.96.113.49 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-SVC-COV23IKAKYWND6VU
meta l4proto tcp ip daddr 10.96.149.162 tcp dport 15010 counter packets 0 bytes 0 jump KUBE-SVC-NVNLZVDQSGQUD3NM
meta l4proto tcp ip daddr 10.96.231.15 tcp dport 3000 counter packets 0 bytes 0 jump KUBE-SVC-XUJLWDDTZEWKLHU6
meta l4proto tcp ip daddr 10.96.149.162 tcp dport 15012 counter packets 2 bytes 120 jump KUBE-SVC-CG3LQLBYYHBKATGN
fib daddr type local counter packets 329 bytes 19740 jump KUBE-NODEPORTS
}
chain KUBE-POSTROUTING {
meta mark & 0x00004000 != 0x00004000 counter packets 1593 bytes 95580 return
counter packets 13 bytes 780 meta mark set mark xor 0x4000
counter packets 13 bytes 780 masquerade fully-random
}
chain KUBE-NODEPORTS {
meta l4proto tcp tcp dport 30207 counter packets 0 bytes 0 jump KUBE-EXT-VVO7BBXOSCJQDQML
meta l4proto tcp tcp dport 31182 counter packets 0 bytes 0 jump KUBE-EXT-XUJLWDDTZEWKLHU6
}
chain KUBE-MARK-MASQ {
counter packets 13 bytes 780 meta mark set mark or 0x4000
}
chain KUBE-SVC-COV23IKAKYWND6VU {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.113.49 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-UYFG3BP6SBY2ENL5
}
chain KUBE-SVC-OJLEMCF5KYSTXAAJ {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.230.205 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-4Y5RNE5AMASHQ2OZ
}
chain KUBE-SVC-4MYBDLPZ2DFGC5Z6 {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.83.127 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-VLSRDM63ATDZAA3A
}
chain KUBE-SVC-53SQRANQXVHTJ6HK {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.245.249 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta random & 2147483647 < 715827883 counter packets 0 bytes 0 jump KUBE-SEP-AYXBHI7HU6SF34DI
meta random & 2147483647 < 1073741824 counter packets 0 bytes 0 jump KUBE-SEP-PBXQV3T6XQVEVBGL
counter packets 0 bytes 0 jump KUBE-SEP-WLEZNEPJCJLP5SOM
}
chain KUBE-EXT-VVO7BBXOSCJQDQML {
counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SVC-VVO7BBXOSCJQDQML
}
chain KUBE-SVC-VVO7BBXOSCJQDQML {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.85.31 tcp dport 9090 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-6ZOGXI2ZCDJV5G4O
}
chain KUBE-SVC-NPX46M4PTMTKRN6Y {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.0.1 tcp dport 443 counter packets 29 bytes 1740 jump KUBE-MARK-MASQ
counter packets 30 bytes 1800 jump KUBE-SEP-B5DUEXKFRYN46BFH
}
chain KUBE-SEP-B5DUEXKFRYN46BFH {
ip saddr 192.168.8.4 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 30 bytes 1800 dnat to 192.168.8.4:6443
}
chain KUBE-EXT-XUJLWDDTZEWKLHU6 {
counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SVC-XUJLWDDTZEWKLHU6
}
chain KUBE-SVC-XUJLWDDTZEWKLHU6 {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.231.15 tcp dport 3000 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-AEOIAT7KXYABTON5
}
chain KUBE-SVC-D5JKTLXOFYHV5HQZ {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.106.185 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-IRX4MQBX4KRVQAZU
}
chain KUBE-SVC-IB3WK5BQ64FMB5FP {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.70.203 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-ME7B5OZS3EMRJJUS
}
chain KUBE-SVC-SB7WEE53EMIXFNKY {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.50.119 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-UBXSLXFPFJOARYRN
}
chain KUBE-SVC-QUBDBT4PCRU7S2PI {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.86.60 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-ENYDTZIVOME6TBBV
}
chain KUBE-SVC-ZD23KKVZJDKFKTCE {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.184.88 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-5KXO57AZTMNCDCVX
}
chain KUBE-SVC-ROH4UCJ7RVN2OSM4 {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.225.221 tcp dport 9080 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-YMBKJHKN7Y2F6666
}
chain KUBE-SEP-YMBKJHKN7Y2F6666 {
ip saddr 10.244.1.189 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.189:9080
}
chain KUBE-SEP-5KXO57AZTMNCDCVX {
ip saddr 10.244.1.189 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.189:9080
}
chain KUBE-SEP-UBXSLXFPFJOARYRN {
ip saddr 10.244.1.108 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.108:9080
}
chain KUBE-SEP-ENYDTZIVOME6TBBV {
ip saddr 10.244.1.108 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.108:9080
}
chain KUBE-SEP-6ZOGXI2ZCDJV5G4O {
ip saddr 10.244.1.9 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.9:9090
}
chain KUBE-SEP-UYFG3BP6SBY2ENL5 {
ip saddr 10.244.1.215 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.215:9080
}
chain KUBE-SEP-4Y5RNE5AMASHQ2OZ {
ip saddr 10.244.2.98 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.2.98:9080
}
chain KUBE-SEP-VLSRDM63ATDZAA3A {
ip saddr 10.244.1.237 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.237:9080
}
chain KUBE-SEP-AYXBHI7HU6SF34DI {
ip saddr 10.244.1.131 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.131:9080
}
chain KUBE-SEP-PBXQV3T6XQVEVBGL {
ip saddr 10.244.1.215 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.215:9080
}
chain KUBE-SEP-WLEZNEPJCJLP5SOM {
ip saddr 10.244.2.98 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.2.98:9080
}
chain KUBE-SEP-AEOIAT7KXYABTON5 {
ip saddr 10.244.1.13 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.13:3000
}
chain KUBE-SEP-IRX4MQBX4KRVQAZU {
ip saddr 10.244.1.237 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.237:9080
}
chain KUBE-SEP-ME7B5OZS3EMRJJUS {
ip saddr 10.244.1.131 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.1.131:9080
}
chain KUBE-SVC-WHNIZNLB5XFXIX2C {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.149.162 tcp dport 443 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-22OJIEOUHUS2VH36
}
chain KUBE-SEP-22OJIEOUHUS2VH36 {
ip saddr 10.244.2.88 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.2.88:15017
}
chain KUBE-SVC-XHUBMW47Y5G3ICIS {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.149.162 tcp dport 15014 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-N6BCKY3MRNRV2ZJ2
}
chain KUBE-SEP-N6BCKY3MRNRV2ZJ2 {
ip saddr 10.244.2.88 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.2.88:15014
}
chain KUBE-SVC-CG3LQLBYYHBKATGN {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.149.162 tcp dport 15012 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 259 bytes 15540 jump KUBE-SEP-E675BOVPZS3XINT6
}
chain KUBE-SEP-E675BOVPZS3XINT6 {
ip saddr 10.244.2.88 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 259 bytes 15540 dnat to 10.244.2.88:15012
}
chain KUBE-SVC-NVNLZVDQSGQUD3NM {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.149.162 tcp dport 15010 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
counter packets 0 bytes 0 jump KUBE-SEP-E2OCVXQ5RANXZKNO
}
chain KUBE-SEP-E2OCVXQ5RANXZKNO {
ip saddr 10.244.2.88 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.2.88:15010
}
chain KUBE-SVC-ERIFXISQEP7F7OF4 {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.0.10 tcp dport 53 counter packets 1718 bytes 103080 jump KUBE-MARK-MASQ
meta random & 2147483647 < 1073741824 counter packets 875 bytes 52500 jump KUBE-SEP-IH2TMTJLEHQTEXG4
counter packets 843 bytes 50580 jump KUBE-SEP-QHHO2BBHA2W6ABVA
}
chain KUBE-SEP-IH2TMTJLEHQTEXG4 {
ip saddr 10.244.0.44 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 875 bytes 52500 dnat to 10.244.0.44:53
}
chain KUBE-SVC-JD5MR3NA4I4DYORP {
meta l4proto tcp ip saddr != 10.244.0.0/16 ip daddr 10.96.0.10 tcp dport 9153 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta random & 2147483647 < 1073741824 counter packets 0 bytes 0 jump KUBE-SEP-KTQ44RRS25IYXDAU
counter packets 0 bytes 0 jump KUBE-SEP-SWQQGKEGIJFNRJRL
}
chain KUBE-SEP-KTQ44RRS25IYXDAU {
ip saddr 10.244.0.44 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.0.44:9153
}
chain KUBE-SVC-TCOU7JCQXEZGVUNU {
meta l4proto udp ip saddr != 10.244.0.0/16 ip daddr 10.96.0.10 udp dport 53 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta random & 2147483647 < 1073741824 counter packets 2 bytes 171 jump KUBE-SEP-YGFHBW2DM6N3IEK3
counter packets 0 bytes 0 jump KUBE-SEP-W3GSBK4IMEBEFHPJ
}
chain KUBE-SEP-YGFHBW2DM6N3IEK3 {
ip saddr 10.244.0.44 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto udp counter packets 2 bytes 171 dnat to 10.244.0.44:53
}
chain KUBE-SEP-QHHO2BBHA2W6ABVA {
ip saddr 10.244.0.63 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 843 bytes 50580 dnat to 10.244.0.63:53
}
chain KUBE-SEP-SWQQGKEGIJFNRJRL {
ip saddr 10.244.0.63 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto tcp counter packets 0 bytes 0 dnat to 10.244.0.63:9153
}
chain KUBE-SEP-W3GSBK4IMEBEFHPJ {
ip saddr 10.244.0.63 counter packets 0 bytes 0 jump KUBE-MARK-MASQ
meta l4proto udp counter packets 0 bytes 0 dnat to 10.244.0.63:53
}
}
table ip mangle {
chain KUBE-IPTABLES-HINT {
}
chain KUBE-KUBELET-CANARY {
}
chain KUBE-PROXY-CANARY {
}
}
table ip filter {
chain KUBE-FIREWALL {
ip saddr != 127.0.0.0/8 ip daddr 127.0.0.0/8 ct status dnat counter packets 0 bytes 0 drop
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
ct state new counter packets 245383 bytes 14723644 jump KUBE-PROXY-FIREWALL
ct state new counter packets 245383 bytes 14723644 jump KUBE-SERVICES
counter packets 3043981 bytes 2633914697 jump KUBE-FIREWALL
}
chain INPUT {
type filter hook input priority filter; policy accept;
ct state new counter packets 47332 bytes 2840200 jump KUBE-PROXY-FIREWALL
counter packets 3210147 bytes 435991279 jump KUBE-NODEPORTS
ct state new counter packets 47332 bytes 2840200 jump KUBE-EXTERNAL-SERVICES
counter packets 3210791 bytes 436579809 jump KUBE-FIREWALL
}
chain KUBE-KUBELET-CANARY {
}
chain KUBE-PROXY-CANARY {
}
chain KUBE-EXTERNAL-SERVICES {
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
ct state new counter packets 774 bytes 46491 jump KUBE-PROXY-FIREWALL
counter packets 287624 bytes 35538980 jump KUBE-FORWARD
ct state new counter packets 774 bytes 46491 jump KUBE-SERVICES
ct state new counter packets 774 bytes 46491 jump KUBE-EXTERNAL-SERVICES
}
chain KUBE-NODEPORTS {
}
chain KUBE-SERVICES {
meta l4proto tcp ip daddr 10.96.65.65 tcp dport 80 counter packets 0 bytes 0 reject
}
chain KUBE-FORWARD {
meta mark & 0x00004000 == 0x00004000 counter packets 0 bytes 0 accept
ct state related,established counter packets 1866 bytes 233783 accept
}
chain KUBE-PROXY-FIREWALL {
}
}
table ip6 mangle {
chain KUBE-IPTABLES-HINT {
}
chain KUBE-KUBELET-CANARY {
}
chain KUBE-PROXY-CANARY {
}
}
table ip6 nat {
chain KUBE-KUBELET-CANARY {
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
counter packets 0 bytes 0 jump KUBE-POSTROUTING
}
chain KUBE-PROXY-CANARY {
}
chain KUBE-SERVICES {
ip6 daddr != ::1 fib daddr type local counter packets 0 bytes 0 jump KUBE-NODEPORTS
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
counter packets 0 bytes 0 jump KUBE-SERVICES
}
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
counter packets 0 bytes 0 jump KUBE-SERVICES
}
chain KUBE-POSTROUTING {
meta mark & 0x00004000 != 0x00004000 counter packets 0 bytes 0 return
counter packets 0 bytes 0 meta mark set mark xor 0x4000
counter packets 0 bytes 0
}
chain KUBE-NODEPORTS {
}
chain KUBE-MARK-MASQ {
counter packets 0 bytes 0 meta mark set mark or 0x4000
}
}
table ip6 filter {
chain KUBE-KUBELET-CANARY {
}
chain KUBE-PROXY-CANARY {
}
chain KUBE-EXTERNAL-SERVICES {
}
chain INPUT {
type filter hook input priority filter; policy accept;
counter packets 8 bytes 552 jump KUBE-FIREWALL
ct state new counter packets 0 bytes 0 jump KUBE-PROXY-FIREWALL
counter packets 8 bytes 552 jump KUBE-NODEPORTS
ct state new counter packets 0 bytes 0 jump KUBE-EXTERNAL-SERVICES
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
ct state new counter packets 0 bytes 0 jump KUBE-PROXY-FIREWALL
counter packets 0 bytes 0 jump KUBE-FORWARD
ct state new counter packets 0 bytes 0 jump KUBE-SERVICES
ct state new counter packets 0 bytes 0 jump KUBE-EXTERNAL-SERVICES
}
chain KUBE-NODEPORTS {
}
chain KUBE-SERVICES {
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 139 bytes 7888 jump KUBE-FIREWALL
ct state new counter packets 0 bytes 0 jump KUBE-PROXY-FIREWALL
ct state new counter packets 0 bytes 0 jump KUBE-SERVICES
}
chain KUBE-FORWARD {
meta mark & 0x00004000 == 0x00004000 counter packets 0 bytes 0 accept
ct state related,established counter packets 0 bytes 0 accept
}
chain KUBE-PROXY-FIREWALL {
}
chain KUBE-FIREWALL {
}
}
table inet kindnet-network-policies {
set podips-v4 {
type ipv4_addr
}
set podips-v6 {
type ipv6_addr
}
chain postrouting {
type filter hook postrouting priority srcnat - 5; policy accept;
udp dport 53 accept
meta l4proto ipv6-icmp accept
meta skuid 0 accept
ct state established,related accept
ip saddr @podips-v4 queue flags bypass to 102
ip daddr @podips-v4 queue flags bypass to 102
ip6 saddr @podips-v6 queue flags bypass to 102
ip6 daddr @podips-v6 queue flags bypass to 102
}
chain prerouting {
type filter hook prerouting priority dstnat + 5; policy accept;
meta l4proto != udp accept
udp dport != 53 accept
ip saddr @podips-v4 queue flags bypass to 102
ip daddr @podips-v4 queue flags bypass to 102
ip6 saddr @podips-v6 queue flags bypass to 102
ip6 daddr @podips-v6 queue flags bypass to 102
}
}
table inet kindnet-dnscache {
set set-v4-nameservers {
type ipv4_addr
elements = { 10.96.0.10 }
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
ip saddr 10.244.2.0/24 ip daddr @set-v4-nameservers udp dport 53 queue flags bypass to 103
}
chain output {
type filter hook output priority raw; policy accept;
meta mark 0x0000006e udp sport 53 notrack
}
}
table inet kindnet-ipmasq {
set noMasqV4 {
type ipv4_addr
flags interval
auto-merge
elements = { 10.244.0.0/24, 10.244.1.0/24,
10.244.2.0/24 }
}
set noMasqV6 {
type ipv6_addr
flags interval
auto-merge
}
chain postrouting {
type nat hook postrouting priority srcnat - 10; policy accept;
ct state established,related accept
fib saddr type local accept
ip daddr @noMasqV4 accept
ip6 daddr @noMasqV6 accept
masquerade
}
}

View File

@ -0,0 +1,17 @@
table ip filter {
chain output {
type filter hook output priority 100; policy accept;
}
chain input {
type filter hook input priority 0; policy accept;
iifname "lan0" accept
iifname "wan0" drop
}
chain forward {
type filter hook forward priority 0; policy drop;
iifname "lan0" oifname "wan0" accept
iifname "wan0" oifname "lan0" ct state related,established accept
}
}

5
set.go
View File

@ -46,8 +46,6 @@ const (
NFTA_SET_ELEM_EXPRESSIONS = 0x11
)
var allocSetID uint32
// SetDatatype represents a datatype declared by nft.
type SetDatatype struct {
Name string
@ -532,8 +530,7 @@ func (cc *Conn) AddSet(s *Set, vals []SetElement) error {
}
if s.ID == 0 {
allocSetID++
s.ID = allocSetID
s.ID = cc.allocateTransactionID()
if s.Anonymous {
s.Name = "__set%d"
if s.IsMap {