Firewall Configuration Cheat Sheet
Covers practical firewall rule syntax for iptables and cloud security groups, plus best practices for default-deny policies.
iptables Basics (Linux)
Common commands to view and set firewall rules.
# List current rules with line numbersiptables -L -n -v --line-numbers# Allow SSH from a specific subnetiptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT# Allow established/related connectionsiptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT# Default-deny policy on INPUT chainiptables -P INPUT DROP# Save rules (Debian/Ubuntu)netfilter-persistent save
UFW (Simplified Firewall)
Higher-level firewall management on Ubuntu/Debian systems.
ufw default deny incomingufw default allow outgoingufw allow 22/tcp # SSHufw allow 443/tcp # HTTPSufw allow from 10.0.0.0/24 to any port 3306 # DB access from internal net onlyufw enableufw status verbose
Key Concepts
Terminology used when designing firewall policy.
- Default-deny- Block all traffic by default, explicitly allow only what's needed
- Stateful inspection- Tracks connection state so return traffic for allowed sessions is automatically permitted
- Ingress vs. egress- Inbound traffic to the host vs. outbound traffic leaving it — both should be filtered
- Security groups (cloud)- Stateful, instance-level virtual firewalls in AWS/Azure/GCP
- NACLs (AWS)- Stateless, subnet-level firewall rules evaluated in addition to security groups
Configuration Best Practices
Habits that keep firewall rulesets secure and maintainable.
- Least exposure- Only open ports actually required by the service
- Restrict by source- Scope management ports (SSH/RDP) to known IP ranges, never 0.0.0.0/0
- Log dropped traffic- Helps detect scanning and troubleshoot blocked legitimate traffic
- Document every rule- Include owner and purpose so rules can be safely retired later
- Regular audits- Periodically review rules to remove stale or overly permissive entries
nftables Ruleset (iptables successor)
A modern nftables configuration replacing separate iptables/ip6tables/ipset tooling with one syntax.
# /etc/nftables.confflush rulesettable inet filter { chain input { type filter hook input priority 0; policy drop; iif lo accept ct state established,related accept ct state invalid drop tcp dport 22 ip saddr 10.0.0.0/24 accept tcp dport { 80, 443 } accept ip protocol icmp accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; }}
SYN Flood & Connection Rate Limiting
Throttling new connection attempts with iptables to blunt basic flood/scan traffic.
# Limit new SYN packets to 20/sec with a burst of 40, drop the restiptables -N SYN_FLOODiptables -A INPUT -p tcp --syn -j SYN_FLOODiptables -A SYN_FLOOD -m limit --limit 20/s --limit-burst 40 -j RETURNiptables -A SYN_FLOOD -j DROP# Cap concurrent connections per source IP to a service (basic DoS mitigation)iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 --connlimit-mask 32 -j REJECT# Enable SYN cookies at the kernel level as a second line of defensesysctl -w net.ipv4.tcp_syncookies=1
ipset for Large Blocklists
Matching thousands of IPs efficiently instead of one iptables rule per address.
# Create a hash-based set and load a blocklist into itipset create blocklist hash:ip hashsize 4096 maxelem 200000ipset add blocklist 203.0.113.5ipset add blocklist 198.51.100.0/24# Single iptables rule references the whole set (O(1) lookup vs O(n) rule chain)iptables -I INPUT -m set --match-set blocklist src -j DROP# Persist across rebootsipset save > /etc/ipset.rules# and restore it from /etc/rc.local or a systemd unit:# ipset restore < /etc/ipset.rules
Advanced Firewall Concepts
Terminology relevant once you move past single-host, single-rule-chain setups.
- conntrack table- Kernel's connection-tracking state table; exhausting it (net.netfilter.nf_conntrack_max) causes silent drops under load
- NAT table vs filter table- iptables/nftables separate address translation (PREROUTING/POSTROUTING) from packet filtering (INPUT/FORWARD/OUTPUT)
- firewalld zones- RHEL/CentOS abstraction grouping interfaces by trust level (public, internal, trusted) with a rule set per zone
- Egress filtering- Restricting outbound traffic to known-good destinations; limits data exfiltration and C2 callback paths after a compromise
- ULOG/NFLOG- Kernel logging targets that send dropped/matched packets to userspace for structured logging instead of dmesg
- Web Application Firewall (WAF)- Layer-7 filtering (SQLi/XSS pattern matching) that complements, but doesn't replace, network-layer firewall rules
AWS Security Group as Code (Terraform)
Declarative, reviewable firewall rules for cloud infrastructure instead of manual console clicks.
resource "aws_security_group" "app" { name = "app-sg" description = "Default-deny; explicit allow only" vpc_id = aws_vpc.main.id ingress { description = "HTTPS from anywhere" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH from bastion subnet only" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["10.0.1.0/24"] } egress { description = "Allow all outbound" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }}
When testing new iptables rules remotely, always add a cron job like 'iptables-restore < /etc/iptables/rules.v4.bak' scheduled a few minutes out as a failsafe — a bad default-deny rule can lock you out instantly with no console access.