Code Monkey home page Code Monkey logo

Comments (5)

turekt avatar turekt commented on May 28, 2024 2

Hi,

I believe that the Data field in your first &expr.Cmp is not properly aligned. Here is the code that works:

c, _ := nftables.New()

matchTable := &nftables.Table{
	Family: nftables.TableFamilyIPv4,
	Name:   "filter",
}

matchChain := &nftables.Chain{
	Name:  "forward",
	Table: matchTable,
}

c.AddRule(&nftables.Rule{
	Table: matchTable,
	Chain: matchChain,
	Exprs: []expr.Any{
		&expr.Meta{Key: expr.MetaKeyIIFTYPE, Register: 1},
		&expr.Cmp{
			Op:       expr.CmpOpEq,
			Register: 1,
			Data:     []byte{0x01, 0x00},
		},
		&expr.Payload{
			DestRegister: 1,
			Base:         expr.PayloadBaseLLHeader,
			Offset:       6,
			Len:          6,
		},
		&expr.Cmp{
			Op:       expr.CmpOpEq,
			Register: 1,
			Data:     []byte{0xc4, 0xa4, 0x02, 0x7a, 0x25, 0x30},
		},
		&expr.Log{
			Key:        uint32(1 << unix.NFTA_LOG_PREFIX),
			QThreshold: uint16(20),
			Group:      uint16(1),
			Snaplen:    uint32(132),
			Data:       []byte("accept-log"),
		},
		&expr.Verdict{
			Kind: expr.VerdictAccept,
		},
	},
})

if err := c.Flush(); err != nil {
	fmt.Printf("nftables.Flush() failed: %v", err)
}

Running it gives the desired result:

# go run main.go && nft list ruleset
table ip filter {
	chain input {
		type filter hook input priority filter; policy accept;
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ether saddr c4:a4:02:7a:25:30 log prefix "accept-log" accept
	}

	chain output {
		type filter hook output priority filter; policy accept;
	}
}

I hope that this fixes your issue.

from nftables.

stapelberg avatar stapelberg commented on May 28, 2024 1

It’s impossible to answer such a short question without any details or code.

Please explain what you’re trying to do, please post your code and let us know which error you’re getting.

from nftables.

ymm135 avatar ymm135 commented on May 28, 2024 1

code

   if len(policy.SMac) > 0 {
		sMacSet := nftables.Set{
			Name:    "smac-set",
			ID:      uint32(1), //rand.Intn(0xffff)),
			Table:   p.Table,
			KeyType: nftables.TypeEtherAddr,
		}

		fmt.Println(sMacSet)

		if err := p.Nft.Conn.AddSet(&sMacSet, []nftables.SetElement{{Key: []byte{0x90, 0xb8, 0xe0, 0x01, 0x4b, 0x0}}}); err != nil {
			fmt.Printf("AddSet %v\n", err)
		}

		exprs = append(exprs, &expr.Lookup{
			SetID:   sMacSet.ID,
			SetName: sMacSet.Name,
		})
	}

nft list ruleset

set smac-set {
		type ether_addr
		elements = { 00:4b:01:e0:b8:90 }
	}

	chain FORWARD {
		type filter hook input priority filter; policy accept;
		iifname "enp1s0" oifname "enp2s0" ip saddr != 10.25.16.0-10.25.16.255 ip daddr != 10.25.10.0-10.25.10.255 tcp dport 22 log prefix "accept log " accept
	}

My desired result is

set smac-set {
		type ether_addr
		elements = { 00:4b:01:e0:b8:90 }
	}

	chain FORWARD {
		type filter hook input priority filter; policy accept;
		iifname "enp1s0" oifname "enp2s0" ip saddr != 10.25.16.0-10.25.16.255 ip daddr != 10.25.10.0-10.25.10.255 ether saddr @smac-set tcp dport 22 log prefix "accept log " accept
	}

ether saddr @smac-set

Did I describe clearly enough ?
I don't know how to set nftables rules for mac address through api !

from nftables.

stapelberg avatar stapelberg commented on May 28, 2024 1

Thanks for the additional details. Can you share your full code which constructs the rules? Without a working program, it will be a lot of work to look into the issue. You should make it as easy as possible for others to help you :)

When I run your ruleset through nft --debug=all -f /tmp/ruleset, I get:

ip nat FORWARD
  [ meta load iifname => reg 1 ]
  [ cmp eq reg 1 0x31706e65 0x00003073 0x00000000 0x00000000 ]
  [ meta load oifname => reg 1 ]
  [ cmp eq reg 1 0x32706e65 0x00003073 0x00000000 0x00000000 ]
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ range neq reg 1 0x0010190a 0xff10190a ]
  [ payload load 4b @ network header + 16 => reg 1 ]
  [ range neq reg 1 0x000a190a 0xff0a190a ]
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 6b @ link header + 6 => reg 1 ]
  [ lookup reg 1 set smac-set ]
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000006 ]
  [ payload load 2b @ transport header + 2 => reg 1 ]
  [ cmp eq reg 1 0x00001600 ]
  [ log prefix accept log  ]
  [ immediate reg 0 accept ]

It might be good to simplify your issue to the simplest possible ruleset that shows the problem. For example, you could remove all the IP source/destination address checking and port checking to make this a little easier to work with.

from nftables.

ymm135 avatar ymm135 commented on May 28, 2024

@stapelberg thanks for your reply!

The rule that I want to generate is :
rules.nft

table ip filter {
	chain FORWARD {
		ether saddr c4:a4:02:7a:25:30 log prefix "accept-log" accept
	}
}

When I run your ruleset through nft --debug=netlink -f rules.nft, I get:

ip (null) (null) use 0
ip filter FORWARD
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 6b @ link header + 6 => reg 1 ]
  [ cmp eq reg 1 0x7a02a4c4 0x00003025 ]
  [ log prefix accept-log ]
  [ immediate reg 0 accept ]

my code is :

package main

import (
	"fmt"
	"runtime"

	"github.com/google/nftables"
	"github.com/google/nftables/expr"
	"github.com/vishvananda/netns"
	"golang.org/x/sys/unix"
)

// the running kernel in a separate network namespace.
// cleanupSystemNFTConn() must be called from a defer to cleanup
// created network namespace.
func openSystemNFTConn() (*nftables.Conn, netns.NsHandle) {
	runtime.LockOSThread()

	// init pid
	const init_pid = 1
	ns, err := netns.GetFromPid(init_pid)

	if err != nil {
		fmt.Sprintln("GetFromPid err", err.Error())
	}

	c, err := nftables.New(nftables.WithNetNSFd(int(ns)))

	if err != nil {
		fmt.Sprintln("nftables.New() failed", err.Error())
	}
	return c, ns
}

func cleanupSystemNFTConn(newNS netns.NsHandle) {
	defer runtime.UnlockOSThread()

	if err := newNS.Close(); err != nil {
		fmt.Printf("newNS.Close() failed: %v", err)
	}
}

func main() {
	c, ns := openSystemNFTConn()
	defer cleanupSystemNFTConn(ns)

	c.FlushRuleset()

	filter := c.AddTable(&nftables.Table{
		Family: nftables.TableFamilyIPv4,
		Name:   "filter",
	})

	filterChain := c.AddChain(&nftables.Chain{
		Name:     "FORWARD",
		Table:    filter,
		Type:     nftables.ChainTypeFilter,
		Hooknum:  nftables.ChainHookInput,
		Priority: nftables.ChainPriorityFilter,
	})

	keyGQ := uint32((1 << unix.NFTA_LOG_PREFIX))

	c.AddRule(&nftables.Rule{
		Table: filter,
		Chain: filterChain,
		Exprs: []expr.Any{
			// meta load iiftype => reg 1
			&expr.Meta{Key: expr.MetaKeyIIFTYPE, Register: 1},
			// cmp eq reg 1 0x00000001
			&expr.Cmp{
				Op:       expr.CmpOpEq,
				Register: 1,
				Data:     []byte{0x01},
			},
			// payload load 6b @ link header + 6 => reg 1
			&expr.Payload{
				DestRegister: 1,
				Base:         expr.PayloadBaseLLHeader,
				Offset:       6, // TODO
				Len:          6, // TODO
			},
			// cmp eq reg 1 0x7a02a4c4 0x00003025
			&expr.Cmp{
				Op:       expr.CmpOpEq,
				Register: 1,
				Data:     []byte{0xc4, 0xa4, 0x02, 0x7a, 0x25, 0x30},
			},
			&expr.Log{
				Key:        keyGQ,
				QThreshold: uint16(20),
				Group:      uint16(1),
				Snaplen:    uint32(132),
				Data:       []byte("accept-log "),
			},
			&expr.Verdict{
				Kind: expr.VerdictAccept,
			},
		},
	})

	if err := c.Flush(); err != nil {
		fmt.Println(err.Error())
	}

	rules, err := c.GetRules(filter, filterChain)
	if err != nil {
		fmt.Println("get", err.Error())
	}

	fmt.Printf("rule:%v\n", rules[0])
}

The result of the operation is not what I want :

table ip filter {
	chain FORWARD {
		type filter hook input priority filter; policy accept;
		@ll,48,48 0xc4a4027a2530 log prefix "accept-log " accept
	}
}

How can i turn @ll,48,48 0xc4a4027a2530 into ether saddr c4:a4:02:7a:25:30 in nftables rule ? Can you help me to find the error !

from nftables.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.