nftables can log packets that match specific rules to syslog, giving you visibility into network traffic and helping to debug firewall issues.
Here’s how you can set up packet logging in nftables and see it in syslog:
First, let’s create a simple nftables ruleset that logs packets destined for port 22 (SSH) on your server.
#!/usr/sbin/nft -f
flush ruleset
table ip filter {
chain input {
type filter hook input priority 0; policy accept;
# Log packets destined for SSH (port 22)
tcp dport 22 log prefix "SSH_PACKET: " counter accept
# Drop all other incoming packets (for demonstration)
drop
}
}
Apply this ruleset:
sudo nft -f your_ruleset_file.nft
Now, to see the logs, you’ll typically look in syslog. The exact file depends on your Linux distribution and syslog daemon configuration, but common locations are:
/var/log/syslog(Debian/Ubuntu)/var/log/messages(CentOS/RHEL)/var/log/kern.log(often where kernel-level messages like firewall logs go)
You can monitor these files in real-time using tail:
sudo tail -f /var/log/syslog
Or, if you’re using journald (common on modern systems), you can use journalctl:
sudo journalctl -f -u nftables
Or more generally, to see kernel messages:
sudo journalctl -f -k
When you attempt to connect to your server via SSH from another machine, you should see log entries appear. For example, you might see something like this in your logs:
Oct 26 10:00:00 your-server-hostname kernel: [ 1234.567890] SSH_PACKET: IN=eth0 OUT= MAC=... SRC=192.168.1.100 DST=192.168.1.50 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=54321 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
Let’s break down the nftables logging mechanism and the output.
The log statement in nftables is a terminal statement for that specific rule. This means that once a packet matches the log rule, the logging action is performed, and then the packet’s fate is determined by the next statement on that rule. In our example, counter accept means the packet is counted (for statistics) and then accepted into the system. If we had used log prefix "DENIED_SSH: " counter drop, it would log and then drop.
The prefix option is crucial. It prepends a string to every log message generated by that rule. This makes it incredibly easy to filter for your specific nftables logs within the vast output of syslog. Without a prefix, you’d have to search for generic terms like "nftables" or "kernel," which might be noisy.
The counter option is also very useful. It increments a packet and byte counter associated with that rule. This allows you to see how many packets have matched the logging rule, which is invaluable for understanding traffic patterns and confirming that your logging is actually being triggered. You can inspect these counters with sudo nft list counters.
The output you see in syslog is a detailed snapshot of the packet at the moment it was logged. Key fields include:
IN: The incoming network interface.OUT: The outgoing network interface (if applicable).MAC: The MAC addresses.SRC: The source IP address.DST: The destination IP address.LEN: The total length of the IP packet.PROTO: The IP protocol (e.g., TCP, UDP, ICMP).SPT: Source port.DPT: Destination port.WINDOW: TCP window size.SYN,ACK,FIN,RST,URG,PSH: TCP flags.
When configuring nftables logging, you need to ensure that your syslog daemon is running and configured to accept kernel messages. For most distributions, this is the default behavior. However, if you’re using a custom syslog configuration or a very minimal setup, you might need to explicitly enable it.
A common pitfall is expecting to see logs immediately without ensuring the syslog daemon is running or that the log file is being written to. Always verify syslog status (sudo systemctl status rsyslog or sudo systemctl status syslog-ng).
Another point of confusion can be the log level. nftables logs at the kern facility, which is usually handled by default. However, if you have specific syslog filters that exclude kernel messages, your nftables logs won’t appear.
The log statement can be placed in any chain where you want to monitor traffic. You can log packets being accepted, dropped, or even forwarded. The flexibility allows you to create detailed audit trails for security analysis or network troubleshooting. For instance, logging all dropped packets can help identify scanning attempts or misconfigured clients.
# Example: Log all dropped packets in the input chain
chain input {
type filter hook input priority 0; policy drop; # Default to drop
# Allow established connections
ct state established,related accept
# Allow loopback
iifname "lo" accept
# Log and drop everything else
log prefix "UNMATCHED_DROP: " counter drop
}
The nftables logging mechanism is part of the kernel’s netfilter subsystem. When a packet matches a log rule, the nftables layer instructs the kernel to format a message and send it to the kernel logging buffer. The syslog daemon (or journald) then reads from this buffer and writes it to the appropriate log file or journal.
When troubleshooting why your nftables logs aren’t appearing, always check the nftables ruleset first for syntax errors or incorrect rule placement. Then, verify the syslog daemon’s status and its configuration for accepting kernel messages. Finally, ensure that packets are actually reaching the log rule by checking the rule’s counters (sudo nft list counters).
The next step after effectively logging packets is often to use this information to refine your firewall rules or to trigger automated responses, such as rate-limiting or blocking offending IP addresses based on repeated log entries.