firewall-config

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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
在以下场景中使用此技能:
  • 搭建新服务器并需要限制网络访问时
  • 在应用层级之间实现网络分段时
  • 为AWS、GCP或Azure资源配置云安全组时
  • 从iptables迁移至nftables时
  • 审计现有防火墙规则以符合合规要求时
  • 应对需要紧急阻断网络的安全事件时

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
  • Linux主机的Root或sudo权限
  • 已配置AWS CLI以管理云安全组
  • 了解TCP/IP、端口及协议知识
  • 包含所需流量流向的网络拓扑图

iptables

iptables

Basic Setup with Default Deny

默认拒绝的基础配置

bash
undefined
bash
undefined

Flush existing rules

Flush existing rules

iptables -F iptables -X iptables -t nat -F iptables -t mangle -F
iptables -F iptables -X iptables -t nat -F iptables -t mangle -F

Default policies - deny all inbound, allow outbound

Default policies - deny all inbound, allow outbound

iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT

Allow established connections

Allow established connections

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Allow loopback

Allow loopback

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

Drop invalid packets

Drop invalid packets

iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Allow SSH (restrict to management subnet)

Allow SSH (restrict to management subnet)

iptables -A INPUT -p tcp --dport 22 -s 10.0.100.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 10.0.100.0/24 -j ACCEPT

Allow HTTP/HTTPS from anywhere

Allow HTTP/HTTPS from anywhere

iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

Allow ICMP (ping) with rate limiting

Allow ICMP (ping) with rate limiting

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT

Log dropped packets (rate limited to avoid log flooding)

Log dropped packets (rate limited to avoid log flooding)

iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4

Save rules (Debian/Ubuntu)

Save rules (Debian/Ubuntu)

iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
undefined
iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
undefined

Anti-DDoS Rules

抗DDoS规则

bash
undefined
bash
undefined

SYN flood protection

SYN flood protection

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 --syn -m limit --limit 25/s --limit-burst 50 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP

Limit new connections per source IP

Limit new connections per source IP

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT

Block port scanning (detect TCP flags abuse)

Block port scanning (detect TCP flags abuse)

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
undefined
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
undefined

Application-Specific Rules

应用专属规则

bash
undefined
bash
undefined

Web server with database backend

Web server with database backend

Allow app servers to reach database (port 5432)

Allow app servers to reach database (port 5432)

iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT

Allow monitoring (Prometheus node exporter)

Allow monitoring (Prometheus node exporter)

iptables -A INPUT -p tcp --dport 9100 -s 10.0.200.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 9100 -s 10.0.200.0/24 -j ACCEPT

DNS resolution

DNS resolution

iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A INPUT -p tcp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A INPUT -p tcp --sport 53 -j ACCEPT

NTP

NTP

iptables -A INPUT -p udp --sport 123 -j ACCEPT
iptables -A INPUT -p udp --sport 123 -j ACCEPT

Block specific IP (incident response)

Block specific IP (incident response)

iptables -I INPUT 1 -s 203.0.113.50 -j DROP
undefined
iptables -I INPUT 1 -s 203.0.113.50 -j DROP
undefined

UFW (Uncomplicated Firewall)

UFW(简易防火墙)

bash
undefined
bash
undefined

Enable UFW with default deny

Enable UFW with default deny

ufw default deny incoming ufw default allow outgoing ufw enable
ufw default deny incoming ufw default allow outgoing ufw enable

Allow SSH from management network

Allow SSH from management network

ufw allow from 10.0.100.0/24 to any port 22 proto tcp
ufw allow from 10.0.100.0/24 to any port 22 proto tcp

Allow HTTP/HTTPS

Allow HTTP/HTTPS

ufw allow 80/tcp ufw allow 443/tcp
ufw allow 80/tcp ufw allow 443/tcp

Allow specific application profile

Allow specific application profile

ufw allow 'Nginx Full'
ufw allow 'Nginx Full'

Rate limit SSH (max 6 connections in 30 seconds)

Rate limit SSH (max 6 connections in 30 seconds)

ufw limit ssh
ufw limit ssh

Allow port range

Allow port range

ufw allow 8000:8080/tcp
ufw allow 8000:8080/tcp

Deny specific IP

Deny specific IP

ufw deny from 203.0.113.50
ufw deny from 203.0.113.50

Check status

Check status

ufw status verbose ufw status numbered
ufw status verbose ufw status numbered

Delete a rule by number

Delete a rule by number

ufw delete 3
ufw delete 3

Application profiles

Application profiles

ufw app list ufw app info 'Nginx Full'
undefined
ufw app list ufw app info 'Nginx Full'
undefined

nftables

nftables

Complete Server Configuration

完整服务器配置

bash
#!/usr/sbin/nft -f
flush ruleset
bash
#!/usr/sbin/nft -f
flush ruleset

Define variables

Define variables

define LAN = 10.0.0.0/16 define MGMT = 10.0.100.0/24 define MONITOR = 10.0.200.0/24
table inet filter {

Rate limiting set

set rate_limit { type ipv4_addr flags dynamic,timeout timeout 1m }
chain input { type filter hook input priority 0; policy drop;
# Connection tracking
ct state established,related accept
ct state invalid drop

# Loopback
iif "lo" accept

# ICMP and ICMPv6
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

# SSH from management only
tcp dport 22 ip saddr $MGMT accept

# HTTP/HTTPS from anywhere
tcp dport { 80, 443 } accept

# Prometheus metrics from monitoring subnet
tcp dport 9100 ip saddr $MONITOR accept

# Rate limit new connections
tcp flags syn limit rate over 25/second burst 50 packets drop

# Log dropped traffic
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;
# Optional: restrict outbound to known destinations
# tcp dport { 80, 443, 53 } accept
# udp dport { 53, 123 } accept
# ct state established,related accept
# drop
} }
define LAN = 10.0.0.0/16 define MGMT = 10.0.100.0/24 define MONITOR = 10.0.200.0/24
table inet filter {

Rate limiting set

set rate_limit { type ipv4_addr flags dynamic,timeout timeout 1m }
chain input { type filter hook input priority 0; policy drop;
# Connection tracking
ct state established,related accept
ct state invalid drop

# Loopback
iif "lo" accept

# ICMP and ICMPv6
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

# SSH from management only
tcp dport 22 ip saddr $MGMT accept

# HTTP/HTTPS from anywhere
tcp dport { 80, 443 } accept

# Prometheus metrics from monitoring subnet
tcp dport 9100 ip saddr $MONITOR accept

# Rate limit new connections
tcp flags syn limit rate over 25/second burst 50 packets drop

# Log dropped traffic
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;
# Optional: restrict outbound to known destinations
# tcp dport { 80, 443, 53 } accept
# udp dport { 53, 123 } accept
# ct state established,related accept
# drop
} }

NAT table for port forwarding

NAT table for port forwarding

table ip nat { chain prerouting { type nat hook prerouting priority -100; # Forward port 8080 to internal app server tcp dport 8080 dnat to 10.0.1.10:8080 }
chain postrouting { type nat hook postrouting priority 100; oifname "eth0" masquerade } }
undefined
table ip nat { chain prerouting { type nat hook prerouting priority -100; # Forward port 8080 to internal app server tcp dport 8080 dnat to 10.0.1.10:8080 }
chain postrouting { type nat hook postrouting priority 100; oifname "eth0" masquerade } }
undefined

nftables Management Commands

nftables管理命令

bash
undefined
bash
undefined

Load configuration

Load configuration

nft -f /etc/nftables.conf
nft -f /etc/nftables.conf

List all rules

List all rules

nft list ruleset
nft list ruleset

List specific table

List specific table

nft list table inet filter
nft list table inet filter

Add a rule dynamically

Add a rule dynamically

nft add rule inet filter input tcp dport 8443 accept
nft add rule inet filter input tcp dport 8443 accept

Insert rule at position

Insert rule at position

nft insert rule inet filter input position 5 ip saddr 10.0.50.0/24 tcp dport 3306 accept
nft insert rule inet filter input position 5 ip saddr 10.0.50.0/24 tcp dport 3306 accept

Delete a rule by handle

Delete a rule by handle

nft -a list chain inet filter input # show handles nft delete rule inet filter input handle 15
nft -a list chain inet filter input # show handles nft delete rule inet filter input handle 15

Monitor in real time

Monitor in real time

nft monitor
undefined
nft monitor
undefined

AWS Security Groups

AWS安全组

Terraform Configuration

Terraform配置

hcl
undefined
hcl
undefined

Web tier security group

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" } }
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

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"] } }
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

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"] } }
undefined
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"] } }
undefined

AWS CLI Commands

AWS CLI命令

bash
undefined
bash
undefined

Create security group

Create security group

aws ec2 create-security-group
--group-name web-sg
--description "Web server SG"
--vpc-id vpc-0abc123
aws ec2 create-security-group
--group-name web-sg
--description "Web server SG"
--vpc-id vpc-0abc123

Add inbound rule

Add inbound rule

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-0abc123
--protocol tcp --port 443
--cidr 0.0.0.0/0

Add rule referencing another security group

Add rule referencing another security group

aws ec2 authorize-security-group-ingress
--group-id sg-0db456
--protocol tcp --port 5432
--source-group sg-0app789
aws ec2 authorize-security-group-ingress
--group-id sg-0db456
--protocol tcp --port 5432
--source-group sg-0app789

Remove a rule

Remove a rule

aws ec2 revoke-security-group-ingress
--group-id sg-0abc123
--protocol tcp --port 22
--cidr 0.0.0.0/0
aws ec2 revoke-security-group-ingress
--group-id sg-0abc123
--protocol tcp --port 22
--cidr 0.0.0.0/0

Describe rules

Describe rules

aws ec2 describe-security-group-rules
--filters Name=group-id,Values=sg-0abc123
undefined
aws ec2 describe-security-group-rules
--filters Name=group-id,Values=sg-0abc123
undefined

Firewall Rule Audit Script

防火墙规则审计脚本

bash
#!/bin/bash
bash
#!/bin/bash

firewall-audit.sh - Audit current firewall rules for common issues

firewall-audit.sh - Audit current firewall rules for common issues

echo "=== Firewall Audit Report ===" echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "Host: $(hostname)" echo ""
echo "=== Firewall Audit Report ===" echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "Host: $(hostname)" echo ""

Check if firewall is active

Check if firewall is active

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 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 ---"

Check for overly permissive rules

Check for overly permissive rules

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"; then echo "CRITICAL: PostgreSQL (port 5432) open to 0.0.0.0/0" fi
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"; then echo "CRITICAL: PostgreSQL (port 5432) open to 0.0.0.0/0" fi

Check default policies

Check default policies

DEFAULT_INPUT=$(iptables -L INPUT 2>/dev/null | head -1 | grep -oP 'policy \K\w+') if [ "$DEFAULT_INPUT" = "ACCEPT" ]; then echo "CRITICAL: Default INPUT policy is ACCEPT - should be DROP" fi
undefined
DEFAULT_INPUT=$(iptables -L INPUT 2>/dev/null | head -1 | grep -oP 'policy \K\w+') if [ "$DEFAULT_INPUT" = "ACCEPT" ]; then echo "CRITICAL: Default INPUT policy is ACCEPT - should be DROP" fi
undefined

Troubleshooting

故障排查

ProblemCauseSolution
Locked out of SSHRule order or default deny applied before allowUse out-of-band console access; add SSH allow rule first
Rules lost after rebootRules not persistedInstall
iptables-persistent
or save to
/etc/nftables.conf
Docker bypasses iptablesDocker modifies iptables FORWARD chainUse
DOCKER-USER
chain for custom rules; set
"iptables": false
in daemon.json
nftables and iptables conflictBoth running simultaneouslyMigrate fully to nftables; remove iptables packages
AWS SG rule limit reachedMax 60 inbound rules per SGUse prefix lists or consolidate CIDR ranges
Legitimate traffic blockedRule ordering issuePlace more specific allow rules before general deny rules
问题原因解决方案
无法通过SSH登录规则顺序错误或在允许规则之前应用了默认拒绝策略使用带外控制台访问;优先添加SSH允许规则
重启后规则丢失规则未持久化安装
iptables-persistent
或保存规则至
/etc/nftables.conf
Docker绕过iptablesDocker修改了iptables的FORWARD链使用
DOCKER-USER
链添加自定义规则;在daemon.json中设置
"iptables": false
nftables与iptables冲突两者同时运行完全迁移至nftables;卸载iptables相关包
AWS安全组规则数量达到上限每个安全组最多60条入站规则使用前缀列表或合并CIDR范围
合法流量被阻断规则顺序问题将更具体的允许规则放在通用拒绝规则之前

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
  • 所有链采用默认拒绝策略
  • 最小化规则集——仅开放必要端口
  • 定期审计规则(至少每月一次)
  • 记录被阻断的流量以用于安全监控
  • 为所有规则添加描述及工单引用
  • 使用连接跟踪实现状态检测
  • 对入站连接进行速率限制以防止DDoS攻击
  • 将管理流量与应用流量分离
  • 在生产环境之前先在预发布环境测试规则变更
  • 保留工作规则集的持久化备份

Related Skills

相关技能

  • linux-hardening - System security
  • aws-vpc - AWS networking
  • zero-trust - Identity-based access patterns
  • vpn-setup - Secure tunnel configuration
  • linux-hardening - 系统安全
  • aws-vpc - AWS网络配置
  • zero-trust - 基于身份的访问模式
  • vpn-setup - 安全隧道配置