防火墙是IDC服务器安全的第一道防线,但很多运维同学对它要么一知半解、要么只会复制粘贴几条命令。本文把 iptables 和 firewalld 两代防火墙工具讲透,并给出生产环境可直接套用的配置模板。## 一、先搞清楚数据包是怎么走的理解防火墙之前,必须先理解数据包在内核里的流转路径(Netfilter钩子):- PREROUTING:数据包刚进来,还没做路由决策- INPUT:发给本机的包- FORWARD:经过本机转发的包(路由/NAT场景)- OUTPUT:本机发出的包- POSTROUTING:出去之前iptables 的4张表挂在不同的链上:- filter表:过滤,核心是 INPUT/OUTPUT/FORWARD 三条链- nat表:地址转换,PREROUTING(DNAT)和 POSTROUTING(SNAT)- mangle表:修改包特征(TOS、TTL等)- raw表:连接跟踪的例外处理记住一个口诀:日常封禁用filter表,端口映射用nat表,其余两张表生产环境基本用不到。## 二、iptables 核心用法1. 基础命令结构bashiptables -t 表名 -A/-I/-D 链名 匹配条件 -j 动作2. 常用动作- ACCEPT:放行- DROP:丢弃(不回应,扫描器会超时,比REJECT更「隐身」)- REJECT:拒绝(立刻返回错误,调试时好用)- SNAT/DNAT:源/目标地址转换3. 生产常用规则bash# 查看规则(带行号)iptables -L -n --line-numbers# 默认策略:INPUT拒绝、OUTPUT放行iptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT ACCEPT# 放行回环和已建立的连接(这行必须放最前面)iptables -A INPUT -i lo -j ACCEPTiptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT# 放行常用端口iptables -A INPUT -p tcp --dport 22 -j ACCEPTiptables -A INPUT -p tcp --dport 80 -j ACCEPTiptables -A INPUT -p tcp --dport 443 -j ACCEPT# 限制SSH来源IPiptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT# 防SYN Flood(生产慎用,先压测)iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT4. 端口映射(DNAT)把公网IP的8080映射到内网10.0.0.5的80:bashiptables -t nat -A PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80iptables -t nat -A POSTROUTING -d 10.0.0.5 -p tcp --dport 80 -j SNAT --to-source 公网IP同时要开启内核转发:bashecho 'net.ipv4.ip_forward = 1' >> /etc/sysctl.confsysctl -p5. 规则持久化iptables规则重启即失,必须保存:bash# CentOS 7+yum install -y iptables-servicesservice iptables save # 保存到 /etc/sysconfig/iptablessystemctl enable iptables## 三、firewalld:新一代管理工具CentOS 7+ 默认用 firewalld,它底层还是iptables/nftables,只是换了个更易用的管理方式——区域(zone)。1. 基本操作bashsystemctl status firewalld # 查看状态firewall-cmd --statefirewall-cmd --list-all # 查看当前区域规则firewall-cmd --reload # 重载配置(临时规则会丢)firewall-cmd --permanent --reload # 重载永久配置2. 开放/关闭端口bashfirewall-cmd --add-port=8080/tcp # 临时放行firewall-cmd --permanent --add-port=8080/tcp # 永久放行firewall-cmd --permanent --remove-port=8080/tcp3. 服务方式放行bashfirewall-cmd --permanent --add-service=httpfirewall-cmd --permanent --add-service=https4. 限制来源IPbash# 只允许公司IP访问SSHfirewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="1.2.3.4/32" port port="22" protocol="tcp" accept'# 封禁恶意IPfirewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="5.6.7.8/32" reject'5. 端口转发bashfirewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=10.0.0.5## 四、生产环境避坑指南坑1:改防火墙把自己锁外面- 云服务器上改防火墙前,先确认安全组/控制台VNC可用- 加SSH规则永远比删SSH规则谨慎,改完先 ssh 新开一个连接验证- 不要同时执行「清空规则+改默认策略」,分步执行、逐步验证坑2:firewalld和iptables混用冲突同时启用了 firewalld 又手动起 iptables 服务,规则会互相覆盖、行为难以预测。生产环境二选一,推荐用 firewalld 管理,别手动去改 iptables 文件。坑3:Docker和iptables相爱相杀Docker 会自动往 iptables 的 DOCKER 链写规则。如果你手动 iptables -F 清空规则,Docker 的端口映射会全部失效。操作前先 iptables -L -n | grep DOCKER 确认。坑4:顺序就是生命iptables 规则从上到下匹配,匹配即停止。所以「放行已建立连接」和「回环放行」必须放在最前面,-A 追加和 -I 插入位置不同,效果天差地别。坑5:nf_conntrack 表爆满高并发服务器上连接跟踪表可能被打满,表现为新连接全部超时。排查:bashsysctl net.netfilter.nf_conntrack_countsysctl net.netfilter.nf_conntrack_max适当调大 nf_conntrack_max,并缩短 nf_conntrack_tcp_timeout_established。## 五、一套可复用的生产模板CentOS 7/8 通用,按需删减:bash#!/bin/bash# 初始化:清空规则iptables -F; iptables -X; iptables -t nat -F# 默认策略iptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT ACCEPT# 基础放行iptables -A INPUT -i lo -j ACCEPTiptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT# 业务端口iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT# 公司管理网段iptables -A INPUT -p tcp --dport 22 -s 10.10.0.0/16 -j ACCEPT# 日志记录被丢弃的包(排障利器)iptables -A INPUT -j LOG --log-prefix "IPT-DROP: " --log-level 4service iptables saveecho "防火墙规则已应用并保存"防火墙配置做完一定要写进运维文档,并定期(建议每次变更后)做一次连通性巡检:公网端口可达性、管理端口从办公网可达性、业务流量是否正常。安全是动态的,规则也要跟着业务走。
评论