Linux防火墙管理实战指南:iptables与firewalld配置详解
·
目录
防火墙概述
什么是防火墙
防火墙是一种网络安全设备或软件,用于监控和控制网络流量,基于预定的安全规则允许或阻止数据包的传输。
Linux防火墙架构
应用层
↓
Netfilter框架
↓
内核空间 (iptables规则)
↓
网络接口
主要组件
- Netfilter:Linux内核中的网络过滤框架
- iptables:传统的防火墙管理工具
- firewalld:现代化的防火墙管理服务
iptables详解
1. iptables基础概念
表(Tables)
# 查看所有表
iptables -t filter -L # 过滤表(默认)
iptables -t nat -L # NAT表
iptables -t mangle -L # 修改表
iptables -t raw -L # 原始表
链(Chains)
- INPUT:处理进入本机的数据包
- OUTPUT:处理从本机发出的数据包
- FORWARD:处理经过本机转发的数据包
- PREROUTING:数据包进入路由表之前
- POSTROUTING:数据包离开路由表之后
动作(Targets)
- ACCEPT:允许数据包通过
- DROP:丢弃数据包
- REJECT:拒绝数据包并发送错误信息
- LOG:记录日志
- REDIRECT:重定向
2. iptables命令语法
基本语法
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 # 清零计数器
3. iptables实战配置
基础防火墙配置
#!/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
NAT配置
#!/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
4. iptables持久化
CentOS/RHEL系统
# 安装iptables-services
yum install iptables-services
# 保存当前规则
service iptables save
# 或者手动保存
iptables-save > /etc/sysconfig/iptables
# 启动服务
systemctl enable iptables
systemctl start iptables
Ubuntu/Debian系统
# 安装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详解
1. firewalld基础概念
区域(Zones)
firewalld使用区域的概念来管理网络流量:
# 查看所有区域
firewall-cmd --get-zones
# 查看默认区域
firewall-cmd --get-default-zone
# 查看活动区域
firewall-cmd --get-active-zones
# 设置默认区域
firewall-cmd --set-default-zone=public
预定义区域
- drop:丢弃所有传入连接
- block:拒绝所有传入连接
- public:公共区域,不信任网络中的其他计算机
- external:外部区域,用于路由器等设备
- dmz:非军事化区域,允许有限的服务
- work:工作区域,信任网络中的大部分计算机
- home:家庭区域,信任网络中的大部分计算机
- internal:内部区域,信任网络中的所有计算机
- trusted:信任区域,信任网络中的所有计算机
2. firewalld服务管理
# 服务状态管理
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
3. firewalld基本操作
服务管理
# 查看可用服务
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
富规则(Rich Rules)
# 允许特定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
4. firewalld高级配置
端口转发
# 启用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
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>My Custom Application</description>
<port protocol="tcp" port="8080"/>
<port protocol="udp" port="8081"/>
</service>
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的场景:
- 现代化的系统管理
- 需要动态配置
- 桌面环境或服务器环境
- 与NetworkManager集成
实战案例
案例1:Web服务器防火墙配置
iptables方案
#!/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
firewalld方案
#!/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
案例2:内网服务器防火墙配置
#!/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
案例3:负载均衡器配置
#!/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
故障排除
常见问题和解决方案
1. 无法连接服务
# 检查服务状态
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
2. 规则不生效
# firewalld重新加载
firewall-cmd --reload
# iptables重启服务
systemctl restart iptables
# 检查规则优先级
iptables -L -n --line-numbers
3. 性能问题
# 查看连接统计
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
安全最佳实践
1. 防火墙配置原则
最小权限原则
# 默认拒绝所有,只开放必要的服务
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"'
2. 监控和告警
创建监控脚本
#!/bin/bash
# 防火墙监控脚本
LOG_FILE="/var/log/firewall_monitor.log"
ALERT_EMAIL="admin@example.com"
# 检查异常连接
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
3. 备份和恢复
iptables备份
#!/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"
firewalld备份
#!/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/"
总结
关键要点
- 理解原理:掌握Netfilter框架和防火墙工作原理
- 选择工具:根据需求选择iptables或firewalld
- 安全第一:遵循最小权限原则,定期审查规则
- 监控告警:建立完善的监控和告警机制
- 备份恢复:定期备份配置,准备应急恢复方案
学习路径
- 基础学习:理解防火墙基本概念和Linux网络架构
- 工具掌握:熟练使用iptables和firewalld命令
- 实战演练:在测试环境中进行各种配置实验
- 生产应用:在生产环境中谨慎应用防火墙规则
- 持续优化:根据实际需求不断优化和调整规则
进阶方向
- 网络安全:深入学习网络安全理论和实践
- 自动化运维:结合Ansible、Puppet等工具自动化管理
- 容器网络:学习Docker、Kubernetes网络安全
- 云平台安全:掌握云平台防火墙和安全组配置
通过本指南的学习和实践,您应该能够熟练掌握Linux防火墙的配置和管理,为系统安全提供有力保障。记住,防火墙只是安全防护的一部分,还需要结合其他安全措施构建完整的安全体系。
更多推荐
所有评论(0)