VPS防火墙怎么只放必要的端口?iptables最小权限规则配置

VPS默认防火墙是空的——所有端口对公网敞开。本文给出iptables最小权限配置:放行SSH和服务端口后设置默认DROP,配合连接追踪、SSH防爆破限流和持久化保存。雨云优惠码admin01新用户五折,KVM支持完整iptables。
发布于
15

很多人拿到VPS后第一件事是装宝塔或跑Docker,很少有人主动去配防火墙。默认情况下大部分VPS镜像的iptables是空的——所有端口对所有IP开放。你的SSH端口、数据库端口、Redis端口都暴露在公网上,被扫到只是时间问题。

本文给出一个「最小权限」的iptables配置方法:显式放行你需要的端口,其余全部拒绝。雨云优惠码admin01新用户五折,KVM云服务器支持完整的iptables规则,不会像部分轻量服务器那样限制内核模块。

为什么要用iptables而不是云平台防火墙

雨云等云平台控制台提供了防火墙功能,可以设置入站和出站规则。那为什么还要在服务器上配iptables?

  • 双重防护:云平台防火墙是第一层(网络边界),iptables是第二层(主机层)。两层都在总比一层好
  • 云平台防火墙的粒度有限:通常是按端口和协议过滤,无法做到基于连接状态的精细控制
  • 出站控制:云平台防火墙主要管入站,iptables可以精细控制服务器主动发出的连接
  • 防内网横向移动:如果你的VPS被入侵了,iptables可以限制内网流量,防止攻击者从你这台机器跳到同网段的其他机器
  • 不受云平台限制:云防火墙有规则数量上限,iptables没有这种限制

最佳做法是两层都用。云平台防火墙放行常用端口(80/443/SSH端口),iptables做更精细的控制。

iptables基础概念:表、链和规则

iptables有四个核心概念,理解这三个就不会被命令吓到:

  • 表(Table):规则的分组。最常用的是filter表(用于过滤流量),还有nat表(用于地址转换)和mangle表(用于修改数据包)
  • 链(Chain):一个表里有几条链。filter表有INPUT(入站)、OUTPUT(出站)和FORWARD(转发)三条链。每条链是一个规则列表,数据包按顺序匹配
  • 规则(Rule):每条规则定义了一个匹配条件和一个动作(ACCEPT放行、DROP丢弃、REJECT拒绝并通知对方)。匹配到第一条符合条件的规则后停止
  • 策略(Policy):链的默认动作,当数据包不匹配任何规则时执行。我们会在每条链的末尾设置默认DROP

数据包的流动路径:入站流量进INPUT链 → 逐条匹配规则 → 匹配到就执行动作 → 都不匹配就执行默认策略(Policy)。出站类似,走OUTPUT链。

第一步:查看当前规则

SSH登录VPS后,先看当前的iptables状态:

sudo iptables -L -n -v

参数说明:-L列出规则,-n不解析IP为主机名(速度快),-v显示详细信息(包括数据包和字节计数器)。

如果输出显示三条链都是空的(只有Chain名字和policy ACCEPT),说明当前没有任何防火墙规则——所有流量都可以自由进出。这也是大多数VPS的默认状态。

第二步:先写好SSH放行规则(最重要)

在设置默认DROP之前,必须先放行你的SSH端口(通常是22,但建议改成非标准端口)。如果先把INPUT默认策略改成DROP再发现自己SSH连不上了,就只能通过云平台控制台的VNC来恢复了。

假设你的SSH端口是22:

# 放行已经建立的连接(让SSH当前会话不断开)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 放行SSH端口
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 放行回环接口(本地服务之间的通信)
sudo iptables -A INPUT -i lo -j ACCEPT

-A INPUT表示追加规则到INPUT链,-p tcp指定协议,--dport 22指定目标端口。第一条用了conntrack连接追踪模块,让已经建立的SSH连接不会因为后面的DROP规则被断开。

如果你改了SSH端口(比如改成2222):

sudo iptables -A INPUT -p tcp --dport 2222 -j ACCEPT

第三步:放行你需要的服务端口

在放行SSH的基础上,继续追加你实际需要的服务端口:

# Web服务
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 如果需要ping(ICMP),放行echo-request
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 宝塔面板端口(如果你装了宝塔,默认8888)
sudo iptables -A INPUT -p tcp --dport 8888 -j ACCEPT

# Docker暴露的端口(举例:一个Web应用在8080)
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

原则是:**只放行你真正在用的端口**。不要复制别人的规则列表全盘照抄——别人可能开了MySQL远程端口3306,你不需要的话就别放。

第四步:设置默认DROP

放行完成必要端口后,把INPUT的默认策略改成DROP:

sudo iptables -P INPUT DROP

这行命令的意思是:所有不匹配以上任何ACCEPT规则的入站流量,全部丢弃。

执行前务必确认:

  • SSH端口已经放行
  • ESTABLISHED,RELATED连接追踪已放行(避免当前SSH会话断开)
  • 你开了两个SSH终端窗口,这样万一配错了还有一个能恢复

出站流量(OUTPUT链)通常保持默认ACCEPT即可——服务器主动发出的请求一般不需要限制。如果你需要限制出站(比如防止被入侵后往外发数据),可以同样配置OUTPUT链。

第五步:查看和验证规则

配置完成后,用以下命令查看规则列表和顺序:

sudo iptables -L -n -v --line-numbers

--line-numbers显示规则编号,方便后续删除或插入。输出示例:

Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      123  9876 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
2        5   300 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
4        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
5        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0

用外部工具验证:从你的本机(不在VPS上的另一台机器)用 nmap 扫描VPS的端口:

nmap -p 22,80,443,3306,6379 VPS的IP

应该只看到22/80/443是open状态,3306(MySQL)和6379(Redis)是filtered(被DROP了,连不上也扫不到)。

第六步:持久化保存

iptables规则存在内存中,重启VPS后会丢失。需要安装iptables-persistent来保存:

# Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save

# CentOS/RHEL
sudo yum install iptables-services
sudo service iptables save
sudo systemctl enable iptables

安装iptables-persistent时会提示是否保存当前规则,选Yes。以后每次修改iptables规则后记得重新保存:

sudo netfilter-persistent save

添加和删除单条规则

日常操作中可能需要临时调整规则:

# 在指定位置插入规则(在第3条之前插入)
sudo iptables -I INPUT 3 -p tcp --dport 9090 -j ACCEPT

# 删除第3条规则
sudo iptables -D INPUT 3

# 删除匹配特定条件的规则(如果有重复会删第一条匹配的)
sudo iptables -D INPUT -p tcp --dport 9090 -j ACCEPT

# 清空所有规则(危险!会删掉SSH放行)
sudo iptables -F

注意:-F清空所有规则不会改变默认策略。如果默认策略已经是DROP,清空规则后所有流量都会被拒绝,包括SSH。

限流防护:SSH暴力破解

除了基本放行,iptables还可以做限流。SSH暴力破解是VPS最常见的攻击方式,用一个限流规则可以在不影响正常使用的前提下大幅减少攻击尝试:

# 同一IP在60秒内最多发起3个新的SSH连接,超出的丢弃
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

这两条规则配合:第一条记录每个新连接的来源IP,第二条检查60秒内同一IP是否已经有3个以上的新连接——如果超过,第4个开始丢弃。

替代方案:nftables和ufw

iptables是经典的Linux防火墙,但在较新的发行版中逐渐被nftables取代。nftables语法更简洁,性能更好:

# nftables 等效配置
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport {80, 443} accept

如果你觉得iptables命令太繁琐,可以用ufw(Uncomplicated Firewall)——它是iptables的一个友好前端:

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

ufw底层还是iptables,只是包装了一层更简单的命令。

故障恢复:配错后被锁在外面怎么办

如果iptables配错导致SSH断开,不要慌:

  1. 通过雨云控制台的「VNC」或「控制台」功能登录服务器——这个不依赖网络,相当于直接插显示器
  2. 执行 sudo iptables -P INPUT ACCEPT 把INPUT默认策略改回ACCEPT
  3. 修改规则后重新测试SSH
  4. 确认SSH正常后重新设置DROP策略

另一种更安全的方法:在配置iptables时加一个「保险丝」——配一个定时任务,5分钟后自动恢复ACCEPT策略。如果你配错了被锁在外面,5分钟后自动恢复:

# 在修改iptables之前先执行
sudo bash -c 'echo "iptables -P INPUT ACCEPT" | at now + 5 minutes'

修改完后验证SSH没问题,再取消这个定时任务:

sudo atq  # 查看定时任务ID
sudo atrm 任务ID  # 取消

合规声明

本文所述的iptables防火墙配置方法属于常规的服务器安全运维操作。服务器的使用应遵守《网络安全法》《数据安全法》等法律法规,确保部署的应用和服务符合合规要求。

常见问题(FAQ)

云平台已经有防火墙了,为什么还要配iptables?
双重防护。云防火墙是网络边界层,iptables是主机层。iptables可以做更精细的控制(连接状态追踪、限流、出站过滤),且不受云防火墙规则数量限制。两者配合使用是最佳实践。
iptables配错被锁在外面了怎么办?
通过云平台控制台的VNC功能登录(不依赖网络),执行sudo iptables -P INPUT ACCEPT恢复默认策略。建议在修改iptables前设置一个5分钟后的自动恢复定时任务作为保险。
iptables和ufw有什么区别?
ufw是iptables的前端,命令更简单(ufw allow 22/tcp),底层还是调用iptables。新手推荐ufw,需要高级功能(限流、连接追踪)时用iptables。本教程以iptables为主,最后也给出了ufw的等效配置。
iptables规则重启后会丢失吗?
会的。iptables规则存在内存中。需要安装iptables-persistent(Debian/Ubuntu)或iptables-services(CentOS)并执行保存命令,确保重启后自动恢复规则。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 / 600
0 讨论
热门最新
总结
暂无总结

暂无数据