Why Comment Your IPTables Rules?
As your Linux firewall configuration grows beyond a handful of rules, understanding the purpose of each rule becomes increasingly difficult. A complex production server might have dozens or even hundreds of IPTables rules covering SSH access, web traffic, database connections, VPN tunnels, rate limiting, and application-specific filtering. Without documentation, troubleshooting becomes a guessing game, and well-meaning administrators risk breaking critical rules when they cannot tell what each one does.
IPTables provides a built-in comment module that allows you to attach human-readable descriptions directly to individual rules. These comments are stored as part of the rule definition, survive iptables-save and iptables-restore operations, and appear when listing rules with verbose output. Comments serve the same purpose for firewall rules that code comments serve in software: they explain the intent behind each decision, making maintenance and handoff between team members much easier.
The Comment Module Syntax
To add a comment to an IPTables rule, use the -m comment match module along with the --comment option:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT -m comment --comment "Allow SSH access"
The comment module is available by default in modern Linux kernels (2.6.x and later) and does not need to be separately installed. The -m comment flag loads the comment match extension, and --comment specifies the actual comment text.
Basic Syntax Structure
iptables [chain] [match criteria] -j [target] -m comment --comment "your comment here"
The comment module can appear anywhere in the rule, but placing it at the end keeps the rule readable by separating the functional match criteria from the documentation. Some administrators prefer to place it immediately after the chain specification for consistency:
# Comment at the end (common convention)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT -m comment --comment "Allow HTTP"
# Comment after chain (alternative convention)
iptables -A INPUT -m comment --comment "Allow HTTP" -p tcp --dport 80 -j ACCEPT
Both approaches are functionally identical. Choose one convention and use it consistently across your entire ruleset.
Character Limits and Constraints
The IPTables comment module has a maximum comment length of 256 characters. Comments exceeding this limit will cause the rule to fail with an error. While 256 characters is generous, it encourages concise documentation rather than lengthy paragraphs.
Additional constraints to be aware of:
- Quoting: Always enclose comments in double quotes if they contain spaces. Single-word comments technically work without quotes, but quoting is a good habit to prevent shell interpretation issues.
- Special characters: Avoid shell special characters (backticks, dollar signs, exclamation marks) in comments, or escape them properly. These characters can be misinterpreted by the shell before being passed to IPTables.
- Unicode: While the kernel stores comments as byte strings and technically allows UTF-8, it is safest to stick to ASCII characters for maximum compatibility across tools and systems.
- Newlines: Comments cannot contain newline characters. Each comment must be a single line.
Examples for Different Rule Types
Access Control Rules
# Allow SSH from office network
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT \
-m comment --comment "SSH: office network (Chicago)"
# Allow SSH from VPN
iptables -A INPUT -p tcp --dport 22 -s 10.8.0.0/24 -j ACCEPT \
-m comment --comment "SSH: OpenVPN clients"
# Block known attacker
iptables -A INPUT -s 198.51.100.55 -j DROP \
-m comment --comment "Block: brute force source, reported 2024-03-15"
Service Rules
# Web server
iptables -A INPUT -p tcp --dport 80 -j ACCEPT \
-m comment --comment "HTTP: public web server"
iptables -A INPUT -p tcp --dport 443 -j ACCEPT \
-m comment --comment "HTTPS: public web server"
# Database (restricted access)
iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.0/24 -j ACCEPT \
-m comment --comment "MySQL: app server subnet only"
iptables -A INPUT -p tcp --dport 3306 -j DROP \
-m comment --comment "MySQL: block all other access"
# Mail server
iptables -A INPUT -p tcp --dport 25 -j ACCEPT \
-m comment --comment "SMTP: inbound mail"
iptables -A INPUT -p tcp --dport 587 -j ACCEPT \
-m comment --comment "SMTP submission: authenticated clients"
Rate Limiting Rules
# SSH rate limiting (see: /learn/iptables-rate-limiting)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH \
-m comment --comment "SSH rate limit: track new connections"
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 --name SSH -j DROP \
-m comment --comment "SSH rate limit: drop >4 attempts/60s"
NAT and Forwarding Rules
# Port forwarding to internal web server
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.1.10:80 \
-m comment --comment "NAT: forward HTTP to internal web server"
# Masquerade outbound traffic
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE \
-m comment --comment "NAT: masquerade outbound on eth0"
Logging Rules
# Log dropped packets before the default drop
iptables -A INPUT -j LOG --log-prefix "DROPPED: " --log-level 4 \
-m comment --comment "Log all packets before default drop"
iptables -A INPUT -j DROP \
-m comment --comment "Default policy: drop all unmatched"
Viewing Comments
Comments are visible when listing rules with the verbose flag:
# Show rules with comments
iptables -L -v -n
# Example output:
# Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
# pkts bytes target prot opt in out source destination
# 1234 98K ACCEPT tcp -- * * 203.0.113.0/24 0.0.0.0/0 tcp dpt:22 /* SSH: office network (Chicago) */
# 567 45K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 /* HTTP: public web server */
# 23 1840 DROP all -- * * 198.51.100.55 0.0.0.0/0 /* Block: brute force source, reported 2024-03-15 */
Comments appear enclosed in /* */ delimiters in the output, making them easy to spot. They also appear in iptables-save output in the same format:
# iptables-save output
-A INPUT -s 203.0.113.0/24 -p tcp -m tcp --dport 22 -m comment --comment "SSH: office network (Chicago)" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -m comment --comment "HTTP: public web server" -j ACCEPT
Best Practices for Documenting Firewall Rules
Use a Consistent Naming Convention
Adopt a standard format for your comments. A useful pattern is Service: description (context):
# Good: consistent format
"SSH: office network (Chicago)"
"SSH: VPN clients (OpenVPN)"
"HTTP: public web server"
"MySQL: app server subnet only"
"Block: brute force source, reported 2024-03-15"
# Bad: inconsistent format
"allow ssh from office"
"HTTP traffic"
"mysql access for apps"
"blocked bad IP"
Include Dates and Ticket References
For temporary rules, blocking rules, and exception rules, include the date and a reference to the change request or incident ticket:
# Include date for temporary or incident-related rules
iptables -A INPUT -s 198.51.100.0/24 -j DROP \
-m comment --comment "Block: DDoS source, INC-2024-0342, 2024-03-15"
# Include expiration for temporary rules
iptables -A INPUT -p tcp --dport 8080 -s 192.0.2.10 -j ACCEPT \
-m comment --comment "Temp: vendor access for migration, expires 2024-04-01"
Document the Why, Not Just the What
The rule itself shows what it does (the ports, protocols, and IPs). The comment should explain why the rule exists:
# Bad: restates the obvious
iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.5 -j ACCEPT \
-m comment --comment "Allow TCP 3306 from 10.0.1.5"
# Good: explains the purpose
iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.5 -j ACCEPT \
-m comment --comment "MySQL: replication from secondary db server"
Group Related Rules
Use a prefix system to group related rules together. When viewing rules with iptables -L, the comments make it immediately clear which rules are related:
# SSH rules grouped by prefix
"SSH: office network (Chicago)"
"SSH: VPN clients (OpenVPN)"
"SSH rate limit: track new connections"
"SSH rate limit: drop >4 attempts/60s"
# Web server rules grouped by prefix
"HTTP: public web server"
"HTTPS: public web server"
"HTTP rate limit: track connections"
"HTTP rate limit: drop >50/10s"
Review and Audit Regularly
Comments make auditing much easier. Schedule regular reviews of your firewall rules:
# Export rules with comments for review
iptables-save > /root/firewall-audit-$(date +%Y%m%d).txt
# Search for expired temporary rules
iptables-save | grep -i "temp\|expires\|temporary"
# Search for rules related to a specific incident
iptables-save | grep "INC-2024"
Comments in Saved Rules
When you save your IPTables rules with iptables-save, the comments are preserved as part of the rule definition. When you restore rules with iptables-restore, the comments are restored as well. This means your documentation survives reboots, backups, and migration between servers.
# Save rules (comments included)
iptables-save > /etc/iptables/rules.v4
# Restore rules (comments restored)
iptables-restore < /etc/iptables/rules.v4
You can also edit the saved rules file directly with a text editor. The comment syntax in the file is the same as in the command line, so you can add, modify, or remove comments by editing the saved file and then restoring it. For more on saving and restoring rules, see our guide on creating default blocks with IPTables.
Comments in ip6tables
The comment module works identically in ip6tables (the IPv6 equivalent of IPTables). All the same syntax, character limits, and best practices apply:
# IPv6 rule with comment
ip6tables -A INPUT -p tcp --dport 22 -s 2001:db8::/32 -j ACCEPT \
-m comment --comment "SSH: office IPv6 network"
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT \
-m comment --comment "HTTP: public web server (IPv6)"
Maintaining consistent comments across both your IPv4 and IPv6 rulesets is important for comprehensive firewall management.
Scripting with Comments
When managing firewall rules through scripts, comments become even more valuable. They allow scripts to identify and manage specific rules programmatically:
#!/bin/bash
# Remove all rules with a specific comment
COMMENT="Temp: vendor access for migration, expires 2024-04-01"
# Find and delete rules matching the comment
while iptables -L INPUT -n --line-numbers | grep -q "$COMMENT"; do
LINE=$(iptables -L INPUT -n --line-numbers | grep "$COMMENT" | head -1 | awk '{print $1}')
iptables -D INPUT $LINE
done
This approach makes it easy to create scripts that add temporary rules and clean them up automatically based on their comments.
Summary
Commenting your IPTables rules using the -m comment --comment module is a simple but essential practice for maintaining a manageable and auditable firewall configuration. Good comments explain the purpose of each rule, include dates and ticket references for temporary rules, and follow a consistent naming convention. Combined with proper rule organization, rate limiting, and default block policies, well-documented firewall rules make your Linux security infrastructure easier to maintain, troubleshoot, and hand off between team members.
Need help managing your firewall infrastructure? Explore NOC.org plans to get started.