1. 轻量服务器防火墙基础认知
在CentOS 7.9系统中,firewalld作为动态防火墙管理器取代了传统的iptables。与iptables直接操作规则链不同,firewalld引入了"zone"和"service"的概念,使得规则管理更加灵活。每个zone预定义了不同的信任级别,比如public zone默认禁止所有传入连接,只允许指定的服务。
轻量服务器通常资源有限,因此需要特别注意:
- 避免加载不必要的模块(如ipset)
- 规则集应当尽量简洁
- 长期不用的服务端口应及时关闭
- 日志记录级别要适中,避免磁盘空间快速耗尽
重要提示:操作防火墙前务必确保已配置SSH白名单或拥有控制台直接访问权限,否则可能导致服务器失联。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 初始环境检查与准备
2.1 系统状态确认
首先检查防火墙运行状态:
bash复制systemctl status firewalld
正常运行的输出应包含"active (running)"。如果未运行,使用以下命令启用并启动:
bash复制systemctl enable --now firewalld
2.2 默认zone确认
查看当前生效的zone:
bash复制firewall-cmd --get-default-zone
轻量服务器通常使用public zone,但建议根据实际需求调整:
bash复制firewall-cmd --set-default-zone=public
2.3 基础规则备份
在进行任何修改前,建议导出当前规则:
bash复制firewall-cmd --list-all > ~/firewall_backup_$(date +%Y%m%d).txt
3. HTTP/HTTPS服务放行配置
3.1 通过预定义服务添加
CentOS的firewalld已内置http和https服务定义:
bash复制firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
这些服务默认对应80和443端口。要验证是否生效:
bash复制firewall-cmd --list-services | grep -E 'http|https'
3.2 自定义端口配置
如果使用非标准端口(如8080):
bash复制firewall-cmd --permanent --add-port=8080/tcp
对于需要批量添加的端口范围:
bash复制firewall-cmd --permanent --add-port=8000-8010/tcp
3.3 源IP限制(可选)
为增强安全性,可限制访问来源IP:
bash复制firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="http" accept'
4. 规则持久化与验证
4.1 配置重载
所有带--permanent参数的修改需要重载才能生效:
bash复制firewall-cmd --reload
4.2 规则验证
检查最终生效的规则:
bash复制firewall-cmd --list-all
完整输出应包含类似内容:
code复制public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client http https
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
4.3 连通性测试
从外部机器测试端口开放情况:
bash复制telnet your_server_ip 80
# 或使用更现代的替代方案
nc -zv your_server_ip 443
5. 高级配置与优化
5.1 服务超时设置
为防止资源耗尽,可设置富规则超时:
bash复制firewall-cmd --add-rich-rule='rule service name="http" accept' --timeout=300
5.2 日志配置
启用防火墙日志(默认记录到/var/log/messages):
bash复制firewall-cmd --set-log-denied=all
日志级别可选:all、unicast、broadcast、multicast、off
5.3 性能优化
对于高并发场景,可调整内核参数:
bash复制echo 'net.netfilter.nf_conntrack_max = 524288' >> /etc/sysctl.conf
sysctl -p
6. 常见问题排查
6.1 端口开放但无法访问
检查可能的原因:
- SELinux是否阻止:
bash复制getsebool -a | grep httpd
- 应用是否监听正确接口:
bash复制ss -tulnp | grep ':80'
6.2 规则不生效
诊断步骤:
- 检查运行时与永久规则差异:
bash复制diff <(firewall-cmd --list-all) <(firewall-cmd --list-all --permanent)
- 查看防火墙日志:
bash复制journalctl -u firewalld --since "1 hour ago"
6.3 连接被意外拒绝
可能原因及解决方案:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 间歇性连接失败 | 连接追踪表满 | 增大nf_conntrack_max |
| 只有部分IP能访问 | 存在冲突的rich rule | 检查所有富规则 |
| HTTPS能通但HTTP不行 | 端口重定向问题 | 检查web服务器配置 |
7. 安全加固建议
- 定期审计开放端口:
bash复制firewall-cmd --list-ports | awk '{print "Port:",$0}'
- 启用速率限制防止CC攻击:
bash复制firewall-cmd --add-rich-rule='rule protocol value="tcp" port port="80" limit value="25/m" accept'
- 结合fail2ban增强防护:
bash复制yum install -y fail2ban
systemctl enable --now fail2ban
- 对于暴露在公网的服务,建议:
- 使用非标准端口
- 强制HTTPS连接
- 启用HTTP/2协议
- 配置严格的CSP策略
8. 维护与管理技巧
- 规则版本控制:
bash复制# 每次重大修改前
firewall-cmd --runtime-to-permanent
cp /etc/firewalld/zones/public.xml ~/public_$(date +%s).xml
- 批量操作示例:
bash复制for port in {8000..8010}; do
firewall-cmd --permanent --add-port=${port}/tcp
done
- 临时开放端口(调试用):
bash复制firewall-cmd --add-port=8080/tcp --timeout=60
- 快速关闭所有外部访问(应急):
bash复制firewall-cmd --panic-on
# 恢复
firewall-cmd --panic-off
在实际运维中,我发现很多连接问题其实源于对firewalld的zone概念理解不透彻。比如当网卡被分配到错误的zone,或者服务被添加到非活跃zone时,规则看似存在但实际上不生效。建议每次修改后都使用firewall-cmd --get-active-zones确认各接口的zone分配情况。
