NFTables.Expr.CT (NFTables v0.8.2)
View SourceConnection 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.CTExamples
# 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 mark.
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
@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)
@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: ")
@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)
@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: ")
@spec ct_label(NFTables.Expr.t(), String.t() | non_neg_integer()) :: NFTables.Expr.t()
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: ")
@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()
@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: ")
@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()
@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])
@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])
@spec ct_zone(NFTables.Expr.t(), non_neg_integer()) :: NFTables.Expr.t()
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")
@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()
@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)