NFTables.Expr.CT (NFTables v0.8.2)

View Source

Connection tracking (CT) matching functions for Expr.

Provides functions for matching based on connection tracking state, status, direction, labels, zones, helpers, and other CT-related attributes. Connection tracking is essential for stateful firewalls and enables intelligent packet filtering based on connection context.

Import

import NFTables.Expr.CT

Examples

# Allow established and related traffic
state([:established, :related]) |> accept()

# Match new connections with rate limiting
tcp() |> dport(22) |> ct_state([:new]) |> limit_connections(3) |> accept()

# Track NATed connections
ct_status([:snat]) |> counter()

# Match connection marks
connmark(42) |> jump("marked_chain")

For more information, see the nftables connection tracking wiki.

Summary

Functions

Match connection byte count.

Match connection tracking direction.

Match connection tracking helper.

Match connection tracking label.

Match original (pre-NAT) destination address.

Match original (pre-NAT) source address.

Match connection packet count.

Match connection tracking state.

Match connection tracking status.

Match connection tracking zone.

Limit number of connections per source IP.

Convenience alias for ct_state/2. Match connection tracking state.

Functions

connmark(builder \\ Expr.expr(), mark)

@spec connmark(NFTables.Expr.t(), non_neg_integer()) :: NFTables.Expr.t()

Match connection mark.

Connection marks are persistent across packets in a connection.

Example

builder |> connmark(42)

ct_bytes(builder \\ Expr.expr(), op, bytes)

@spec ct_bytes(NFTables.Expr.t(), atom(), non_neg_integer()) :: NFTables.Expr.t()

Match connection byte count.

Example

# Block connections exceeding 1GB
builder |> ct_bytes(:gt, 1_000_000_000) |> drop()

# Match large downloads
builder |> ct_bytes(:ge, 100_000_000) |> log("BIG-DL: ")

ct_direction(builder \\ Expr.expr(), direction)

@spec ct_direction(NFTables.Expr.t(), atom()) :: NFTables.Expr.t()

Match connection tracking direction.

Example

# Match original direction (outgoing)
builder |> ct_direction(:original)

# Match reply direction (incoming)
builder |> ct_direction(:reply)

ct_helper(builder \\ Expr.expr(), helper)

@spec ct_helper(NFTables.Expr.t(), String.t()) :: NFTables.Expr.t()

Match connection tracking helper.

Matches connections assigned to a specific CT helper (FTP, SIP, etc.).

Example

# Match FTP connections
builder |> ct_helper("ftp") |> accept()

# Match SIP connections
builder |> ct_helper("sip") |> log("SIP: ")

ct_label(builder \\ Expr.expr(), label)

Match connection tracking label.

CT labels are 128-bit bitmaps for complex stateful tracking.

Example

# Match connections labeled as suspicious
builder |> ct_label("suspicious") |> drop()

# Match numeric label bit
builder |> ct_label(5) |> log("LABELED: ")

ct_original_daddr(builder \\ Expr.expr(), addr)

@spec ct_original_daddr(NFTables.Expr.t(), String.t()) :: NFTables.Expr.t()

Match original (pre-NAT) destination address.

Example

# Match original destination before DNAT
builder |> ct_original_daddr("203.0.113.100") |> accept()

ct_original_saddr(builder \\ Expr.expr(), addr)

@spec ct_original_saddr(NFTables.Expr.t(), String.t()) :: NFTables.Expr.t()

Match original (pre-NAT) source address.

Example

# Match original source before SNAT
builder |> ct_original_saddr("192.168.1.100") |> accept()

# Track pre-NAT source
builder |> ct_original_saddr("10.0.0.0/8") |> log("INTERNAL: ")

ct_packets(builder \\ Expr.expr(), op, packets)

@spec ct_packets(NFTables.Expr.t(), atom(), non_neg_integer()) :: NFTables.Expr.t()

Match connection packet count.

Example

# Match connections with many packets
builder |> ct_packets(:gt, 10000) |> log("HIGH-PKT: ")

# Block after packet limit
builder |> ct_packets(:ge, 50000) |> drop()

ct_state(builder \\ Expr.expr(), states)

@spec ct_state(NFTables.Expr.t(), [atom()]) :: NFTables.Expr.t()

Match connection tracking state.

States

  • :invalid - Invalid connection
  • :established - Established connection
  • :related - Related to existing connection
  • :new - New connection
  • :untracked - Untracked connection

Example

builder |> ct_state([:established, :related])

ct_status(builder \\ Expr.expr(), statuses)

@spec ct_status(NFTables.Expr.t(), [atom()]) :: NFTables.Expr.t()

Match connection tracking status.

Statuses

  • :expected - Connection is expected
  • :seen_reply - Packets seen in both directions
  • :assured - Connection is assured (will not be deleted on timeout)
  • :confirmed - Connection is confirmed
  • :snat - Source NAT applied
  • :dnat - Destination NAT applied
  • :dying - Connection is dying

Example

# Match assured connections
builder |> ct_status([:assured])

# Match NATed connections
builder |> ct_status([:snat])

ct_zone(builder \\ Expr.expr(), zone)

Match connection tracking zone.

CT zones provide isolation for multi-tenant or namespace scenarios.

Example

# Match zone 1
builder |> ct_zone(1) |> accept()

# Match zone for specific tenant
builder |> ct_zone(100) |> jump("tenant_100")

limit_connections(builder \\ Expr.expr(), count)

@spec limit_connections(NFTables.Expr.t(), non_neg_integer()) :: NFTables.Expr.t()

Limit number of connections per source IP.

Example

# Limit to 10 concurrent connections per IP
builder
|> tcp()
|> dport(80)
|> ct_state([:new])
|> limit_connections(10)
|> reject()

# Limit SSH connections per IP
builder
|> tcp()
|> dport(22)
|> ct_state([:new])
|> limit_connections(3)
|> drop()

state(builder \\ Expr.expr(), states)

@spec state(NFTables.Expr.t(), [atom()]) :: NFTables.Expr.t()

Convenience alias for ct_state/2. Match connection tracking state.

Supports dual-arity: can start a new expression or continue an existing one.

Example

# Accept established connections
state([:established, :related]) |> accept()

# Continue existing expression
builder |> state([:new]) |> rate_limit(10, :minute)