拿到一台全新的Ubuntu云服务器,很多人的第一反应是立刻开始部署应用、配置环境。但往往在服务刚跑起来几分钟,SSH日志里就开始出现来自世界各地的暴力破解尝试。这不是危言耸听,而是公网服务器的日常。解决这个问题最直接、最核心的一步,就是立即启用防火墙并设置默认拒绝所有入站流量。这并非高深技巧,而是服务器安全的基础底线。

Ubuntu系统自带的防火墙工具是UFW,全称Uncomplicated Firewall。它本质上是对iptables的一层友好封装,把复杂的iptables规则链简化为几个直观的命令。很多教程会直接教你放行22端口、80端口,但在此之前,必须先把默认策略从“允许”扭转为“拒绝”。如果不这么做,你后续添加的放行规则就失去了根基,任何你忘记关闭的服务都可能成为入侵的入口。

我们先来看默认策略的状态。一台刚装好的Ubuntu,UFW通常处于未激活状态,且默认入站策略往往是“允许”。你可以用以下命令确认:

sudo ufw status verbose

如果输出显示“inactive”或者默认入站策略为“allow”,那就意味着你的服务器正敞开着大门。此时,正确的做法不是先开放端口,而是立刻执行:

sudo ufw default deny incoming

这条命令的意思是:所有从外部发起的连接请求,如果没有被显式地放行,一律直接丢弃。注意,是丢弃而非拒绝。丢弃意味着不回应任何数据包,让扫描者无法判断端口是否存活,这能有效拖慢扫描探测的速度。执行完这条命令后,再执行:

sudo ufw default allow outgoing

这允许服务器主动向外发起连接,比如下载软件包、请求API等,不会影响服务器的正常对外通信。这两条默认策略一设,安全基线就建立起来了。

在开启防火墙之前,有一个极其关键的步骤,如果搞错,你会瞬间失去对服务器的访问。那就是必须提前放行你的SSH管理端口。绝大多数人使用的是默认的22端口,命令如下:

sudo ufw allow 22/tcp

如果你已经修改过SSH端口,比如改成了2222,那么请把命令中的22换成你的实际端口。强烈建议不要使用默认端口,因为扫描器会集中火力攻击22端口。修改SSH端口的方法很简单,编辑/etc/ssh/sshd_config文件,找到Port 22那一行,去掉注释并修改为其他高位端口,然后重启SSH服务即可。在修改并放行新端口后,务必保留当前SSH会话不断开,另开一个终端测试新端口能否登录,确认无误后再关闭旧端口的放行规则。

放行SSH端口后,就可以正式启用防火墙了:

sudo ufw enable

系统会提示你命令可能中断当前连接,输入y确认。因为我们已经提前放行了SSH端口,所以连接不会中断。启用后,可以用sudo ufw status查看当前规则列表,你应该能看到SSH端口被允许,而其他入站请求都被默认拒绝。

接下来是放行Web服务端口。如果你运行的是HTTP服务,需要放行80端口:

sudo ufw allow 80/tcp

如果是HTTPS服务,需要放行443端口:

sudo ufw allow 443/tcp

UFW还支持按服务名称放行,比如sudo ufw allow http和sudo ufw allow https,本质是一样的,但显式指定端口和协议更严谨,不容易出错。如果你的Web服务同时需要HTTP和HTTPS,可以合并为一条命令:

sudo ufw allow 80,443/tcp

除了Web和SSH,你可能还有数据库服务。这里有一个常见的严重错误:很多人为了远程管理方便,直接放行了MySQL的3306端口或PostgreSQL的5432端口。这等于把数据库直接暴露在公网上,极其危险。数据库应该只监听本地回环地址127.0.0.1,或者只允许内网特定IP访问。如果必须远程连接,应该通过SSH隧道转发,而不是直接开放端口。UFW可以#34;允许特定IP访问特定端口的功能可以这样用:

sudo ufw allow from 192.168.1.100 to any port 3306

这表示仅允许内网IP 192.168.1.100访问3306端口,其他任何来源的请求都会被默认拒绝策略挡掉。

对于更复杂的应用,比如Docker容器,这里有一个大坑。Docker默认会直接操作iptables,绕过UFW的规则。也就是说,你即便设置了默认拒绝所有入站,Docker映射到宿主机端口的服务仍然可以从公网访问。这是因为Docker在iptables的FORWARD链和DOKER链中添加了规则,其优先级高于UFW的INUT链。要解决这个问题,你需要在Docker守护进程配置中禁用自动iptables管理。编辑/etc/docker/daemon.json文件,添加:

{
  "iptables": false
}

然后重启Docker服务。但这样做之后,Docker容器间的网络通信会受影响,你需要手动配置容器间通信规则。更稳妥的做法是,在启动容器时,如果某个服务只需要本地访问,就将端口映射绑定到127.0.0.1而非0.0.0.0。例如:

docker run -p 127.0.0.1:8080:80 nginx

这样即使Docker绕过了UFW,外部也无法直接访问这个服务,因为它只监听在本地回环地址上。对于确实需要对外暴露的服务,再单独在UFW中放行对应端口,并保持Docker的自动iptables功能开启,形成双重防护。

除了基于端口的规则,UFW还支持基于应用的配置。你可以查看系统已注册的应用列表:

sudo ufw app list

常见的如Nginx、OpenSSH等都会出现在列表中。使用sudo ufw allow 'Nginx Full'这样的命令可以一次性放行80和443端口。但要注意,应用配置文件的定义可能不完全符合你的需求,最好检查一下/etc/ufw/applications.d/目录下的配置文件内容,确认它放行的端口是否正确。

默认拒绝所有入站策略生效后,你可能会遇到一些意想不到的连接问题。比如FTP服务的被动模式需要服务器开放一段高端口范围来传输数据,或者某些游戏服务器需要开放UDP端口。这时候需要针对性地放行端口范围:

sudo ufw allow 6000:6003/tcp
sudo ufw allow 6000:6003/udp

对于IPv6用户,UFW默认同时管理IPv4和IPv6规则。你可以在/etc/default/ufw中将IPV6设置为yes来确认这一点。这意味着你的默认拒绝策略会同时应用到IPv6流量上,不会出现IPv4锁死了但IPv6敞开的尴尬情况。

日志记录是安全审计的重要环节。UFW默认会将被拒绝的连接记录到系统日志中。你可以通过以下命令查看:

sudo ufw logging on

日志级别可以设置为low、medium、high、full,默认是low。设置得太高会产生大量日志,占用磁盘空间。通常medium级别就足够,它会记录所有被拒绝的入站和出站包。日志文件位置在/var/log/ufw.log,你可以用tail -f /var/log/ufw.log实时观察防火墙拦截情况。如果发现某个必要的服务被误拦,再补充放行规则即可。

最后,定期审查规则是个好习惯。服务器运行一段时间后,可能会积累一些不再#34;临时放行后来忘记删除的规则。执行sudo ufw status numbered可以查看带编号的规则列表,然后用sudo ufw delete 编号来删除不再需要的规则。保持规则集的最小化,只开放必要的端口,是长期维护服务器安全的关键。

开启防火墙并设置默认拒绝所有入站,这看似简单的一个动作,实际上构成了服务器安全防御的第一道也是最重要的一道屏障。它不消耗系统资源,不影响正常服务,却能挡住绝大多数无差别的扫描和攻击。在云服务器环境里,这条规则的价值怎么强调都不过分。