Configuring Firewalls
Purpose
Guide engineers through configuring firewalls across host-based (iptables, nftables, UFW), cloud-based (AWS Security Groups, NACLs), and container-based (Kubernetes NetworkPolicies) environments with practical rule examples and safety patterns to prevent lockouts and security misconfigurations.
When to Use This Skill
Trigger Phrases:
- •"Configure firewall for [server/service]"
- •"Set up security groups for [AWS resource]"
- •"Allow port [X] through firewall"
- •"Block IP address [X.X.X.X]"
- •"Set up UFW on Ubuntu server"
- •"Create iptables/nftables rules"
- •"Configure bastion host firewall"
- •"Implement egress filtering"
Common Scenarios:
- •Initial server setup and hardening
- •Exposing a new service (web server, API, database)
- •Implementing network segmentation
- •Creating bastion host or jump box
- •Migrating from iptables to nftables
- •Configuring cloud security groups
- •Troubleshooting connectivity issues
Decision Framework: Which Firewall Tool?
Cloud Environments
AWS:
- •Instance-level control → Security Groups (stateful, allow-only rules)
- •Subnet-level enforcement → Network ACLs (stateless, allow + deny rules)
- •Use both for defense-in-depth
GCP:
- •Use VPC Firewall Rules (stateful, priority-based)
Azure:
- •Use Network Security Groups (NSGs) (stateful, priority-based)
Host-Based Linux Firewalls
Ubuntu/Debian + Simplicity:
- •Use UFW (Uncomplicated Firewall) - recommended for most users
- •Front-end for iptables/nftables with simplified syntax
RHEL/CentOS/Fedora:
- •Use firewalld (default on Red Hat ecosystem)
- •Zone-based configuration with dynamic updates
Modern Distro + Advanced Control:
- •Use nftables (best performance, modern standard)
- •O(log n) performance vs iptables O(n)
- •Unified IPv4/IPv6/NAT syntax
Legacy Systems:
- •Use iptables (migrate to nftables when feasible)
- •Required for older kernels (< 4.14)
Kubernetes/Containers
- •Use NetworkPolicies (requires CNI plugin: Calico, Cilium, Weave)
- •See references/k8s-networkpolicies.md
Stateful vs Stateless
Stateful (recommended for most cases):
- •Automatically allows return traffic
- •Simpler configuration
- •Examples: Security Groups, UFW, nftables default
Stateless (specialized use):
- •Must explicitly allow both directions
- •Fine-grained control, less state tracking
- •Examples: Network ACLs, custom nftables rules
Quick Start Examples
UFW (Ubuntu/Debian)
# 1. Set defaults sudo ufw default deny incoming sudo ufw default allow outgoing # 2. CRITICAL: Allow SSH before enabling (prevent lockout) sudo ufw allow ssh sudo ufw limit ssh # Rate-limit to prevent brute force # 3. Allow web traffic sudo ufw allow http # Port 80 sudo ufw allow https # Port 443 # 4. Allow from specific IP (e.g., database access) sudo ufw allow from 192.168.1.100 to any port 5432 # 5. Enable firewall sudo ufw enable # 6. Verify rules sudo ufw status verbose
For complete UFW patterns, see references/ufw-patterns.md
nftables (Modern Linux)
#!/usr/sbin/nft -f
# /etc/nftables.conf
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Accept loopback
iif "lo" accept
# Accept established connections (stateful)
ct state established,related accept
# Drop invalid packets
ct state invalid drop
# Allow SSH
tcp dport 22 accept
# Allow HTTP/HTTPS
tcp dport { 80, 443 } accept
# Log dropped packets
log prefix "nftables-drop: " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Apply: sudo nft -f /etc/nftables.conf
Enable on boot: sudo systemctl enable nftables
For advanced patterns (sets, maps), see references/nftables-patterns.md
AWS Security Groups (Terraform)
# Web server security group
resource "aws_security_group" "web" {
name = "web-server-sg"
description = "Security group for web servers"
vpc_id = aws_vpc.main.id
# Allow HTTP/HTTPS from anywhere
ingress {
description = "HTTPS from anywhere"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow SSH from bastion only
ingress {
description = "SSH from bastion"
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.bastion.id]
}
# Allow all outbound
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "web-server-sg"
}
}
For Security Groups vs NACLs guide, see references/aws-security-groups.md
Safety Checklist
Before enabling any firewall:
- • Always allow SSH before enabling (prevent lockout)
- • Test rules before enabling (dry-run when possible)
- • Enable logging for debugging
- • Document rules in version control (Git)
- • Verify externally with nmap:
nmap -Pn <server-ip> - • Have console access (cloud) or physical access (on-prem)
- • Start with default deny, explicitly allow required traffic
- • Use rate limiting for SSH (
ufw limit ssh)
Common Patterns
Pattern 1: Basic Web Server
Requirements:
- •Allow HTTP (80) and HTTPS (443) from anywhere
- •Allow SSH from specific IP or bastion only
- •Default deny all other inbound traffic
UFW:
sudo ufw default deny incoming sudo ufw allow from 203.0.113.0/24 to any port 22 # Office IP sudo ufw allow http sudo ufw allow https sudo ufw enable
nftables: See references/nftables-patterns.md for complete example
AWS Security Group: See references/aws-security-groups.md for Terraform module
Pattern 2: Database Server (Private)
Requirements:
- •Allow database port (5432, 3306, etc.) from app tier only
- •No public internet access
- •SSH from bastion only
See references/database-patterns.md for implementation
Pattern 3: Bastion Host (Jump Box)
Purpose: Single hardened entry point for SSH access
See references/bastion-pattern.md for complete implementation
Pattern 4: Egress Filtering
Purpose: Control outbound traffic to prevent data exfiltration
See references/egress-filtering.md for implementation
Key Concepts
Stateful Firewalls
Track connection state (established, related, new):
- •Automatically allow return traffic
- •Simpler rule configuration
- •Used by: Security Groups, UFW, nftables (default)
Stateless Firewalls
No connection tracking:
- •Must explicitly allow both directions
- •Must allow ephemeral ports (1024-65535) for return traffic
- •Used by: Network ACLs
Defense-in-Depth
Layer multiple firewall controls:
- •Cloud: Security Groups + NACLs
- •Host: UFW/nftables + fail2ban
- •Container: NetworkPolicies
Rule Evaluation
Security Groups (AWS): All rules evaluated, most permissive wins Network ACLs (AWS): Sequential evaluation, first match wins nftables/iptables: Sequential, first match wins UFW: Sequential by rule number
Universal Best Practices
- •Default Deny: Start with deny-all, explicitly allow required traffic
- •Principle of Least Privilege: Only open necessary ports/IPs
- •No 0.0.0.0/0 on Sensitive Ports: Never allow SSH/RDP/database from anywhere
- •Version Control: Store firewall rules in Git
- •Logging: Enable and monitor firewall logs
- •Regular Audits: Review rules quarterly, remove unused
- •Don't Mix Tools: Avoid running iptables and nftables simultaneously
- •Test Before Production: Use staging environment first
Advanced Topics
Bastion Host Architecture: See references/bastion-pattern.md for single entry point patterns
DMZ (Demilitarized Zone): See references/dmz-pattern.md for network segmentation
Egress Filtering: See references/egress-filtering.md for outbound traffic control
Kubernetes NetworkPolicies: See references/k8s-networkpolicies.md for pod-to-pod isolation
Migrating iptables to nftables: See references/migration-guide.md for conversion process
Cloud Firewall Comparisons:
- •AWS: references/aws-security-groups.md
- •GCP: references/gcp-firewall.md
- •Azure: references/azure-nsg.md
Troubleshooting
"I locked myself out via SSH":
- •Cloud: Use console/session manager to access
- •On-prem: Physical console access or IPMI/iLO
- •Prevention: Always allow SSH before enabling firewall
Connection timeouts:
- •Check if firewall is blocking traffic:
sudo ufw statusorsudo nft list ruleset - •Verify service is listening:
ss -tuln | grep <port> - •Test externally:
nmap -Pn <ip> -p <port> - •Check logs:
/var/log/ufw.logorjournalctl -u nftables
AWS: Ephemeral port issues:
- •NACLs need return traffic: Allow 1024-65535 inbound
- •Security Groups are stateful (no ephemeral config needed)
Kubernetes pods can't communicate:
- •Check NetworkPolicies:
kubectl get networkpolicies -n <namespace> - •Verify CNI plugin supports NetworkPolicies (Calico, Cilium)
- •Test without policies first
For complete troubleshooting guide, see references/troubleshooting.md
Common Mistakes to Avoid
❌ Allowing 0.0.0.0/0 on SSH/RDP → Use bastion or VPN ❌ Forgetting to enable firewall → Rules configured but not active ❌ Not testing before enabling → Risk of lockout ❌ Missing ephemeral ports in NACLs → Return traffic blocked ❌ Running iptables + nftables → Conflicts and unpredictable behavior ❌ No logging → Can't debug or audit ❌ Large port ranges → Unnecessary attack surface ❌ Not documenting rules → Future confusion
Tool-Specific Commands
UFW
# Status sudo ufw status verbose sudo ufw status numbered # Add rules sudo ufw allow <port>/<protocol> sudo ufw allow from <ip> to any port <port> sudo ufw limit ssh # Rate limiting # Delete rules sudo ufw delete <rule-number> sudo ufw delete allow 80/tcp # Logging sudo ufw logging on tail -f /var/log/ufw.log # Reset (disable and remove all rules) sudo ufw reset
nftables
# List ruleset sudo nft list ruleset # Load config sudo nft -f /etc/nftables.conf # Flush all rules sudo nft flush ruleset # Add rule dynamically sudo nft add rule inet filter input tcp dport 8080 accept # Enable on boot sudo systemctl enable nftables
iptables
# List rules sudo iptables -L -v -n sudo iptables -L INPUT --line-numbers # Add rule sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Delete rule sudo iptables -D INPUT <rule-number> # Save rules sudo netfilter-persistent save # Debian/Ubuntu sudo service iptables save # RHEL/CentOS
AWS CLI
# List security groups aws ec2 describe-security-groups --group-ids sg-xxxxx # List NACLs aws ec2 describe-network-acls --network-acl-ids acl-xxxxx # Add rule to security group aws ec2 authorize-security-group-ingress \ --group-id sg-xxxxx \ --protocol tcp \ --port 443 \ --cidr 0.0.0.0/0
For infrastructure as code approach, use Terraform (see references/aws-security-groups.md)
Examples Directory
Complete working examples available in:
- •
examples/ufw/- UFW configuration scripts - •
examples/nftables/- nftables rulesets - •
examples/iptables/- iptables rule scripts - •
examples/terraform-aws/- AWS Security Groups and NACLs - •
examples/terraform-gcp/- GCP firewall rules - •
examples/terraform-azure/- Azure NSGs - •
examples/kubernetes/- NetworkPolicy manifests
Integration Points
Related Skills:
- •
security-hardening - Firewalls are one component of server hardening. See security-hardening skill for SSH hardening, fail2ban, auditd, and SELinux.
- •
building-ci-pipelines - CI runners need network access to repos and artifact stores. Configure firewall rules for self-hosted runners.
- •
deploying-applications - Applications need firewall rules for service exposure. See deploying-applications for integration.
- •
infrastructure-as-code - Manage firewalls as code with Terraform/CloudFormation. See infrastructure-as-code for IaC best practices.
- •
kubernetes-operations - Advanced K8s networking beyond basic NetworkPolicies. See kubernetes-operations for Services, Ingress, and CNI configuration.
- •
network-architecture - Broader network design patterns. See network-architecture for VPC design, subnets, and routing.
Reference Files
Tool-Specific Guides:
- •references/ufw-patterns.md - Complete UFW guide with examples
- •references/nftables-patterns.md - nftables syntax, sets, maps, logging
- •references/iptables-patterns.md - iptables basics and migration path
- •references/migration-guide.md - Convert iptables to nftables
Cloud Provider Guides:
- •references/aws-security-groups.md - Security Groups vs NACLs with Terraform
- •references/gcp-firewall.md - GCP VPC firewall rules
- •references/azure-nsg.md - Azure Network Security Groups
Advanced Patterns:
- •references/bastion-pattern.md - Jump box architecture
- •references/dmz-pattern.md - Network segmentation with DMZ
- •references/egress-filtering.md - Outbound traffic control
- •references/k8s-networkpolicies.md - Kubernetes pod isolation
Support:
- •references/troubleshooting.md - Common issues and solutions
- •references/decision-tree.md - Visual guide for tool selection