Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure host-based firewalls (iptables, nftables, UFW) and cloud security groups (AWS, GCP, Azure) with practical rules for common scenarios like web servers, databases, and bastion hosts. Use when exposing services, hardening servers, or implementing network segmentation with defense-in-depth strategies.
.claude/skills/ancoleman-configuring-firewalls/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-17 | ✗→✓ | ▲ Improved | 212% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 675% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 177% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 274% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 375% | 0% |
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.
Trigger Phrases:
Common Scenarios:
AWS:
GCP:
Azure:
Ubuntu/Debian + Simplicity:
RHEL/CentOS/Fedora:
Modern Distro + Advanced Control:
Legacy Systems:
Stateful (recommended for most cases):
Stateless (specialized use):
bash# 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#!/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
hcl# 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
Before enabling any firewall:
nmap -Pn <server-ip>ufw limit ssh)Requirements:
UFW:
bashsudo 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
Requirements:
See references/database-patterns.md for implementation
Purpose: Single hardened entry point for SSH access
See references/bastion-pattern.md for complete implementation
Purpose: Control outbound traffic to prevent data exfiltration
See references/egress-filtering.md for implementation
Track connection state (established, related, new):
No connection tracking:
Layer multiple firewall controls:
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
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:
"I locked myself out via SSH":
Connection timeouts:
sudo ufw status or sudo nft list rulesetss -tuln | grep <port>nmap -Pn <ip> -p <port>/var/log/ufw.log or journalctl -u nftablesAWS: Ephemeral port issues:
Kubernetes pods can't communicate:
kubectl get networkpolicies -n <namespace>For complete troubleshooting guide, see references/troubleshooting.md
❌ 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
bash# 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
bash# 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
bash# 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
bash# 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)
Complete working examples available in:
examples/ufw/ - UFW configuration scriptsexamples/nftables/ - nftables rulesetsexamples/iptables/ - iptables rule scriptsexamples/terraform-aws/ - AWS Security Groups and NACLsexamples/terraform-gcp/ - GCP firewall rulesexamples/terraform-azure/ - Azure NSGsexamples/kubernetes/ - NetworkPolicy manifestsRelated Skills:
Tool-Specific Guides:
Cloud Provider Guides:
Advanced Patterns:
Support:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | pass→pass | 3,185 | 4,329 | +36% | 1 | 1 | 0% | 563 | 4,364 | +675% | 0 | 0 | — |
case-06 | pass→pass | 9,484 | 7,170 | -24% | 1 | 1 | 0% | 1,822 | 5,038 | +177% | 0 | 0 | — |
case-01 | pass→pass | 6,660 | 5,880 | -12% | 1 | 1 | 0% | 1,261 | 4,721 | +274% | 0 | 0 | — |
case-02 | pass→pass | 6,363 | 8,550 | +34% | 1 | 1 | 0% | 1,090 | 5,177 | +375% | 0 | 0 | — |
case-03 | pass→pass | 16,533 | 11,035 | -33% | 1 | 1 | 0% | 2,740 | 5,355 | +95% | 0 | 0 | — |
case-04 | pass→pass | 7,532 | 6,369 | -15% | 1 | 1 | 0% | 1,290 | 4,831 | +274% | 0 | 0 | — |
case-07 | pass→pass | 13,151 | 10,622 | -19% | 1 | 1 | 0% | 2,016 | 5,280 | +162% | 0 | 0 | — |
case-08 | pass→pass | 6,633 | 5,785 | -13% | 1 | 1 | 0% | 1,265 | 4,814 | +281% | 0 | 0 | — |
case-09 | pass→pass | 3,873 | 4,547 | +17% | 1 | 1 | 0% | 707 | 4,348 | +515% | 0 | 0 | — |
case-10 | pass→pass | 13,613 | 11,999 | -12% | 1 | 1 | 0% | 2,313 | 5,670 | +145% | 0 | 0 | — |
case-11 | pass→pass | 4,304 | 5,152 | +20% | 1 | 1 | 0% | 707 | 4,480 | +534% | 0 | 0 | — |
case-12 | pass→pass | 6,586 | 5,963 | -9% | 1 | 1 | 0% | 1,118 | 4,659 | +317% | 0 | 0 | — |
case-13 | pass→pass | 8,560 | 7,492 | -12% | 1 | 1 | 0% | 1,305 | 4,786 | +267% | 0 | 0 | — |
case-14 | pass→pass | 14,604 | 16,893 | +16% | 1 | 1 | 0% | 2,343 | 6,542 | +179% | 0 | 0 | — |
case-15 | pass→pass | 12,002 | 8,546 | -29% | 1 | 1 | 0% | 1,892 | 5,027 | +166% | 0 | 0 | — |
case-21 | pass→pass | 8,215 | 6,514 | -21% | 1 | 1 | 0% | 1,516 | 4,756 | +214% | 0 | 0 | — |
case-16 | pass→pass | 6,033 | 6,654 | +10% | 1 | 1 | 0% | 1,007 | 4,774 | +374% | 0 | 0 | — |
case-17 | fail→pass | 8,986 | 5,485 | -39% | 1 | 1 | 0% | 1,447 | 4,521 | +212% | 0 | 0 | — |
case-18 | pass→pass | 8,857 | 9,269 | +5% | 1 | 1 | 0% | 1,631 | 5,200 | +219% | 0 | 0 | — |
case-19 | pass→pass | 4,910 | 3,111 | -37% | 1 | 1 | 0% | 722 | 4,087 | +466% | 0 | 0 | — |
case-20 | pass→pass | 8,275 | 7,980 | -4% | 1 | 1 | 0% | 1,236 | 4,919 | +298% | 0 | 0 | — |
case-22 | pass→pass | 5,818 | 6,204 | +7% | 1 | 1 | 0% | 1,078 | 4,760 | +342% | 0 | 0 | — |
case-23 | pass→pass | 12,537 | 13,307 | +6% | 1 | 1 | 0% | 2,678 | 6,466 | +141% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.