Ubuntu服务器只靠默认的SSH密钥登录和改端口并不够,一旦业务端口暴露在公网,扫描和爆破流量会持续消耗资源。白名单机制的核心思路是先把默认策略设为拒绝,再只放行你信任的IP或IP段访问指定端口。Ubuntu上最直接的实现工具是系统自带的UFW,它本质上是iptables的前端,但规则管理更不容易出错。下面直接讲如何从零配置一套可用的防火墙白名单访问机制。

先确认UFW状态和默认策略

Ubuntu桌面版和服务器版通常都预装了UFW,但默认没有启用。先执行sudo ufw status查看状态,如果显示inactive,说明防火墙还没生效。正式配置前,先设置默认规则:sudo ufw default deny incoming,这会让所有入站连接默认被拒绝;再执行sudo ufw default allow outgoing,保证服务器主动对外请求不受影响。这两步是白名单机制的基础,顺序不能反,否则一旦启用防火墙,你现有的SSH连接可能直接断开。

优先放行管理IP再启用防火墙

很多人配置白名单失败,是因为先启用了防火墙,然后才想起来加SSH放行规则,结果把自己锁在服务器外面。正确顺序是先添加你自己的公网IP或办公网出口IP。假设你的固定IP是203.0.113.50,执行sudo ufw allow from 203.0.113.50 to any port 22 proto tcp。如果IP不固定,至少先放行你当前运营商分配的公网网段,例如sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp。确认规则已经写入后,再执行sudo ufw enable启用防火墙。

按服务维度建立白名单规则

白名单不是只放行SSH,而是要针对每个对外开放的服务分别控制。比如服务器运行Nginx,只希望公司IP和CDN回源节点访问443端口,可以执行sudo ufw allow from 198.51.100.0/24 to any port 443 proto tcp。如果还有数据库端口5432,只允许内网网段10.0.0.0/8访问,执行sudo ufw allow from 10.0.0.0/8 to any port 5432 proto tcp。每条规则都要明确来源IP或网段、目标端口和协议,避免使用any放行全部端口,否则白名单就失去了意义。

处理动态IP和跳板机场景

家庭宽带或移动办公场景下,出口IP经常变化,固定IP白名单会导致无法连接服务器。这时可以设置一台固定IP的跳板机,所有管理流量先经过跳板机再访问目标服务器。目标服务器只放行跳板机IP,跳板机本身再通过密钥认证和二次验证加固。如果必须直接放行动态IP,可以定期更新规则,但安全边界会变弱。更稳妥的做法是使用云服务商的安全组配合UFW,在两层都做白名单限制。

用UFW配置文件管理复杂规则

当规则超过十几条,命令行维护会变得混乱。UFW支持在/etc/ufw/before.rules和/etc/ufw/after.rules中直接写iptables规则,但更推荐使用应用配置文件。在/etc/ufw/applications.d/目录下创建自定义文件,定义端口组合,例如定义一个名为web的白名单应用,包含80和443端口。然后执行sudo ufw allow from 203.0.113.0/24 to any app web,这样规则更易读,也方便批量修改。

验证规则和排查连接问题

配置完成后执行sudo ufw status numbered查看所有规则及编号,确认默认策略是deny incoming,并且允许的IP和端口都正确。如果发现某个IP无法连接,先检查该IP是否在规则列表中,再确认对方出口IP是否和预期一致。可以用sudo tail -f /var/log/ufw.log查看实时拦截日志,日志中会显示被拒绝的源IP、目标端口和协议。如果日志中看到合法IP被拦截,说明规则没有覆盖到该IP,需要补充放行。

结合ipset处理大规模IP白名单

如果白名单IP数量达到几百甚至上千个,逐条添加UFW规则会拖慢防火墙处理速度。这时可以借助ipset。先安装ipset,创建一个名为whitelist的集合,把需要放行的IP批量加入集合。然后在UFW的before.rules中添加一条规则,匹配ipset集合中的IP直接放行。这样iptables只需要匹配一次集合,不用逐条比对,性能更好。ipset还支持定时更新,适合需要频繁变动的IP列表。

防止规则被意外清空

服务器重启或UFW重载后,规则一般会保留,但如果手动执行了ufw reset,所有规则会被清空并恢复默认策略。为了防止误操作导致服务中断,建议定期备份规则。执行sudo ufw status numbered > ufw-backup.txt保存当前规则列表,或者直接备份/etc/ufw/目录下的配置文件。恢复时重新执行规则命令即可。另外,修改防火墙前最好先开一个备用SSH会话,万一主会话断开,还能通过备用会话恢复规则。

白名单之外的加固措施

防火墙白名单只解决谁能访问的问题,不解决访问者身份是否可信的问题。即使来源IP在白名单内,如果该IP对应的设备已经被入侵,攻击者依然可以直达服务器。因此白名单必须配合强认证手段,比如SSH禁用密码登录、启用密钥认证、配置fail2ban防止暴力破解。对于Web服务,还需要在应用层做访问控制,例如Nginx中限制特定路径只能由指定IP访问。多层防护叠加,才能让白名单机制真正发挥作用。

实际配置示例

下面给出一套完整的UFW白名单配置流程,假设服务器IP为192.0.2.10,需要放行办公网203.0.113.0/24访问SSH和Web端口,放行监控服务器198.51.100.25访问Zabbix端口10050。

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw allow from 203.0.113.0/24 to any port 80 proto tcp
sudo ufw allow from 203.0.113.0/24 to any port 443 proto tcp
sudo ufw allow from 198.51.100.25 to any port 10050 proto tcp
sudo ufw enable
sudo ufw status verbose

执行完这些命令后,只有规则中列出的来源IP能访问对应端口,其他所有入站流量都会被丢弃。如果后续需要新增IP,直接执行sudo ufw allow from 新IP to any port 端口 proto tcp即可。

常见错误和注意事项

第一,不要在未放行SSH的情况下启用防火墙。第二,不要使用sudo ufw allow 22这种不带来源限制的规则,这等于对所有IP开放22端口,白名单形同虚设。第三,修改默认策略为deny incoming后,如果服务器上有Docker容器,Docker的端口映射可能绕过UFW,需要额外配置DOCKER-USER链。第四,测试规则时不要直接重启服务器,先用ufw reload验证规则语法。第五,定期审查规则,删除不再使用的IP和端口,保持规则集最小化。

白名单访问机制不是一次性配置完就结束了,它需要随业务变化持续维护。把默认拒绝作为底线,只放行必要的来源和端口,再配合日志监控和定期审计,Ubuntu服务器的公网暴露面就能被压缩到最小。这套方法对大多数中小型业务足够实用,而且完全基于系统自带工具,不依赖第三方付费防火墙。