nufftables

package module
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2024 License: Apache-2.0 Imports: 5 Imported by: 5

README

'nuff tables!

PkgGoDev GitHub build and test Go Report Card Coverage

The nufftables go module is a thin wrapper around Google's nftables to ease reasoning over the current state of tables, chains, rules, and expressions. If you just want to setup and remove netfilter chains and rules, then @google/nftables should already be sufficient most of the time.

CLI Tool Examples

  • cmd/nftdump is a simple CLI tool that fetches all netfilter tables (in the host network namespace) and then dumps the corresponding objects to stdout.

  • cmd/portfinder is another simple CLI tool that fetches the IPv4 and IPv6 netfilter tables and scans them for certain port forwarding expressions, dumping the forwarded port information found to stdout. Only port forwarding expressions using port range and target DNAT expressions (with an optional IP address compare) will be detected.

Example Usage

A simplified example, without proper error handling, that reasons about netfilter port match expressions:

import (
    "github.com/google/nftables"
    "github.com/google/nftables/expr"
    "github.com/thediveo/nufftables"
)

func main() {
    conn, _ := nftables.New(nftables.AsLasting())
    defer conn.CloseLasting()

    tables := nufftables.GetFamilyTables(conn, nufftables.TableFamilyIPv4)
    for _, chain := range tables.Table("nat", nufftables.TableFamilyIPv4) {
        for _, rule := range chain.Rules {
            if _, match := nufftables.OfType[*expr.Match](rule.Expressions()); match != nil {
                fmt.Printf("port match expression: %#v\n", match)
            }
        }
    }
}

Note

nufftables supports versions of Go that are noted by the Go release policy, that is, major versions N and N-1 (where N is the current major version).

VSCode Tasks

The included nufftables.code-workspace defines the following tasks:

  • View Go module documentation task: installs pkgsite, if not done already so, then starts pkgsite and opens VSCode's integrated ("simple") browser to show the nufftable's documentation.
Aux Tasks
  • pksite service: auxilliary task to run pkgsite as a background service using scripts/pkgsite.sh. The script leverages browser-sync and nodemon to hot reload the Go module documentation on changes; many thanks to @mdaverde's Build your Golang package docs locally for paving the way. scripts/pkgsite.sh adds automatic installation of pkgsite, as well as the browser-sync and nodemon npm packages for the local user.
  • view pkgsite: auxilliary task to open the VSCode-integrated "simple" browser and pass it the local URL to open in order to show the module documentation rendered by pkgsite. This requires a detour via a task input with ID "pkgsite".

Make Targets

  • make: lists all targets.
  • make coverage: runs all tests with coverage and then updates the coverage badge in README.md.
  • make pkgsite: installs x/pkgsite, as well as the browser-sync and nodemon npm packages first, if not already done so. Then runs the pkgsite and hot reloads it whenever the documentation changes.
  • make report: installs @gojp/goreportcard if not yet done so and then runs it on the code base.
  • make test: runs all tests, once as root and then as the invoking user.

Copyright 2022-24 Harald Albrecht, licensed under the Apache License, Version 2.0.

Documentation

Overview

Package nufftables is a thin wrapper around Google's nftables to ease reasoning over the current state of tables, chains, rules, and expressions. If you just want to setup and remove netfilter chains and rules, then google/nftables should be sufficient most of the time.

Information Model

nufftables' information model is basically that of netfilter and Google's nftables information model in particular, but with the hierarchy added in explicitly.

Reasoning About Expressions

To simplify “fishing” for expressions in rules, nufftables defines a set of convenience functions:

  • OfType finds and returns the expression of the exact type, such as *expr.Payload or *expr.Cmp, as well as the remaining expressions after the match.

  • OfTypeFunc finds and returns the expression of the exact type, additionally satisfying the constraints of the passed “approver” function.

  • OfTypeTransformed finds the expression of the exact type, and if accepted by the constraint-and-transformer function specified, returns the transformed value.

  • PrefixedOfTypeFunc find a matching twin expressions and then returns the transformation of the trailing twin. A typical use case might be matching on the sequence of an *expr.Payload network header load, immediately followed by an *expr.Cmp destination IP address compare, transforming the trailing match to return just the concrete IP address checked for.

  • Often times, certain expressions can be optional: OptionalOfType, OptionalOfTypeFunc, OptionalPrefixedOfTypeFunc, OptionalOfTypeTransformed and OptionalPrefixedOfTypeTransformed return the original expressions instead of nil in case no match exists. This way, the optional expression matches can be neatly chained into the overall expression parsing and matching, without breaking the flow.

For instance,

remexprs, cmp := nufftables.OptionalOfTypeFunc(
  rule.Expressions(),
  func(cmp *expr.Cmp) bool {
    return cmp.Op == expr.CmpOpEq && len(cmp.Data) == 4
  })

returns the first expr.Cmp expression, if any, that is compares with a given IPv4 address for equality (expr.CmpOpEq). The (optional) search returns either the remaining expressions after a match, or the original slice of expressions in case of no match.

In contrast,

exprs, match := nufftables.OfTypeFunc(
  exprs, func(match *expr.Match) bool {...})

either returns the first match of an expr.Match expression together with the remaining expressions, or simply a nil match with nil expressions.

These basic building blocks allow to assemble a DSL for netfilter table expression reasoning, and to finally build high-level functions on top of this all. Please see the github.com/thediveo/nufftables/dsl and github.com/thediveo/nufftables/portfinder packages for more details.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Chain

type Chain struct {
	*nftables.Chain
	Table *Table
	Rules []Rule // sorted by rule position.
}

Chain represents a nftables.Chain together with all its Rule objects. Please note that Rules are automatically sorted by their nftables.Rule.Position.

type ChainHook

type ChainHook nftables.ChainHook

ChainHook wraps nftables.ChainHook to support clear-text string representations of chain hook values.

func (ChainHook) Name

func (h ChainHook) Name(fam TableFamily) string

Name returns the name of a chain hook, based on the (table's) address family the hook is used in.

The following chain hook names are currently defined:

  • PREROUTING, or INGRESS (netdev table family only)
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

type Expressions

type Expressions []expr.Any

Expressions represents a slice of expr.Any expressions for a single Rule.

func OfType

func OfType[E expr.Any](exprs Expressions) (Expressions, E)

OfType returns the first expression (if any) of the specified type E, together with the remaining expressions after the match. The type parameter E must be a pointer to a concrete nftables expression type, such as *expr.Match, et cetera. If no expression with a matching type could be found, then a nil expressions list is returned, together with a zero matching expression (~nil).

func OfTypeFunc

func OfTypeFunc[E expr.Any](exprs Expressions, fn func(e E) bool) (Expressions, E)

OfTypeFunc returns the first expression (if any) of the specified type E and additionally satisfying fn(E). If no expression with a matching type and satisfied fn(E) could be found, then a nil expressions list is returned, together with a zero matching expression of type E (~nil).

func OfTypeTransformed added in v0.9.0

func OfTypeTransformed[E expr.Any, R any](exprs Expressions, fn func(e E) (R, bool)) (Expressions, R)

OfTypeTransformed returns the transformed result of type R of the first expression matching the specified type E and additionally satisfying the transformator fn(E); otherwise, it returns a zero result expression of type R, as well as a nil expressions list.

The passed fn should return the transformed expression of type R as well as true upon accepting a match; otherwise, it should return false, so that OfTypeTransformed tries to find the next potential match of type E.

func OptionalOfType

func OptionalOfType[E expr.Any](exprs Expressions) (Expressions, E)

OptionalOfType returns the first expression (if any) of the specified type E, together with the remaining expressions after the match; otherwise, it returns a zero matching expression of type E (~nil), together with the original expressions.

This form allows chaining in optional expressions without further separate found/not-found case handling, giving a somewhat “fluent” expression hunting experience.

func OptionalOfTypeFunc

func OptionalOfTypeFunc[E expr.Any](exprs Expressions, fn func(e E) bool) (Expressions, E)

OptionalOfTypeFunc returns the first expression (if any) of the specified type E and additionally satisfying fn(E), together with the remaining expressions after the match; otherwise, it returns a zero matching expression of type E (~nil) together with the original expressions.

This form allows chaining in optional expressions without further separate found/not-found case handling, giving a somewhat “fluent” expression hunting experience.

func OptionalOfTypeTransformed added in v0.10.0

func OptionalOfTypeTransformed[E expr.Any, R any](exprs Expressions, fn func(e E) (R, bool)) (Expressions, R)

OptionalOfTypeTransformed returns the transformed result of type R of the first expression matching the specified type E and additionally satisfying the transformator fn(E); otherwise, it returns a zero result expression of type R, as well as the original expressions list.

The passed fn should return the transformed expression of type R as well as true upon accepting a match; otherwise, it should return false, so that OfTypeTransformed tries to find the next potential match of type E.

func OptionalPrefixedOfTypeFunc added in v0.10.0

func OptionalPrefixedOfTypeFunc[P, E expr.Any](exprs Expressions, prefn func(p P) bool, fn func(e E) bool) (Expressions, E)

OptionalPrefixedOfTypeFunc returns the first expression (if any) of the specified type E also satisfying fn(E) that additionally has a prefix expression of type P satisfying prefn(P). If no such twin-match could be found, then the original expressions together with a zero expression of type E is returned instead.

func OptionalPrefixedOfTypeTransformed added in v0.10.0

func OptionalPrefixedOfTypeTransformed[P, E expr.Any, R any](exprs Expressions, precfn func(p P) bool, fn func(e E) (R, bool)) (Expressions, R)

OptionalPrefixedOfTypeTransformed returns the transformed result of type R of the first expression matching the specified type E also satisfying fn(E) that additionally has a prefix expression of type P satisfying prefn(P); otherwise, it returns a zero result expression of type R, as well as the original expressions list.

The passed fn should return the transformed expression of type R as well as true upon accepting a match; otherwise, it should return false, so that OfTypeTransformed tries to find the next potential match of type E.

func PrefixedOfTypeFunc added in v0.10.0

func PrefixedOfTypeFunc[P, E expr.Any](exprs Expressions, prefn func(p P) bool, fn func(e E) bool) (Expressions, E)

PrefixedOfTypeFunc returns the first expression (if any) of the specified type E also satisfying fn(E) that additionally has a prefix expression of type P satisfying prefn(P). If no such twin-match could be found, then a nil expressions list is returned together with a zero expression of type E (~nil).

func PrefixedOfTypeTransformed added in v0.10.0

func PrefixedOfTypeTransformed[P, E expr.Any, R any](exprs Expressions, prefn func(p P) bool, fn func(e E) (R, bool)) (Expressions, R)

PrefixedOfTypeTransformed returns the transformed result of type R of the first expression matching the specified type E also satisfying fn(E) that additionally has a prefix expression of type P satisfying prefn(P). If no such twin-match could be found, then a nil expressions list is returned together with a zero expression of type E (~nil).

type Rule

type Rule struct {
	*nftables.Rule
	Chain *Chain
}

Rule is a nftables.Rule belonging to a Chain.

func (*Rule) Expressions

func (r *Rule) Expressions() Expressions

Expressions returns all expressions for this rule.

type Table

type Table struct {
	*nftables.Table
	ChainsByName map[string]*Chain
}

Table is a nftables.Table together with all its named Chain objects.

type TableFamily

type TableFamily nftables.TableFamily

TableFamily wraps nftables.TableFamily in order to implement the fmt.Stringer interface.

Reexported netfilter table family constants, for convenience.

func (TableFamily) String

func (tf TableFamily) String() string

String returns the table family name (identifier) for the given TableFamily value, such as "inet", "ip" (for IPv4), "ipv6", et cetera.

type TableKey

type TableKey struct {
	Name   string
	Family TableFamily
}

TableKey represents an index key into a TableMap. Every Table is always namespaced to a nftables.TableFamily, such as nftables.TableFamilyINet (both IPv4 and IPv6), nftables.TableFamilyIPv4, nftables.TableFamilyIPv6, et cetera.

type TableMap

type TableMap map[TableKey]*Table

TableMap indexes table names (that are always "namespaced" in a particular address family) to their corresponding Table objects. The Table objects then contain their Chain objects, and the chain objects in turn Rule objects. It's turtles all the way down.

func GetAllTables

func GetAllTables(conn *nftables.Conn) (TableMap, error)

GetAllTables returns the available netfilter tables as a TableMap using the specified conn for retrieval. The Table objects in the returned TableMap are populated with their named Chain objects, and these in turn contain their Rule objects including expressions.

func GetFamilyTables

func GetFamilyTables(conn *nftables.Conn, family TableFamily) (TableMap, error)

GetFamilyTables returns the netfiler tables for the specified netfilter family only, together with all their chains and rules.

func (TableMap) Table

func (t TableMap) Table(name string, family TableFamily) *Table

Table returns the named table of the specified family if available, otherwise nil.

func (TableMap) TableChain

func (t TableMap) TableChain(tablename string, family TableFamily, chainname string) *Chain

TableChain returns the specified named chain in the specified table and family, otherwise nil.

Directories

Path Synopsis
cmd
nftdump
nftdump dumps netfilter tables with their chains, rules, and down to the level of expressions.
nftdump dumps netfilter tables with their chains, rules, and down to the level of expressions.
portfinder
portfinder lists forwarded ports found in "nat" netfilter tables for the IPv4 and IPv6 families.
portfinder lists forwarded ports found in "nat" netfilter tables for the IPv4 and IPv6 families.
Package dsl helps with reasoning about rule expressions.
Package dsl helps with reasoning about rule expressions.
Package portfinder helps with reasoning about rule expressions about port forwarding in combination with destination NAT (“DNAT”).
Package portfinder helps with reasoning about rule expressions about port forwarding in combination with destination NAT (“DNAT”).

Jump to

Keyboard shortcuts

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