
核心要点(TL;DR)
- 只放行必要端口,默认拒绝所有入站流量。
- iptables规则顺序很重要,允许规则需在拒绝规则之前。
- firewalld使用zone管理规则,public zone默认拒绝。
- 修改规则前先备份,避免锁死SSH连接。
痛点:端口开放过多,服务器成了“筛子”
很多运维人员为了省事,直接关闭防火墙或放行所有端口,导致服务器暴露在扫描和攻击之下。实际上,遵循最小权限原则,只开放必要的端口,能大幅降低风险。本文将以iptables和firewalld为例,手把手教你实现端口最小化放行,并提供可落地的检查清单。
一、识别必要端口:从服务清单开始
在配置防火墙之前,先明确服务器上运行了哪些服务,以及它们监听的端口。使用以下命令查看当前监听端口:
ss -tulnp或
netstat -tulnp输出中会显示所有处于LISTEN状态的端口及对应进程。根据业务需求,标记出必须对外开放的端口,例如:
- Web服务:80(HTTP)、443(HTTPS)
- SSH管理:22(建议修改为非常用端口)
- 数据库:3306(仅限内网访问,不应对外)
- 其他应用端口:如8080、9000等,按需开放
对于不需要对外提供服务的端口,一律不开放。内网通信可通过安全组或私有网络隔离。
二、iptables最小化放行策略与实操
2.1 清空现有规则并设置默认策略
首先备份当前规则:
iptables-save > /root/iptables-backup-$(date +%F).rules然后清空规则并设置默认拒绝:
iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT注意:在远程SSH连接下操作时,务必先放行SSH端口再设置默认拒绝,否则会断连。建议在本地控制台操作或使用定时恢复。
2.2 放行必要端口
允许已建立的连接和本地回环:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT放行SSH端口(假设为22):
iptables -A INPUT -p tcp --dport 22 -j ACCEPT放行Web端口:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT如需限制源IP,可加-s参数,例如只允许192.168.1.0/24访问3306:
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3306 -j ACCEPT2.3 保存规则并持久化
不同发行版保存方式不同:
- CentOS/RHEL:
service iptables save或iptables-save > /etc/sysconfig/iptables - Debian/Ubuntu:
apt install iptables-persistent然后netfilter-persistent save
三、firewalld最小化放行策略与实操
3.1 理解zone与默认策略
firewalld通过zone管理规则,默认public zone拒绝所有入站流量。查看当前活动zone:
firewall-cmd --get-active-zones查看public zone的规则:
firewall-cmd --zone=public --list-all3.2 放行必要端口
永久放行SSH和HTTP/HTTPS:
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https或直接指定端口:
firewall-cmd --permanent --zone=public --add-port=8080/tcp重载使配置生效:
firewall-cmd --reload3.3 限制源IP访问
使用rich rule限制特定IP访问端口:
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'重载后生效。
四、验证与排查:确保规则生效且无遗漏
配置完成后,从外部测试端口连通性:
nc -zv 服务器IP 22
nc -zv 服务器IP 80检查防火墙规则:
- iptables:
iptables -L -n -v - firewalld:
firewall-cmd --list-all
查看日志确认是否有拒绝记录:
tail -f /var/log/messages | grep -i drop或
journalctl -u firewalld -f常见问题:规则顺序错误导致允许规则被拒绝规则覆盖。iptables规则从上到下匹配,确保允许规则在拒绝规则之前。
五、最小化放行检查清单
| 检查项 | 操作 | 确认 |
|---|---|---|
| 默认策略是否为DROP/REJECT | iptables -P INPUT DROP 或 firewall-cmd --zone=public --set-target=DROP | 是 |
| 是否放行已建立连接 | iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT | 是 |
| SSH端口是否放行且限制源IP | iptables -A INPUT -p tcp -s 管理IP --dport 22 -j ACCEPT | 是 |
| Web端口是否放行 | 放行80/443 | 按需 |
| 数据库端口是否仅内网访问 | 使用rich rule或iptables限制源IP | 是 |
| 规则是否持久化 | iptables-save 或 firewall-cmd --runtime-to-permanent | 是 |
| 是否定期审计规则 | 每月检查一次 | 是 |
行动建议:立即加固你的服务器
不要等到被入侵才后悔。花10分钟,按照上述步骤检查并优化防火墙规则。对于需要更高级防护的场景,可以考虑使用AegisX的云防火墙服务,它提供可视化规则管理和自动威胁阻断,帮助你在最小化放行的基础上增加动态防护层。记住,安全是一个持续的过程,定期审计和更新规则同样重要。
常见问题(FAQ)
如何确定服务器需要开放哪些端口?
首先列出所有对外提供服务的端口,如Web的80/443、SSH的22。使用netstat -tulnp或ss -tulnp查看监听端口,结合业务需求确认必要性。非必要端口一律不开放,遵循最小权限原则。
iptables和firewalld应该用哪个?
两者都是Linux防火墙管理工具,iptables更底层灵活,firewalld提供动态管理和zone概念。CentOS/RHEL 7+默认使用firewalld,若已熟悉iptables也可继续使用。选择一种并保持统一,避免冲突。
修改防火墙规则后如何避免失去SSH连接?
建议先设置定时任务恢复规则,或使用nohup在后台测试。例如:`iptables-save > backup.rules`备份,然后添加规则并设置5分钟后还原:`echo 'iptables-restore < backup.rules' | at now +5 minutes`。确认无误后再取消定时任务。
firewalld如何只允许特定IP访问某端口?
使用rich rule实现,例如:`firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'`,然后重载防火墙。这样只有指定IP能访问3306端口。
如何验证防火墙规则是否生效?
使用`iptables -L -n -v`或`firewall-cmd --list-all`查看规则。从外部使用telnet或nc测试端口连通性:`nc -zv 服务器IP 端口`。同时检查日志:`tail -f /var/log/messages`或`journalctl -u firewalld`。