nftables

package
v0.0.0-...-7458283 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2024 License: Apache-2.0, MIT Imports: 16 Imported by: 0

Documentation

Overview

Package nftables provides the interface to process packets through a netfilter (nf) ruleset and maintain/modify the ruleset accordingly. The package implements a bytecode nftables interpreter that accepts an nf ruleset (with the accompanying assembly and/or machine code) outputted from the nftables binary, along with network packets (as a stack.PacketBuffer) to filter, modify, and evaluate packets. We support a subset of the functionality of the nftables binary. The package is not yet thread-safe.

To use the package, construct a ruleset using the official nft binary and then pass the ruleset as a string (with flag --debug=netlink on to get the assembly) to InterpretRuleset command. The interpreter has strict syntax and only accepts rulesets outputted directly from the nftables binary. Maintaining and modifying the ruleset is done through the other public functions (Add.., Flush.., etc).

To evaluate a packet through the ruleset, call the EvaluatePacket function with the packet and the hook to evaluate at. The EvaluatePacket function returns the verdict issued by the ruleset and the packet modified by the ruleset (if the verdict is not Drop).

Inner Headers and Tunneling Headers are not supported.

Finally, note that error checking for parameters/inputs is only guaranteed for public functions. Most private functions are assumed to have valid/prechecked inputs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InterpretBitwiseBool

func InterpretBitwiseBool(line string, lnIdx int) (operation, error)

InterpretBitwiseBool creates a new Comparison operation from the given string.

func InterpretByteorder

func InterpretByteorder(line string, lnIdx int) (operation, error)

InterpretByteorder creates a new Byteorder operation from the given string.

func InterpretComparison

func InterpretComparison(line string, lnIdx int) (operation, error)

InterpretComparison creates a new Comparison operation from the given string.

func InterpretCounter

func InterpretCounter(line string, lnIdx int) (operation, error)

InterpretCounter creates a new Counter operation from the given string.

func InterpretImmediate

func InterpretImmediate(line string, lnIdx int) (operation, error)

InterpretImmediate creates a new Immediate operation from the given string.

func InterpretMetaLoad

func InterpretMetaLoad(line string, lnIdx int) (operation, error)

InterpretMetaLoad creates a new MetaLoad operation from the given string.

func InterpretMetaSet

func InterpretMetaSet(line string, lnIdx int) (operation, error)

InterpretMetaSet creates a new MetaSet operation from the given string.

func InterpretOperation

func InterpretOperation(line string, lnIdx int) (operation, error)

InterpretOperation creates a new operation from the given operation string, assumed to be a single line of text surrounded in square brackets. Note: the operation string should be generated as output from the official nft binary (can be accomplished by using flag --debug=netlink).

func InterpretPayloadLoad

func InterpretPayloadLoad(line string, lnIdx int) (operation, error)

InterpretPayloadLoad creates a new PayloadLoad operation from the given string.

func InterpretPayloadSet

func InterpretPayloadSet(line string, lnIdx int) (operation, error)

InterpretPayloadSet creates a new PayloadSet operation from the given string.

func InterpretRoute

func InterpretRoute(line string, lnIdx int) (operation, error)

InterpretRoute creates a new Route operation from the given string.

func VC

func VC(v int32) uint32

VC converts a numeric code to a uint32 number representing the verdict.

func VerdictCodeToString

func VerdictCodeToString(v uint32) string

VerdictCodeToString prints names for the supported verdicts.

Types

type AddressFamily

type AddressFamily int

AddressFamily describes the 6 address families supported by nftables. The address family determines the type of packets processed, and each family contains hooks at specific stages of the packet processing pipeline.

const (
	// IP     represents IPv4 Family.
	IP AddressFamily = iota

	// IP6    represents IPv6 Family.
	IP6

	// Inet   represents Internet Family for hybrid IPv4/IPv6 rules.
	Inet

	// Arp    represents ARP Family for IPv4 ARP packets.
	Arp

	// Bridge represents Bridge Family for Ethernet packets across bridge devices.
	Bridge

	// Netdev represents Netdev Family for packets on ingress and egress.
	Netdev

	// NumAFs is the number of address families supported by nftables.
	NumAFs
)

func (AddressFamily) Protocol

func (f AddressFamily) Protocol() uint8

Protocol returns the protocol number for the address family.

func (AddressFamily) String

func (f AddressFamily) String() string

String for AddressFamily returns the name of the address family.

type BaseChainInfo

type BaseChainInfo struct {

	// BcType is the base chain type of the chain (filter, nat, route).
	BcType BaseChainType

	// Hook is the hook to attach the chain to in the netfilter pipeline
	Hook Hook

	// Priority determines the order in which base chains with the same hook are
	// traversed. Each priority is associated with a signed integer priority value
	// which rank base chains in ascending order. See the Priority struct below
	// for more details.
	Priority Priority

	// Device is an optional parameter and is mainly relevant to the bridge and
	// netdev address families. It specifies the device associated with chain.
	Device string

	// PolicyDrop determines whether to change the chain's policy from Accept to
	// Drop. The policy of a chain is the verdict to issue when a packet is not
	// explicitly accepted or rejected by the rules. A chain's policy defaults to
	// Accept, but this can be used to specify otherwise.
	PolicyDrop bool
}

BaseChainInfo stores hook-related info for attaching a chain to the pipeline.

func NewBaseChainInfo

func NewBaseChainInfo(bcType BaseChainType, hook Hook, priority Priority, device string, policyDrop bool) *BaseChainInfo

NewBaseChainInfo creates a new BaseChainInfo object with the given values. The device and policyDrop parameters are optional in the nft binary and should be set to empty string and false if not needed.

type BaseChainType

type BaseChainType int

BaseChainType represents the supported chain types for base chains.

const (
	// BaseChainTypeFilter type  is supported by all Hooks.
	BaseChainTypeFilter BaseChainType = iota

	// BaseChainTypeNat type     is supported by Prerouting, Input, Output, Postrouting Hooks.
	BaseChainTypeNat

	// BaseChainTypeRoute type   is supported by the Output Hook only.
	BaseChainTypeRoute

	// NumBaseChainTypes is the number of base chain types supported by nftables.
	NumBaseChainTypes
)

Constants for BaseChainType

func (BaseChainType) String

func (bcType BaseChainType) String() string

String for BaseChainType returns the name of the base chain type.

type Chain

type Chain struct {
	// contains filtered or unexported fields
}

Chain represents a single chain as a list of rules. A chain can be either a base chain or a regular chain. Base chains (aka hook functions) contain a hook which attaches it directly to the netfilter pipeline to be called whenever the hook is encountered. Regular chains have a nil hook and must be called by base chains for evaluation.

func (*Chain) GetAddressFamily

func (c *Chain) GetAddressFamily() AddressFamily

GetAddressFamily returns the address family of the chain.

func (*Chain) GetBaseChainInfo

func (c *Chain) GetBaseChainInfo() *BaseChainInfo

GetBaseChainInfo returns the base chain info of the chain. Note: Returns nil if the chain is not a base chain.

func (*Chain) GetComment

func (c *Chain) GetComment() string

GetComment returns the comment of the chain.

func (*Chain) GetName

func (c *Chain) GetName() string

GetName returns the name of the chain.

func (*Chain) GetRule

func (c *Chain) GetRule(index int) (*Rule, error)

GetRule returns the rule at the given index in the chain's rule list. Valid indices are -1 (last) and [0, len-1]. Errors on invalid index.

func (*Chain) GetTable

func (c *Chain) GetTable() *Table

GetTable returns the table that the chain belongs to.

func (*Chain) IsBaseChain

func (c *Chain) IsBaseChain() bool

IsBaseChain returns whether the chain is a base chain.

func (*Chain) RegisterRule

func (c *Chain) RegisterRule(rule *Rule, index int) error

RegisterRule assigns the chain to the rule and adds the rule to the chain's rule list at the given index. Valid indices are -1 (append) and [0, len]. Errors on invalid index. This also checks that the operations in the rule comply with the chain. Checks done: - All jump and goto operations have a valid target chain. - Loop checking for jump and goto operations. - TODO(b/345684870): Add more checks as more operations are supported.

func (*Chain) RuleCount

func (c *Chain) RuleCount() int

RuleCount returns the number of rules in the chain.

func (*Chain) SetBaseChainInfo

func (c *Chain) SetBaseChainInfo(info *BaseChainInfo) error

SetBaseChainInfo attaches the specified chain to the netfilter pipeline (and detaches the chain from the pipeline if it was previously attached to a different hook) by setting the base chain info for the chain, returning an error if the base chain info is invalid.

func (*Chain) SetComment

func (c *Chain) SetComment(comment string)

SetComment sets the comment of the chain.

func (*Chain) UnregisterRule

func (c *Chain) UnregisterRule(index int) (*Rule, error)

UnregisterRule removes the rule at the given index from the chain's rule list and unassigns the chain from the rule then returns the unregistered rule. Valid indices are -1 (pop) and [0, len-1]. Errors on invalid index.

type Hook

type Hook int

Hook describes specific points in the pipeline where chains can be attached. Each address family has its own set of hooks (defined in supportedHooks). For IPv4/IPv6/Inet and Bridge, there are two possible pipelines: 1. Prerouting -> Input -> ~Local Process~ -> Output -> Postrouting 2. Prerouting -> Forward -> Postrouting

const (
	// Prerouting Hook    is supported by IPv4/IPv6/Inet, Bridge Families.
	Prerouting Hook = iota

	// Input Hook         is supported by IPv4/IPv6/Inet, Bridge, ARP Families.
	Input

	// Forward Hook       is supported by IPv4/IPv6/Inet, Bridge Families.
	Forward

	// Output Hook        is supported by IPv4/IPv6/Inet, Bridge, ARP Families.
	Output

	// Postrouting Hook   is supported by IPv4/IPv6/Inet, Bridge Families.
	Postrouting

	// Ingress Hook       is supported by IPv4/IPv6/Inet, Bridge, Netdev Families.
	Ingress

	// Egress Hook        is supported by Netdev Family only.
	Egress

	// NumHooks is the number of hooks supported by nftables.
	NumHooks
)

func (Hook) String

func (h Hook) String() string

String for Hook returns the name of the hook.

type LogicError

type LogicError struct {
	// contains filtered or unexported fields
}

LogicError is an interpretation error from modifying the NFTables state.

func (*LogicError) Error

func (e *LogicError) Error() string

Error implements error interface for LogicError to return an error message.

type NFTables

type NFTables struct {
	// contains filtered or unexported fields
}

NFTables represents the nftables state for all address families. Note: unlike iptables, nftables doesn't start with any initialized tables.

func NewNFTables

func NewNFTables(clock tcpip.Clock, rng rand.RNG) *NFTables

NewNFTables creates a new NFTables state object using the given clock for timing operations. Note: Expects random number generator to be initialized with a seed.

func (*NFTables) AddChain

func (nf *NFTables) AddChain(family AddressFamily, tableName string, chainName string, info *BaseChainInfo, comment string, errorOnDuplicate bool) (*Chain, error)

AddChain makes a new chain for the corresponding table and adds it to the chain map and hook function list, returning an error if the address family is invalid or the table doesn't exist. Can return an error if a chain by the same name already exists if errorOnDuplicate is true. Can be used to get an existing chain by the same name if errorOnDuplicate is false. Note: if the chain already exists, the existing chain is returned without any modifications. Note: if the chain is not a base chain, info should be nil.

func (*NFTables) AddTable

func (nf *NFTables) AddTable(family AddressFamily, name string, comment string,
	errorOnDuplicate bool) (*Table, error)

AddTable makes a new table for the specified address family, returning an error if the address family is invalid. Can return an error if a table by the same name already exists if errorOnDuplicate is true. Can be used to get an existing table by the same name if errorOnDuplicate is false. Note: if the table already exists, the existing table is returned without any modifications. Note: Table initialized as not dormant.

func (*NFTables) CreateChain

func (nf *NFTables) CreateChain(family AddressFamily, tableName string, chainName string, info *BaseChainInfo, comment string) (*Chain, error)

CreateChain makes a new chain for the corresponding table and adds it to the chain map and hook function list like AddChain but also returns an error if a chain by the same name already exists. Note: this interface mirrors the difference between the create and add commands within the nft binary.

func (*NFTables) CreateTable

func (nf *NFTables) CreateTable(family AddressFamily, name string, comment string) (*Table, error)

CreateTable makes a new table for the specified address family like AddTable but also returns an error if a table by the same name already exists. Note: this interface mirrors the difference between the create and add commands within the nft binary.

func (*NFTables) DeleteChain

func (nf *NFTables) DeleteChain(family AddressFamily, tableName string, chainName string) (bool, error)

DeleteChain deletes the specified chain from the NFTables object returning true if the chain was deleted and false if the chain doesn't exist. Returns an error if the address family is invalid or the table doesn't exist.

func (*NFTables) DeleteTable

func (nf *NFTables) DeleteTable(family AddressFamily, tableName string) (bool, error)

DeleteTable deletes the specified table from the NFTables object returning true if the table was deleted and false if the table doesn't exist. Returns an error if the address family is invalid.

func (*NFTables) EvaluateHook

func (nf *NFTables) EvaluateHook(family AddressFamily, hook Hook, pkt *stack.PacketBuffer) (Verdict, error)

EvaluateHook evaluates a packet using the rules of the given hook for the given address family, returning a netfilter verdict and modifying the packet in place. Returns an error if address family or hook is invalid or they don't match. TODO(b/345684870): Consider removing error case if we never return an error.

func (*NFTables) Flush

func (nf *NFTables) Flush()

Flush clears entire ruleset and all data for all address families.

func (*NFTables) FlushAddressFamily

func (nf *NFTables) FlushAddressFamily(family AddressFamily) error

FlushAddressFamily clears ruleset and all data for the given address family, returning an error if the address family is invalid.

func (*NFTables) GetChain

func (nf *NFTables) GetChain(family AddressFamily, tableName string, chainName string) (*Chain, error)

GetChain validates the inputs and gets a chain if it exists, error otherwise.

func (*NFTables) GetTable

func (nf *NFTables) GetTable(family AddressFamily, tableName string) (*Table, error)

GetTable validates the inputs and gets a table if it exists, error otherwise.

func (*NFTables) TableCount

func (nf *NFTables) TableCount() int

TableCount returns the number of tables in the NFTables object.

type Priority

type Priority struct {
	// contains filtered or unexported fields
}

Priority represents the priority of a base chain which specifies the order in which base chains with the same hook value are traversed. nftables allows for 2 types of priorities: 1) a simple signed integer value or 2) a predefined standard priority name (which is implicitly mapped to a signed integer value). Priorities are traversed in ascending order such that lower priority value have precedence. Use the respective NewIntPriority or NewStandardPriority to create new Priority objects.

func NewIntPriority

func NewIntPriority(value int) Priority

NewIntPriority creates a new Priority object given a simple signed integer priority value.

func NewStandardPriority

func NewStandardPriority(name string, family AddressFamily, hook Hook) (Priority, error)

NewStandardPriority creates a new Priority object given a standard priority name, returning an error if the standard priority name is not compatible with the given address family and hook.

func (Priority) GetStandardPriorityName

func (p Priority) GetStandardPriorityName() string

GetStandardPriorityName returns the standard priority name for the Priority object. It panics if the priority is not a standard priority name.

func (Priority) GetValue

func (p Priority) GetValue() int

GetValue returns the priority value for the Priority object.

func (Priority) IsStandardPriority

func (p Priority) IsStandardPriority() bool

IsStandardPriority returns true if the priority is a standard priority name.

func (Priority) String

func (p Priority) String() string

String for Priority returns the string representation of the Priority object.

type Rule

type Rule struct {
	// contains filtered or unexported fields
}

Rule represents a single rule in a chain and is represented as a list of operations that are evaluated sequentially (on a packet). Rules must be registered to a chain to be used and evaluated, and rules that have been registered to a chain cannot be modified. Note: Empty rules should be created directly (via &Rule{}).

func InterpretRule

func InterpretRule(ruleString string) (*Rule, error)

InterpretRule creates a new Rule from the given rule string, assumed to be represented as a block of text with a single operation per line. Note: the rule string should be generated as output from the official nft binary (can be accomplished by using flag --debug=netlink).

type SyntaxError

type SyntaxError struct {
	// contains filtered or unexported fields
}

SyntaxError is an interpretation error due to incorrect syntax.

func (*SyntaxError) Error

func (e *SyntaxError) Error() string

Error implements error interface for SyntaxError to return an error message.

type Table

type Table struct {
	// contains filtered or unexported fields
}

Table represents a single table as a collection of named chains. Note: as tables are simply collections of chains, evaluations aren't done on the table-level and instead are done on the chain- and hook- level.

func (*Table) AddChain

func (t *Table) AddChain(name string, info *BaseChainInfo, comment string, errorOnDuplicate bool) (*Chain, error)

AddChain makes a new chain for the table. Can return an error if a chain by the same name already exists if errorOnDuplicate is true.

func (*Table) ChainCount

func (t *Table) ChainCount() int

ChainCount returns the number of chains in the table.

func (*Table) DeleteChain

func (t *Table) DeleteChain(name string) bool

DeleteChain deletes the specified chain from the table returning true if the chain was deleted and false if the chain doesn't exist.

func (*Table) GetAddressFamily

func (t *Table) GetAddressFamily() AddressFamily

GetAddressFamily returns the address family of the table.

func (*Table) GetChain

func (t *Table) GetChain(chainName string) (*Chain, error)

GetChain returns the chain with the specified name if it exists, error otherwise.

func (*Table) GetComment

func (t *Table) GetComment() string

GetComment returns the comment of the table.

func (*Table) GetName

func (t *Table) GetName() string

GetName returns the name of the table.

func (*Table) IsDormant

func (t *Table) IsDormant() bool

IsDormant returns whether the table is dormant.

func (*Table) SetComment

func (t *Table) SetComment(comment string)

SetComment sets the comment of the table.

func (*Table) SetDormant

func (t *Table) SetDormant(dormant bool)

SetDormant sets the dormant flag for the table.

type TableFlag

type TableFlag int

TableFlag is a flag for a table as supported by the nftables binary.

const (
	// TableFlagDormant is set if the table is dormant. Dormant tables are not
	// evaluated by the kernel.
	TableFlagDormant TableFlag = iota
)

type Verdict

type Verdict struct {
	// Code is the numeric code that represents the verdict issued.
	Code uint32

	// ChainName is the name of the chain to continue evaluation if the verdict is
	// Jump or Goto.
	// Note: the chain must be in the same table as the current chain.
	ChainName string
}

Verdict represents the result of evaluating a packet against a rule or chain.

func (Verdict) String

func (v Verdict) String() string

String returns a string representation of the verdict.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL