关于 firewall-config
面向服务器管理员的防火墙配置技能,涵盖 Linux 主机规则和 AWS 安全组。提供规则配置、审计与故障排查示例,涉及 iptables、UFW 和 nftables。
主要功能
- 01配置 iptables、UFW 与 nftables
- 02设置默认拒绝及访问规则
- 03配置 AWS 安全组
- 04审计规则并排查问题
适用场景
- 01限制新服务器的网络访问
- 02划分应用层之间的网络
- 03迁移 iptables 规则至 nftables
- 04审查规则或紧急阻断流量
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill firewall-config安装后在 Claude Code 中输入/firewall-config确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/iptables-rules.shreferences/iptables-guide.mdscripts/firewall-audit.shsetup-ufw.sh详细介绍
防火墙配置
配置基于主机和云的防火墙,保障网络安全。
何时使用此技能
在以下情况使用此技能:
- 设置新服务器,需要限制网络访问
- 在应用层之间实施网络分段
- 为 AWS、GCP 或 Azure 资源配置云安全组
- 从 iptables 迁移到 nftables
- 审核现有防火墙规则是否符合规范
- 应对需要紧急阻断网络流量的安全事件
前提条件
- 拥有 Linux 主机的 root 或 sudo 权限
- 已配置用于云安全组管理的 AWS CLI
- 了解 TCP/IP、端口和协议
- 拥有所需流量流向的网络图
iptables
使用默认拒绝策略进行基本设置
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F
# Default policies - deny all inbound, allow outbound
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Drop invalid packets
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# Allow SSH (restrict to management subnet)
iptables -A INPUT -p tcp --dport 22 -s 10.0.100.0/24 -j ACCEPT
# Allow HTTP/HTTPS from anywhere
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 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
# 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
# Save rules (Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
抗 DDoS 规则
# 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
# Limit new connections per source IP
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
# 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
应用专用规则
# Web server with database backend
# Allow app servers to reach database (port 5432)
iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT
# Allow monitoring (Prometheus node exporter)
iptables -A INPUT -p tcp --dport 9100 -s 10.0.200.0/24 -j ACCEPT
# DNS resolution
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT
# NTP
iptables -A INPUT -p udp --sport 123 -j ACCEPT
# Block specific IP (incident response)
iptables -I INPUT 1 -s 203.0.113.50 -j DROP
UFW(简单防火墙)
# Enable UFW with default deny
ufw default deny incoming
ufw default allow outgoing
ufw enable
# Allow SSH from management network
ufw allow from 10.0.100.0/24 to any port 22 proto tcp
# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp
# Allow specific application profile
ufw allow 'Nginx Full'
# Rate limit SSH (max 6 connections in 30 seconds)
ufw limit ssh
# Allow port range
ufw allow 8000:8080/tcp
# Deny specific IP
ufw deny from 203.0.113.50
# Check status
ufw status verbose
ufw status numbered
# Delete a rule by number
ufw delete 3
# Application profiles
ufw app list
ufw app info 'Nginx Full'
nftables
完整的服务器配置
#!/usr/sbin/nft -f
flush ruleset
# 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
}
}
# 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
}
}
nftables 管理命令
# Load configuration
nft -f /etc/nftables.conf
# List all rules
nft list ruleset
# List specific table
nft list table inet filter
# Add a rule dynamically
nft add rule inet filter input tcp dport 8443 accept
# Insert rule at position
nft insert rule inet filter input position 5 ip saddr 10.0.50.0/24 tcp dport 3306 accept
# Delete a rule by handle
nft -a list chain inet filter input # show handles
nft delete rule inet filter input handle 15
# Monitor in real time
nft monitor
AWS 安全组
Terraform 配置
# 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 命令
# Create security group
aws ec2 create-security-group \
--group-name web-sg \
--description "Web server SG" \
--vpc-id vpc-0abc123
# Add inbound rule
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
aws ec2 authorize-security-group-ingress \
--group-id sg-0db456 \
--protocol tcp --port 5432 \
--source-group sg-0app789
# Remove a rule
aws ec2 revoke-security-group-ingress \
--group-id sg-0abc123 \
--protocol tcp --port 22 \
--cidr 0.0.0.0/0
# Describe rules
aws ec2 describe-security-group-rules \
--filters Name=group-id,Values=sg-0abc123
防火墙规则审核脚本
#!/bin/bash
# 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 ""
# 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 ---"
# 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
# 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
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 无法通过 SSH 登录 | 规则顺序不当,或在允许规则之前应用了默认拒绝策略 | 使用带外控制台访问;先添加 SSH 允许规则 |
| 重启后规则丢失 | 规则未持久化 | 安装 iptables-persistent,或保存到 /etc/nftables.conf |
| Docker 绕过 iptables | Docker 修改了 iptables FORWARD 链 | 使用 DOCKER-USER 链设置自定义规则;在 daemon.json 中设置 "iptables": false |
| nftables 与 iptables 冲突 | 两者同时运行 | 完整迁移到 nftables;移除 iptables 软件包 |
| AWS SG 规则数量达到上限 | 每个 SG 最多允许 60 条入站规则 | 使用前缀列表或合并 CIDR 范围 |
| 合法流量被阻止 | 规则顺序不当 | 将更具体的允许规则置于一般拒绝规则之前 |
最佳实践
- 所有链都采用默认拒绝策略
- 尽量精简规则集,只开放必需的流量
- 定期审核规则(至少每月一次)
- 记录被拒绝的流量,以便进行安全监控
- 为所有规则添加说明和工单引用
- 使用连接跟踪进行有状态检查
- 限制入站连接速率,防止 DDoS
- 将管理流量与应用流量分开
- 在预发布环境中测试规则变更,再部署到生产环境
- 持久保存可用规则集的备份
相关技能
- linux-hardening - 系统安全
- aws-vpc - AWS 网络
- zero-trust - 基于身份的访问模式
- vpn-setup - 安全隧道配置
评论
支持 Markdown