CentOS服务器暴露在公网后,端口扫描几乎是每分钟都在发生的常态事件。攻击者通过批量扫描工具探测开放端口、识别服务版本、寻找已知漏洞,进而发起定向入侵。防端口扫描的核心不是让扫描行为完全消失——这在公网上不现实——而是让你的服务器在扫描结果中“隐身”或“高成本化”,让攻击者主动放弃。下面直接讲具体可落地的防护方法。

1. 最小化端口暴露:先做减法

很多服务器被攻破的起点,是开放了根本不需要对外服务的端口。先执行 ss -tlnp 查看当前监听的TCP端口,逐个确认哪些必须对公网开放。例如一台纯Web服务器,通常只需要22(SSH)、80(HTTP)、443(HTTPS)。像3306(MySQL)、6379(Redis)、9200(Elasticsearch)这类服务,如果不需要被外部直接访问,一律绑定到127.0.0.1,而不是0.0.0.0。修改服务配置文件中的监听地址,例如MySQL的 bind-address = 127.0.0.1,Redis的 bind 127.0.0.1。改完后重启服务,再用 ss -tlnp 复查,确保公网侧看不到这些高危端口。这一步比任何防火墙规则都更根本,因为服务根本不对外监听,扫描器连探测的机会都没有。

2. 用firewalld做默认拒绝策略

CentOS 7及以上版本默认使用firewalld。很多人只添加了开放端口的规则,却忽略了默认区域的策略。正确做法是先设置默认拒绝,再逐个放行必要端口。执行以下命令:

systemctl enable firewalld
systemctl start firewalld
firewall-cmd --set-default-zone=drop
firewall-cmd --permanent --add-port=22/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload

默认区域设为drop后,所有未被显式允许的入站连接都会被静默丢弃。这比reject更隐蔽,因为扫描器不会立即收到“端口不可达”的响应,连接会超时,大幅降低扫描效率。注意:如果你通过SSH远程管理服务器,务必先确保22端口已加入允许列表,否则执行reload后会立即断连。

3. 限制SSH访问来源与认证方式

SSH是扫描器重点关照对象,暴力破解尝试极其频繁。第一,如果管理IP固定,直接把SSH访问限制在特定来源IP或IP段。在firewalld中使用rich rule:

firewall-cmd --permanent --remove-port=22/tcp
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" port protocol="tcp" port="22" accept'
firewall-cmd --reload

这样除指定IP外,其他任何地址访问22端口都会被直接丢弃,扫描器甚至无法判断22端口是否开放。第二,禁用密码登录,改用密钥认证。编辑 /etc/ssh/sshd_config,设置 PasswordAuthentication no、PubkeyAuthentication yes、PermitRootLogin prohibit-password。同时可修改默认端口,虽然修改端口本身不构成安全,但能过滤掉大量无差别扫描。改端口后同样需要在firewalld中放行新端口,并移除旧端口的开放规则。

4. 部署fail2ban实现动态封禁

防火墙静态规则只能做粗粒度控制,fail2ban则能根据日志动态识别扫描行为并自动封禁来源IP。安装:yum install epel-release -y && yum install fail2ban -y。创建配置文件 /etc/fail2ban/jail.local:

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1 203.0.113.50

[sshd]
enabled = true
port = 22
logpath = /var/log/secure

上述配置表示600秒内同一IP失败5次,封禁1小时。fail2ban会自动向firewalld中添加拒绝规则。更进一步,可以针对端口扫描行为创建自定义jail。例如通过监控firewalld日志中大量被丢弃的连接记录,或者使用psad这类专门检测端口扫描的工具。psad能分析iptables日志,识别SYN扫描、FIN扫描等多种扫描模式,并自动将扫描源加入阻断列表。安装psad后,配置 /etc/psad/psad.conf 中的 ENABLE_AUTO_IDS="Y",并设置扫描阈值,例如 SCAN_THRESHOLD=5,表示5秒内检测到5个以上未授权连接尝试即判定为扫描。

5. 利用iptables限制连接速率

firewalld底层就是iptables,对于需要对外提供服务的端口(如80/443),可以用限速规则防止单IP的高频连接尝试。例如限制每个IP对80端口的新建连接速率:

iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 60 --hitcount 20 -j DROP

这组规则表示60秒内单个IP对80端口发起超过20次新建连接,后续连接直接丢弃。对于SSH端口同样可以设置更严格的限速,例如60秒内只允许3次新建连接。注意这些规则重启后会丢失,需要写入 /etc/sysconfig/iptables 或通过firewalld的direct规则持久化。

6. 关闭ICMP响应与系统信息泄露

扫描器常先ping探测主机存活,再决定是否深入扫描。虽然关闭ICMP不能阻止所有扫描,但能过滤掉依赖ping的初级扫描器。在firewalld中禁止ICMP:

firewall-cmd --permanent --add-icmp-block=echo-request
firewall-cmd --reload

同时检查 /etc/sysctl.conf,加入以下内核参数强化网络层行为:

net.ipv4.tcp_syncookies = 1
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2

执行 sysctl -p 生效。这些参数开启SYN Cookie防护、关闭ICMP回显、开启反向路径过滤,能有效缓解SYN Flood和IP欺骗类扫描。

7. 隐藏服务版本信息

扫描器识别开放端口后,下一步就是抓取服务banner判断软件版本,再匹配已知漏洞。对于Web服务器,隐藏版本信息能增加攻击者的判断成本。Nginx在配置文件中设置 server_tokens off;Apache在 httpd.conf 中设置 ServerTokens Prod 和 ServerSignature Off。对于SSH,修改 /etc/ssh/sshd_config 中的 VersionAddendum 参数可以去掉额外的版本字符串,但OpenSSH主版本号无法完全隐藏。更彻底的做法是在SSH服务前加一层端口敲门(Port Knocking)机制,只有按特定顺序访问过预设端口组合的IP,才会被临时放行到22端口。实现方案可用knockd,配置 /etc/knockd.conf 定义敲门序列,例如 7000,8000,9000 三个端口依次访问后,才打开SSH端口30秒。这种机制让扫描器完全无法探测到SSH服务的存在。

8. 定期审计与主动验证

防护措施部署后,必须从外部视角验证实际效果。使用 nmap 从另一台机器对服务器执行扫描:nmap -sS -sV -p- 服务器IP。观察扫描结果中开放端口的数量是否与预期一致,服务版本信息是否还能被识别。如果发现意外开放的端口,立即回溯检查服务配置和防火墙规则。同时定期检查 /var/log/secure、/var/log/messages 以及firewalld日志,分析是否有异常连接模式。对于持续扫描的来源IP段,可以直接在firewalld中添加整段拒绝规则,例如 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="45.155.0.0/16" drop'。

9. 针对大规模扫描的进阶策略

对于遭遇持续性、大规模扫描的服务器,可以考虑在网络边界部署更主动的防御。例如使用ipset配合iptables维护一个动态黑名单,将触发规则的IP自动加入黑名单并设置过期时间。ipset比iptables线性规则效率更高,适合处理数千条封禁记录。创建ipset集合:ipset create scanner-blacklist hash:ip timeout 86400。然后在iptables中添加规则,将匹配到的扫描源IP加入集合,并对集合中的IP直接DROP。这种方式能显著降低iptables规则数量,提升匹配性能。另外,如果服务器托管在云平台,优先使用云平台提供的安全组功能,在安全组层面只开放必要端口,这比操作系统层防火墙更早拦截扫描流量,且不消耗服务器自身资源。

10. 建立响应机制与持续监控

防端口扫描不是一次性配置,而是持续的过程。建议部署轻量级监控脚本,定期检查端口监听变化和防火墙规则完整性。例如每天对比 ss -tlnp 的输出快照,发现新增监听端口立即告警。对于fail2ban和psad的封禁记录,定期查看封禁数量趋势,如果某段时间封禁量异常激增,说明正在遭受集中扫描,需要进一步分析来源特征。同时保持系统更新,及时修补服务漏洞,因为端口扫描的最终目的是利用漏洞,即使端口被扫描到,只要服务本身没有可利用的漏洞,攻击者也无法得手。将 yum update 纳入定期维护计划,并关注CentOS官方的安全公告。

综合运用以上方法,你的CentOS服务器在公网扫描器眼中的“可见面”会大幅缩小,扫描成本显著提高。安全防护的本质是提高攻击者成本、降低自身风险,而不是追求绝对不可见。把这些基础做扎实,绝大多数自动化扫描和机会型攻击都会被挡在门外。