防火墙是一种网络安全设备或软件,用于监控和控制网络流量,基于预定的安全规则允许或阻止数据包的传输。
应用层
↓
Netfilter框架
↓
内核空间 (iptables规则)
↓
网络接口
# 查看所有表
iptables -t filter -L # 过滤表(默认)
iptables -t nat -L # NAT表
iptables -t mangle -L # 修改表
iptables -t raw -L # 原始表
iptables [-t table] -command chain [rule-number] match-criteria -j target
# 查看规则
iptables -L # 查看filter表所有链
iptables -L INPUT # 查看INPUT链
iptables -L -n # 不解析域名,显示IP
iptables -L -v # 显示详细信息
iptables -L --line-numbers # 显示行号
# 添加规则
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 追加规则
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT # 插入规则到第1行
# 删除规则
iptables -D INPUT 1 # 删除第1条规则
iptables -D INPUT -p tcp --dport 22 -j ACCEPT # 删除特定规则
# 修改规则
iptables -R INPUT 1 -p tcp --dport 8080 -j ACCEPT # 替换第1条规则
# 清空规则
iptables -F # 清空所有链
iptables -F INPUT # 清空INPUT链
iptables -X # 删除用户自定义链
iptables -Z # 清零计数器
#!/bin/bash
# iptables基础配置脚本
echo "配置iptables防火墙..."
# 清空现有规则
iptables -F
iptables -X
iptables -Z
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许SSH访问(端口22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许HTTP和HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允许DNS查询
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# 允许ICMP(ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 记录被拒绝的连接
iptables -A INPUT -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables_INPUT_denied: "
echo "iptables配置完成"
#!/bin/bash
# iptables高级配置
# 防止DDoS攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 防止SYN洪水攻击
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
# 防止端口扫描
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A INPUT -m recent --name portscan --remove
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
# 基于时间的规则
iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# 基于MAC地址的规则
iptables -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT
# 基于地理位置的规则(需要geoip模块)
iptables -A INPUT -m geoip --src-cc CN -j ACCEPT
# 限制每个IP的连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT
# 端口敲门(Port Knocking)
iptables -A INPUT -m recent --name knock1 --rcheck --seconds 60 -j DROP
iptables -A INPUT -p tcp --dport 1234 -m recent --name knock1 --set -j DROP
iptables -A INPUT -m recent --name knock1 --rcheck --seconds 10 -p tcp --dport 22 -j ACCEPT
#!/bin/bash
# NAT配置示例
# 启用IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# SNAT(源地址转换)- 用于内网访问外网
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 公网IP
# DNAT(目标地址转换)- 用于外网访问内网服务
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
# MASQUERADE(动态SNAT)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# 端口转发
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80
# 安装iptables-services
yum install iptables-services
# 保存当前规则
service iptables save
# 或者手动保存
iptables-save > /etc/sysconfig/iptables
# 启动服务
systemctl enable iptables
systemctl start iptables
# 安装iptables-persistent
apt-get install iptables-persistent
# 保存规则
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# 或使用netfilter-persistent
netfilter-persistent save
firewalld使用区域的概念来管理网络流量:
# 查看所有区域
firewall-cmd --get-zones
# 查看默认区域
firewall-cmd --get-default-zone
# 查看活动区域
firewall-cmd --get-active-zones
# 设置默认区域
firewall-cmd --set-default-zone=public
# 服务状态管理
systemctl start firewalld
systemctl stop firewalld
systemctl restart firewalld
systemctl enable firewalld
systemctl disable firewalld
systemctl status firewalld
# 查看firewalld状态
firewall-cmd --state
# 重新加载配置
firewall-cmd --reload
# 完全重启firewalld
firewall-cmd --complete-reload
# 查看可用服务
firewall-cmd --get-services
# 查看当前区域允许的服务
firewall-cmd --list-services
# 添加服务(临时)
firewall-cmd --add-service=http
# 添加服务(永久)
firewall-cmd --permanent --add-service=http
# 移除服务
firewall-cmd --remove-service=http
firewall-cmd --permanent --remove-service=http
# 查看特定区域的服务
firewall-cmd --zone=public --list-services
# 开放端口(临时)
firewall-cmd --add-port=8080/tcp
# 开放端口(永久)
firewall-cmd --permanent --add-port=8080/tcp
# 开放端口范围
firewall-cmd --permanent --add-port=8000-9000/tcp
# 查看开放的端口
firewall-cmd --list-ports
# 移除端口
firewall-cmd --remove-port=8080/tcp
firewall-cmd --permanent --remove-port=8080/tcp
# 允许特定IP访问特定端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'
# 拒绝特定IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.200" reject'
# 允许特定网段访问HTTP服务
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept'
# 记录特定连接
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" log prefix="SSH Access: " level="info" accept'
# 限制连接数
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="http" accept limit value="10/m"'
# 查看富规则
firewall-cmd --list-rich-rules
# 启用IP转发
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
# 配置端口转发
firewall-cmd --permanent --zone=external --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.100
# 配置MASQUERADE
firewall-cmd --permanent --zone=external --add-masquerade
# 查看转发规则
firewall-cmd --list-forward-ports
# 创建自定义服务配置文件
cat > /etc/firewalld/services/myapp.xml << EOF
MyApp
My Custom Application
EOF
# 重新加载firewalld
firewall-cmd --reload
# 添加自定义服务
firewall-cmd --permanent --add-service=myapp
# 查看接口绑定
firewall-cmd --get-zone-of-interface=eth0
# 将接口绑定到区域
firewall-cmd --zone=dmz --change-interface=eth1
# 永久绑定
firewall-cmd --permanent --zone=dmz --change-interface=eth1
特性 | iptables | firewalld |
---|---|---|
配置方式 | 命令行规则 | 区域化管理 |
规则持久化 | 需要额外配置 | 自动持久化 |
动态更新 | 需要重载所有规则 | 支持动态更新 |
学习难度 | 较高 | 相对简单 |
灵活性 | 非常灵活 | 相对有限 |
图形界面 | 第三方工具 | firewall-config |
D-Bus支持 | 无 | 支持 |
网络管理器集成 | 无 | 支持 |
使用iptables的场景:
使用firewalld的场景:
#!/bin/bash
# Web服务器iptables配置
# 清空规则
iptables -F
iptables -X
iptables -Z
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 基础规则
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Web服务端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# SSH管理端口(限制IP)
iptables -A INPUT -s 管理员IP -p tcp --dport 22 -j ACCEPT
# 防止DDoS
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 保存规则
iptables-save > /etc/sysconfig/iptables
#!/bin/bash
# Web服务器firewalld配置
# 设置默认区域
firewall-cmd --set-default-zone=public
# 开放Web服务
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 限制SSH访问
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="管理员IP" service name="ssh" accept'
# 防护规则
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="http" accept limit value="25/m"'
# 应用配置
firewall-cmd --reload
#!/bin/bash
# 内网服务器firewalld配置
# 创建内网区域
firewall-cmd --permanent --new-zone=internal-net
firewall-cmd --permanent --zone=internal-net --set-description="Internal Network Zone"
# 配置内网区域
firewall-cmd --permanent --zone=internal-net --add-source=192.168.1.0/24
firewall-cmd --permanent --zone=internal-net --add-service=ssh
firewall-cmd --permanent --zone=internal-net --add-service=http
firewall-cmd --permanent --zone=internal-net --add-service=mysql
# 配置数据库访问
firewall-cmd --permanent --zone=internal-net --add-port=3306/tcp
# 只允许特定服务器访问数据库
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port protocol="tcp" port="3306" accept'
# 应用配置
firewall-cmd --reload
#!/bin/bash
# 负载均衡器防火墙配置
# 启用IP转发
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
# 配置MASQUERADE
firewall-cmd --permanent --zone=external --add-masquerade
# 配置端口转发到后端服务器
firewall-cmd --permanent --zone=external --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10
firewall-cmd --permanent --zone=external --add-forward-port=port=443:proto=tcp:toaddr=192.168.1.10
# 配置健康检查端口
firewall-cmd --permanent --add-port=8080/tcp
# 限制管理访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="管理网段" service name="ssh" accept'
# 应用配置
firewall-cmd --reload
# 检查服务状态
systemctl status firewalld
firewall-cmd --state
# 检查规则
firewall-cmd --list-all
iptables -L -n
# 检查端口监听
netstat -tlnp | grep :80
ss -tlnp | grep :80
# 测试连接
telnet 目标IP 端口
nmap -p 端口 目标IP
# firewalld重新加载
firewall-cmd --reload
# iptables重启服务
systemctl restart iptables
# 检查规则优先级
iptables -L -n --line-numbers
# 查看连接统计
iptables -L -v -n
firewall-cmd --get-log-denied
# 优化规则顺序
# 将常用规则放在前面
# 使用更具体的匹配条件
# 查看firewalld日志
journalctl -u firewalld -f
# 查看iptables日志
tail -f /var/log/messages | grep iptables
# 启用详细日志
firewall-cmd --set-log-denied=all
# 使用tcpdump抓包
tcpdump -i eth0 -n host 目标IP
# 使用wireshark(图形界面)
wireshark
# 默认拒绝所有,只开放必要的服务
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP # 严格模式
# firewalld类似配置
firewall-cmd --set-default-zone=drop
# 网络层防护
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# 应用层防护
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="http" accept limit value="10/s"'
#!/bin/bash
# 防火墙监控脚本
LOG_FILE="/var/log/firewall_monitor.log"
ALERT_EMAIL="[email protected]"
# 检查异常连接
check_connections() {
# 检查连接数
conn_count=$(netstat -an | grep ESTABLISHED | wc -l)
if [ $conn_count -gt 1000 ]; then
echo "$(date): 连接数异常: $conn_count" >> $LOG_FILE
# 发送告警邮件
echo "连接数异常: $conn_count" | mail -s "防火墙告警" $ALERT_EMAIL
fi
}
# 检查失败的连接尝试
check_failed_attempts() {
failed_ssh=$(grep "Failed password" /var/log/secure | grep $(date +%b\ %d) | wc -l)
if [ $failed_ssh -gt 10 ]; then
echo "$(date): SSH登录失败次数过多: $failed_ssh" >> $LOG_FILE
fi
}
# 运行检查
check_connections
check_failed_attempts
#!/bin/bash
# 自动封禁恶意IP
# 分析日志,找出攻击IP
grep "Failed password" /var/log/secure | \
awk '{print $11}' | sort | uniq -c | \
awk '$1 > 5 {print $2}' | \
while read ip; do
# 检查IP是否已被封禁
if ! iptables -L INPUT -n | grep -q $ip; then
echo "封禁恶意IP: $ip"
iptables -I INPUT -s $ip -j DROP
# 或使用firewalld
# firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='$ip' reject"
fi
done
#!/bin/bash
# iptables备份脚本
BACKUP_DIR="/etc/iptables/backup"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 备份当前规则
iptables-save > $BACKUP_DIR/iptables_$DATE.rules
# 保留最近30天的备份
find $BACKUP_DIR -name "iptables_*.rules" -mtime +30 -delete
echo "iptables备份完成: $BACKUP_DIR/iptables_$DATE.rules"
#!/bin/bash
# firewalld备份脚本
BACKUP_DIR="/etc/firewalld/backup"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 备份配置文件
tar -czf $BACKUP_DIR/firewalld_$DATE.tar.gz /etc/firewalld/
# 导出当前配置
firewall-cmd --list-all-zones > $BACKUP_DIR/zones_$DATE.txt
firewall-cmd --list-rich-rules > $BACKUP_DIR/rich_rules_$DATE.txt
echo "firewalld备份完成: $BACKUP_DIR/"
通过本指南的学习和实践,您应该能够熟练掌握Linux防火墙的配置和管理,为系统安全提供有力保障。记住,防火墙只是安全防护的一部分,还需要结合其他安全措施构建完整的安全体系。