| name | firewall-config |
| description | Configure iptables, nftables, and cloud firewalls. Implement network segmentation and traffic filtering. Use when securing network perimeters or implementing security zones. |
| license | MIT |
| metadata | {"author":"devops-skills","version":"1.0"} |
Firewall Configuration
Configure host-based and cloud firewalls for network security.
When to Use This Skill
Use this skill when:
- Setting up a new server and need to restrict network access
- Implementing network segmentation between application tiers
- Configuring cloud security groups for AWS, GCP, or Azure resources
- Migrating from iptables to nftables
- Auditing existing firewall rules for compliance
- Responding to a security incident requiring emergency network blocks
Prerequisites
- Root or sudo access on Linux hosts
- AWS CLI configured for cloud security groups
- Understanding of TCP/IP, ports, and protocols
- Network diagram showing required traffic flows
iptables
Basic Setup with Default Deny
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -p tcp --dport 22 -s 10.0.100.0/24 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
Anti-DDoS Rules
iptables -A INPUT -p tcp --syn -m limit --limit 25/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
Application-Specific Rules
iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 9100 -s 10.0.200.0/24 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 123 -j ACCEPT
iptables -I INPUT 1 -s 203.0.113.50 -j DROP
UFW (Uncomplicated Firewall)
ufw default deny incoming
ufw default allow outgoing
ufw enable
ufw allow from 10.0.100.0/24 to any port 22 proto tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 'Nginx Full'
ufw limit ssh
ufw allow 8000:8080/tcp
ufw deny from 203.0.113.50
ufw status verbose
ufw status numbered
ufw delete 3
ufw app list
ufw app info 'Nginx Full'
nftables
Complete Server Configuration
#!/usr/sbin/nft -f
flush ruleset
define LAN = 10.0.0.0/16
define MGMT = 10.0.100.0/24
define MONITOR = 10.0.200.0/24
table inet filter {
set rate_limit {
type ipv4_addr
flags dynamic,timeout
timeout 1m
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 10/second accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert } accept
tcp dport 22 ip saddr $MGMT accept
tcp dport { 80, 443 } accept
tcp dport 9100 ip saddr $MONITOR accept
tcp flags syn limit rate over 25/second burst 50 packets drop
log prefix "nft-drop: " level warn limit rate 5/minute
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table ip nat {
chain prerouting {
nat hook prerouting priority -100;
tcp dport 8080 dnat to 10.0.1.10:8080
}
chain postrouting {
nat hook postrouting priority 100;
oifname masquerade
}
}
nftables Management Commands
nft -f /etc/nftables.conf
nft list ruleset
nft list table inet filter
nft add rule inet filter input tcp dport 8443 accept
nft insert rule inet filter input position 5 ip saddr 10.0.50.0/24 tcp dport 3306 accept
nft -a list chain inet filter input
nft delete rule inet filter input handle 15
nft monitor
AWS Security Groups
Terraform Configuration
# Web tier security group
resource "aws_security_group" "web" {
name_prefix = "web-sg-"
vpc_id = aws_vpc.main.id
description = "Security group for web servers"
ingress {
description = "HTTPS from internet"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP redirect"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "All outbound"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "web-sg"
Environment = "production"
ManagedBy = "terraform"
}
}
# App tier - only accepts traffic from web tier
resource "aws_security_group" "app" {
name_prefix = "app-sg-"
vpc_id = aws_vpc.main.id
description = "Security group for application servers"
ingress {
description = "HTTP from web tier"
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.web.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Database tier - only accepts from app tier
resource "aws_security_group" "db" {
name_prefix = "db-sg-"
vpc_id = aws_vpc.main.id
description = "Security group for database servers"
ingress {
description = "PostgreSQL from app tier"
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
AWS CLI Commands
aws ec2 create-security-group \
--group-name web-sg \
--description "Web server SG" \
--vpc-id vpc-0abc123
aws ec2 authorize-security-group-ingress \
--group-id sg-0abc123 \
--protocol tcp --port 443 \
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \
--group-id sg-0db456 \
--protocol tcp --port 5432 \
--source-group sg-0app789
aws ec2 revoke-security-group-ingress \
--group-id sg-0abc123 \
--protocol tcp --port 22 \
--cidr 0.0.0.0/0
aws ec2 describe-security-group-rules \
--filters Name=group-id,Values=sg-0abc123
Firewall Rule Audit Script
#!/bin/bash
echo "=== Firewall Audit Report ==="
echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "Host: $(hostname)"
echo ""
if command -v nft &>/dev/null; then
echo "--- nftables rules ---"
nft list ruleset
elif command -v iptables &>/dev/null; then
echo "--- iptables rules ---"
iptables -L -n -v --line-numbers
fi
echo ""
echo "--- Open ports ---"
ss -tlnp
echo ""
echo "--- Potential issues ---"
if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:22"; then
echo "WARNING: SSH (port 22) open to 0.0.0.0/0 - restrict to management subnet"
fi
if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:3306"; then
echo "CRITICAL: MySQL (port 3306) open to 0.0.0.0/0"
fi
if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:5432";
DEFAULT_INPUT=$(iptables -L INPUT 2>/dev/null | -1 | grep -oP )
[ = ];
Troubleshooting
| Problem | Cause | Solution |
|---|
| Locked out of SSH | Rule order or default deny applied before allow | Use out-of-band console access; add SSH allow rule first |
| Rules lost after reboot | Rules not persisted | Install iptables-persistent or save to /etc/nftables.conf |
| Docker bypasses iptables | Docker modifies iptables FORWARD chain | Use DOCKER-USER chain for custom rules; set "iptables": false in daemon.json |
| nftables and iptables conflict | Both running simultaneously | Migrate fully to nftables; remove iptables packages |
| AWS SG rule limit reached | Max 60 inbound rules per SG | Use prefix lists or consolidate CIDR ranges |
| Legitimate traffic blocked | Rule ordering issue | Place more specific allow rules before general deny rules |
Best Practices
- Default deny policy on all chains
- Minimal rule sets - only open what is required
- Regular rule audits (monthly minimum)
- Log denied traffic for security monitoring
- Document all rules with descriptions and ticket references
- Use connection tracking for stateful inspection
- Rate limit inbound connections to prevent DDoS
- Separate management traffic from application traffic
- Test rule changes in staging before production
- Keep persistent backups of working rule sets
Related Skills