CONNTRACK(8)

CONNTRACK(8) ๐Ÿ’…

ok so bestie, we're talking about conntrack from section 8 of the manual โ€” the netfilter connection tracking era. let's get into it ๐Ÿซถ


โœจ NAME โœจ

conntrack โ€” command line interface for netfilter connection tracking ๐ŸŽ€


๐ŸŒธ SYNOPSIS ๐ŸŒธ

conntrack -L [table] [options] [-z]
conntrack -G [table] parameters
conntrack -D [table] parameters
conntrack -I [table] parameters
conntrack -A [table] parameters
conntrack -U [table] parameters
conntrack -E [table] [options]
conntrack -F [table]
conntrack -C [table]
conntrack -S
conntrack -R file

๐Ÿ’– DESCRIPTION ๐Ÿ’–

The conntrack utility is literally your full-featured userspace interface to the Netfilter connection tracking system, and it was made to replace the old /proc/net/ip_conntrack interface. rip to that one, she served ๐Ÿ’€

This tool can be used to search, list, inspect and maintain the connection tracking subsystem of the Linux kernel. it's giving main character energy in the netfilter world, fr fr.

Using conntrack, you can:

  • dump a list of all currently tracked connections โ€” or a filtered selection of them, if you're feeling picky ๐Ÿ’…
  • delete connections from the state table
  • and even add new ones ๐Ÿ‘‘

In addition, you can also monitor connection tracking events โ€” like, show an event message (one line, just one) per newly established connection. so every new connection gets its own little spotlight moment โœจ


๐Ÿฆ‹ TABLES ๐Ÿฆ‹

The connection tracking subsystem maintains several internal tables. let's do a vibe check on each one ๐Ÿงš

  • conntrack โ€” this is the default table. It contains a list of all currently tracked connections through the system. If you don't use connection tracking exemptions (that's the NOTRACK iptables target, iykyk), this means all connections that go through the system. all of them. every single one ๐Ÿ‘€
  • expect โ€” this is the table of expectations. Connection tracking expectations are the mechanism used to "expect" RELATED connections to existing ones. Expectations are generally used by "connection tracking helpers" (sometimes called application level gateways, aka [ALGs]) for more complex protocols such as FTP, SIP or H.323. it's giving "we knew you were coming" ๐Ÿ”ฎ
  • dying โ€” this table shows the conntrack entries that have expired and that have been destroyed by the connection tracking system itself, or via the conntrack utility. rip bozo ๐Ÿชฆ
  • unconfirmed โ€” this table shows new entries that are not yet inserted into the conntrack table. These entries are attached to packets that are traversing the stack, but did not reach the confirmation point at the postrouting hook. they're in their situationship era, not committed yet ๐Ÿ˜ญ
okay so real talk: the tables dying and unconfirmed are basically only useful for debugging purposes. Under normal operation, it is hard to see entries in any of them. There are corner cases where it is valid to see entries in the unconfirmed table โ€” e.g. when packets that are enqueued via nfqueue โ€” and in the dying table, e.g. when conntrackd(8) runs in event reliable mode. so don't panic if you peek and it's empty, that's the normal vibe ๐Ÿซถ

ok that's part 1 and we are SO not done yet, keep reading bestie ๐Ÿ‘‘

โœจ OPTIONS โœจ

okay bestie so the options conntrack understands split into a few little cliques, and we're gonna meet all of them ๐Ÿ’–


๐ŸŽ€ COMMANDS ๐ŸŽ€

these tell it what to actually do, and listen โ€” only one of them can be specified at any given time, okay? pick your fighter, not your whole roster. ๐Ÿ’…

  • -L, --dump โ€” list the connection tracking table or the expectation table. the classic "show me everything" move ๐Ÿ‘€
  • -G, --get โ€” go search for one particular (matching) entry in the table you picked, and show it off โœจ
  • -D, --delete โ€” yeet an entry out of the given table ๐Ÿ—‘๏ธ
  • -I, --create โ€” make a brand new entry in the given table. if it's already there? it fails. no duplicates allowed, we're not like that ๐Ÿšซ
  • -A, --add โ€” add a new entry to the given table
  • -U, --update โ€” update an entry in the given table
  • -E, --event โ€” show a real-time event log, like a live feed of everything happening ๐Ÿ”ด
  • -F, --flush โ€” flush the whole given table. yes, the entire thing ๐Ÿ˜ญ
  • -C, --count โ€” show the table counter ๐Ÿ”ข
  • -S, --stats โ€” show the in-kernel connection tracking system statistics ๐Ÿ“Š
  • -R, --load-file โ€” load entries from a given file. wanna read from stdin instead? just specify - ๐Ÿซถ

๐ŸŒธ PARAMETERS ๐ŸŒธ

  • -z, --zero โ€” atomically zero the counters after reading them. heads up: this one is only valid when you're using it together with the -L, --dump command options. no solo runs, bestie ๐ŸŽ€
  • -o, --output [extended,xml,save,timestamp,id,ktimestamp,labels] โ€” display output in a certain format. let's break it down:
    • with the extended output option, this tool shows you the layer 3 information ๐ŸŒ
    • with ktimestamp, it displays the in-kernel timestamp that's been available since 2.6.38 (you can turn it on via the sysctl(8) key net.netfilter.nf_conntrack_timestamp) โฑ๏ธ
    • the labels output option tells conntrack to show the names of connection tracking labels that might be present ๐Ÿท๏ธ
    • the userspace output option tells you if the event has been triggered by a process ๐Ÿ‘ค
  • -e, --event-mask [ALL|NEW|UPDATES|DESTROY][,...] โ€” set the bitmask of events that are gonna be generated by the in-kernel ctnetlink event code. with this you can shrink the event messages the kernel spits out down to just the types you're actually interested in. this option can only be used in conjunction with -E, --event ๐Ÿ’ซ
  • -b, --buffer-size value โ€” set the Netlink socket buffer size in bytes. this one's your bestie if the command line tool keeps reporting ENOBUFS errors. if you don't pass this option, the default value sitting at the sysctl(8) key net.core.rmem_default gets used. the tool reports this problem when your process is too slow to handle all the event messages, or like, in other words, when there's enough events to overrun the socket buffer ๐Ÿ˜ต. note that a big buffer lowers your chances of hitting ENOBUFS, but it also means more memory consumption, so it's giving tradeoff. this option can only be used in conjunction with -E, --event

๐Ÿฆ‹ FILTER PARAMETERS ๐Ÿฆ‹

  • -s, --src, --orig-src IP_ADDRESS โ€” match only the entries whose source address in the original direction equals whatever you passed as the argument. it implies --mask-src when you use CIDR notation ๐ŸŽฏ
  • -d, --dst, --orig-dst IP_ADDRESS โ€” match only the entries whose destination address in the original direction equals the argument you gave. implies --mask-dst when CIDR notation is used ๐ŸŽฏ
  • -r, --reply-src IP_ADDRESS โ€” match only the entries whose source address in the reply direction equals the argument ๐ŸŽฏ
  • -q, --reply-dst IP_ADDRESS โ€” match only the entries whose destination address in the reply direction equals the argument ๐ŸŽฏ
  • -p, --proto PROTO โ€” specify the layer four (TCP, UDP, ...) protocol ๐Ÿ”ฅ
  • -f, --family PROTO โ€” specify the layer three (ipv4, ipv6) protocol. this option is only required together with -L, --dump. if you don't pass it, the default layer 3 protocol is IPv4 ๐ŸŒ
  • -t, --timeout TIMEOUT โ€” specify the timeout โณ
  • -m, --mark MARK[/MASK] โ€” specify the conntrack mark. optionally you can throw in a mask value too. in --update mode, this mask says which bits should be zeroed before XORing the MARK value into the ctmark. otherwise, the mask gets logically ANDed with the existing mark before the comparison happens. and in --create mode? the mask is just ignored, periodt ๐Ÿ’…
  • -l, --label LABEL โ€” specify a conntrack label. this option is only available in conjunction with -L, --dump, -E, --event, -U --update or -D --delete. it matches the entries whose labels include the ones you passed as arguments. stack up multiple -l options to specify multiple labels that need to be set ๐Ÿท๏ธ
  • --labelmap PATH โ€” specify the path to a connlabel.conf file to load instead of the default one. this option is only available in conjunction with -L, --dump, -E, --event, -U --update or -D --delete ๐Ÿ“
  • --label-add LABEL โ€” specify the conntrack label to add to the selected conntracks. this option is only available in conjunction with -I, --create, -A, --add or -U, --update. rule of thumb bestie: you gotta use either the connlabel match in your iptables ruleset or the ct label statement in your nftables ruleset โ€” that's what turns on ct label support in the kernel, and it's what lets you update labels via -U, --update. otherwise your label updates get straight up ignored ๐Ÿ™ˆ
  • --label-del [LABEL] โ€” specify the conntrack label to delete from the selected conntracks. if no label is given, all labels get deleted ๐Ÿ˜ณ. this option is only available in conjunction with -U, --update
  • -c, --secmark SECMARK โ€” specify the conntrack selinux security mark ๐Ÿ”
  • -u, --status [ASSURED|SEEN_REPLY|FIXED_TIMEOUT|EXPECTED|OFFLOAD|UNSET][,...] โ€” specify the conntrack status โœจ
  • -n, --src-nat โ€” filter source NAT connections ๐ŸŽญ
  • -g, --dst-nat โ€” filter destination NAT connections ๐ŸŽญ
  • -j, --any-nat โ€” filter any NAT connections ๐ŸŽญ
  • -w, --zone โ€” filter by conntrack zone. see the iptables CT target for more information ๐Ÿ—บ๏ธ
  • --orig-zone โ€” filter by conntrack zone in the original direction. see the iptables CT target for more information ๐Ÿ—บ๏ธ
  • --reply-zone โ€” filter by conntrack zone in the reply direction. see the iptables CT target for more information ๐Ÿ—บ๏ธ
  • --tuple-src IP_ADDRESS โ€” specify the tuple source address of an expectation. implies --mask-src when CIDR notation is used ๐ŸŽฏ
  • --tuple-dst IP_ADDRESS โ€” specify the tuple destination address of an expectation. implies --mask-dst when CIDR notation is used ๐ŸŽฏ
  • --mask-src IP_ADDRESS โ€” specify the source address mask. for conntracks, this option is only available in conjunction with -L, --dump, -E, --event, -U --update or -D --delete. for expectations, this option is only available in conjunction with -I, --create ๐ŸŽญ
  • --mask-dst IP_ADDRESS โ€” specify the destination address mask. same limitations as for --mask-src ๐ŸŽญ

๐Ÿ’… PROTOCOL FILTER PARAMETERS ๐Ÿ’…

TCP-specific fields:

  • --sport, --orig-port-src PORT โ€” source port in the original direction
  • --dport, --orig-port-dst PORT โ€” destination port in the original direction
  • --reply-port-src PORT โ€” source port in the reply direction
  • --reply-port-dst PORT โ€” destination port in the reply direction
  • --state state โ€” TCP state, one of NONE, SYN_SENT, SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE or LISTEN ๐Ÿงต

UDP-specific fields:

  • --sport, --orig-port-src PORT โ€” source port in the original direction
  • --dport, --orig-port-dst PORT โ€” destination port in the original direction
  • --reply-port-src PORT โ€” source port in the reply direction
  • --reply-port-dst PORT โ€” destination port in the reply direction

ICMP-specific fields:

  • --icmp-type TYPE โ€” ICMP Type. has to be specified numerically ๐Ÿ”ข
  • --icmp-code CODE โ€” ICMP Code. has to be specified numerically ๐Ÿ”ข
  • --icmp-id ID โ€” ICMP Id. has to be specified numerically (non-mandatory) ๐Ÿ”ข

UDPlite-specific fields:

  • --sport, --orig-port-src PORT โ€” source port in the original direction
  • --dport, --orig-port-dst PORT โ€” destination port in the original direction
  • --reply-port-src PORT โ€” source port in the reply direction
  • --reply-port-dst PORT โ€” destination port in the reply direction

SCTP-specific fields:

  • --sport, --orig-port-src PORT โ€” source port in the original direction
  • --dport, --orig-port-dst PORT โ€” destination port in the original direction
  • --reply-port-src PORT โ€” source port in the reply direction
  • --reply-port-dst PORT โ€” destination port in the reply direction
  • --state state โ€” SCTP state, one of NONE, CLOSED, COOKIE_WAIT, COOKIE_ECHOED, ESTABLISHED, SHUTDOWN_SENT, SHUTDOWN_RECD, SHUTDOWN_ACK_SENT ๐Ÿงต
  • --orig-vtag value โ€” Verification tag (32-bits value) in the original direction ๐Ÿ”–
  • --reply-vtag value โ€” Verification tag (32-bits value) in the reply direction ๐Ÿ”–

DCCP-specific fields (needs Linux >= 2.6.30):

  • --sport, --orig-port-src PORT โ€” source port in the original direction
  • --dport, --orig-port-dst PORT โ€” destination port in the original direction
  • --reply-port-src PORT โ€” source port in the reply direction
  • --reply-port-dst PORT โ€” destination port in the reply direction
  • --state state โ€” DCCP state, one of NONE, REQUEST, RESPOND, PARTOPEN, OPEN, CLOSEREQ, CLOSING, TIMEWAIT ๐Ÿงต
  • --role [client|server] โ€” role that the original conntrack tuple is tracking ๐ŸŽญ

GRE-specific fields:

  • --srckey, --orig-key-src KEY โ€” source key in the original direction (in hexadecimal or decimal) ๐Ÿ”‘
  • --dstkey, --orig-key-dst KEY โ€” destination key in the original direction (in hexadecimal or decimal) ๐Ÿ”‘
  • --reply-key-src KEY โ€” source key in the reply direction (in hexadecimal or decimal) ๐Ÿ”‘
  • --reply-key-dst KEY โ€” destination key in the reply direction (in hexadecimal or decimal) ๐Ÿ”‘

๐Ÿ’– DIAGNOSTICS ๐Ÿ’–

the exit code is 0 for correct function, bestie โœจ errors that look like they were caused by invalid command line parameters get you an exit code of 2 ๐Ÿšซ and any other errors? those hand you an exit code of 1 ๐Ÿ’€

๐Ÿ’– EXAMPLES ๐Ÿ’–

okay bestie this is the part where it all comes together, the little recipes, the greatest hits, the "just copy-paste it and it works" section ๐Ÿซถ every single one of these is literally verbatim, don't you dare change a character:

  • conntrack -L โ€” dumps the connection tracking table in /proc/net/ip_conntrack format. the classic. the OG. the one you run when you have zero thoughts in your head and just want to see things ๐Ÿ‘€
  • conntrack -L -o extended โ€” shows the connection tracking table in /proc/net/nf_conntrack format, but with extra info on top. it's giving "deluxe edition" โœจ
  • conntrack -L -o xml โ€” shows the connection tracking table in XML. for when you want your flows to look like a very serious document ๐Ÿ“„
  • conntrack -L -o save โ€” shows the connection tracking table in conntrack syntax format, i.e. the format that can be fed right back in. it's giving "round trip" ๐Ÿ”
  • conntrack -L -f ipv6 -o extended โ€” only dumps IPv6 connections, in /proc/net/nf_conntrack format, with the additional information. v6 girlies rise up ๐ŸŒˆ
  • conntrack -L --src-nat โ€” shows the source NAT connections. just the NAT ones. filtered. curated. ๐ŸŽ€
  • conntrack -E -o timestamp โ€” shows connection events together with the timestamp. live updates and receipts ๐Ÿ•
  • conntrack -D -s 1.2.3.4 โ€” deletes all flows whose source address is 1.2.3.4. poof. gone. no cap ๐Ÿ’€
  • conntrack -U -s 1.2.3.4 -m 1 โ€” sets connmark to 1 on all the flows whose source address is 1.2.3.4. marking them. claiming them. branding them fr fr ๐Ÿ”ฅ

and here's the fancy one, so let me give it the whole block because it spans two lines and you know I'm not about to mess that up:

conntrack -L -w 11 -o save | sed s/-w 11/-w 12/g | conntrack --load-file
-
  • conntrack -L -w 11 -o save | sed s/-w 11/-w 12/g | conntrack --load-file - โ€” copies all entries from ct zone 11 to ct zone 12. yes it's a whole pipeline. yes it's lowkey iconic. the sed does the little zone switcheroo and --load-file - reads it right back off stdin ๐Ÿฆ‹

๐Ÿ› BUGS ๐Ÿ›

found something cursed? don't just sit there screaming into the void bestie, please, report them to netfilter-devel@vger.kernel.org or file a bug in Netfilter's bugzilla at https://bugzilla.netfilter.org. they want to know. we all want to know ๐Ÿ’œ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

go read these next, they're the friends of the family:

also, see http://conntrack-tools.netfilter.org for the whole vibe ๐Ÿ’…


๐Ÿ‘‘ AUTHORS ๐Ÿ‘‘

the lore, preserved exactly:

Jay Schulist, Patrick McHardy, Harald Welte and Pablo Neira Ayuso wrote the kernel-level "ctnetlink" interface that is used by the conntrack tool.

Pablo Neira Ayuso wrote and maintains the conntrack tool, and Harald Welte added support for conntrack-based accounting counters.

The man page was written by Harald Welte <laforge@netfilter.org> and Pablo Neira Ayuso <pablo@netfilter.org>.


and that's the whole page, bestie!! this little masterpiece is part of the conntrack-tools package, dated Aug 9, 2019, and it lives in section 8 of the manual, aka CONNTRACK(8) ๐Ÿ’– thanks for reading all three parts, you ate that fr fr, now go track some connections ๐ŸŽ€โœจ๐Ÿฆ‹