FTP服务器连不上,八成是防火墙把数据端口给拦了,别只盯着21端口。要想让FTP服务在公网稳定跑起来,得先弄明白主动模式和被动模式的数据链路差异,再针对你的服务器系统(Windows或Linux)和部署环境(物理机或云服务器)把规则写对。
先搞懂FTP的“双通道”机制,否则防火墙规则白设
FTP和HTTP最大的区别在于它需要占用两个端口:一个用于发送指令(控制连接),另一个用于传输文件(数据连接),防火墙只放行控制端口,数据链路照样被掐断,表现出来就是用户能登录,但列目录或传文件时卡死、超时。
主动模式(Active Mode)的数据连接怎么走
主动模式下,客户端向服务器的21端口发起连接后,服务器会主动从自己的20端口向客户端的随机端口发起数据连接,这种模式在公网场景下几乎必被客户端防火墙拦截,所以现在用得越来越少,如果你在局域网内部调试,且客户端防火墙关闭,主动模式才靠谱。
被动模式(Passive Mode)才需要你重点开端口
目前绝大多数FTP客户端(FileZilla、WinSCP)默认采用被动模式,流程是:客户端连服务器的21端口,服务器回复“我在某个端口段等你来连”,然后客户端再向这个随机端口发起数据连接。
这里就是防火墙设置的痛点:被动模式下,21端口固定,但数据端口是动态的,你需要在防火墙里放行一个连续的端口段(比如30000-31000),并把FTP服务端配置为只使用这个端口段,规则才能闭环。
vsftpd防火墙设置教程:CentOS/Rocky Linux实操
Linux生态里,vsftpd是用的最多的FTP服务端,很多教程只告诉你“放行21端口”,结果客户端还是报“Failed to retrieve directory listing”,咱们一步步把规则写对。
放行21端口之外,还得指定并放行被动端口段
首先编辑vsftpd配置文件,把被动端口段固定下来:
vim /etc/vsftpd/vsftpd.conf
在文件末尾加上:
pasv_enable=YES pasv_min_port=30000 pasv_max_port=31000 pasv_address=你的服务器公网IP
最后一行尤其关键,如果服务器在NAT后面(比如云主机),不写这行,客户端拿到的数据连接地址就是内网IP,连进来必然失败,保存后重启vsftpd服务:
systemctl restart vsftpd
firewalld和iptables配置对比
不同Linux发行版用的防火墙工具不一样,规则也略有差别。
以firewalld为例(默认使用)
CentOS 7及以上、Rocky Linux默认走firewalld,执行以下命令:
firewall-cmd --permanent --add-port=21/tcp firewall-cmd --permanent --add-port=30000-31000/tcp firewall-cmd --reload
这里用端口段而非单一端口,就是为了配合被动模式的动态端口分配,注意,有些教程还让你加--add-service=ftp,那个只放行21端口,不解决数据连接问题。
iptables用户看这里
如果你用的是纯iptables环境,规则这样写:
iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --dport 30000:31000 -j ACCEPT
用30000:31000这个冒号语法表示端口范围,请别忘了加-j ACCEPT,并记得保存规则(service iptables save),否则重启后规则就没了。
Windows服务器防火墙FTP端口设置
Windows系统自带的IIS FTP组件,或者第三方Serv-U,设置逻辑和Linux大同小异,唯一区别在于Windows防火墙的图形化配置界面。
IIS FTP的防火墙支持功能
打开IIS管理器 → 选中你的FTP站点 → 打开“FTP防火墙支持”功能,你会发现这里有一个数据通道端口范围的设置项,默认空着,意味着所有高位端口都可能被用来传输数据,这对防火墙规则来说是灾难。
实操步骤:
- 在“数据通道端口范围”里填上
30000-31000 - 填写服务器的外部IP地址(云服务器要填公网IP)
- 然后在Windows防火墙“高级设置”里,新建两条入站规则,分别放行TCP 21端口、TCP 30000-31000端口段
有些运维朋友会问,为啥不直接放行“FTP服务器”这个预定义规则呢?因为那个预定义规则只覆盖了21端口和边缘情况,很多Windows版本下对被动模式的支持不完整,特别是2008之后的系统,还是手动指定端口段最省心。
酷番云服务器FTP端口不通怎么解决
很多人在云服务器上搭建FTP失败,代码和防火墙都配了,从本地连还是报超时,问题往往出在安全组上,云厂商的安全组相当于一层独立于服务器操作系统之外的防火墙,你得两头检查。
本地防火墙先排掉
先用命令确认服务器端口是否处于监听状态:
netstat -tlnp | grep vsftpd
如果有LISTEN输出,说明服务活着,接下来确认系统防火墙规则是否真的生效了:
firewall-cmd --list-all
看输出里有没有21/tcp和30000-31000/tcp,这就排除了系统层面的问题,剩下的只能在安全组里排查。
云安全组和防火墙两头检查
登录酷番云控制台,找到你的服务器实例 → 安全组 → 入站规则列表,你要确保模板里有这两条规则:
- TCP协议,源地址
0.0.0/0,端口21 - TCP协议,源地址
0.0.0/0,端口30000-31000
这里有个典型误操作:用户在安全组里只放了21端口,系统防火墙却开了完整端口段,客户端能连接21端口(所以登录不报错),但当客户端尝试连接数据端口时却被底层拦截,现象就是“登录成功但列目录卡死”。
高效排查路径是:
- 先在服务器本地用
ftp 127.0.0.1测一次,看能不能完整显示目录 - 如果本地能、公网不能,重点看安全组
- 如果本地都不能,回头检查vsftpd配置和系统防火墙
常见场景:简米云FTP服务器防火墙配置要点
简米云服务器和酷番云大同小异,核心也是安全组和系统防火墙的双层放行,但简米云的普通安全组和企业安全组规则不同,普通安全组默认放行所有出方向,入方向需要显式添加,配置路径为:ECS实例 → 安全组 → 配置规则 → 入方向。
有一个细节容易踩坑:如果你的FTP客户端连接时提示“服务器发回了不可路由的地址”,这通常意味着你没有在vsftpd配置里设置pasv_address参数,导致服务器把自己的内网IP发给客户端,而客户端尝试连接内网IP自然失败,行业共识认为,这层配置在NAT环境中比防火墙本身还重要。
Q&A:FTP防火墙设置高频疑问
FTP主动模式端口不通,是不是防火墙拦了?
主动模式下,服务器向客户端发起连接时,源端口是20,目的端口是客户端随机开放的一个高位端口(客户端防火墙需要允许),如果你是局域网环境,建议直接在客户端防火墙里允许ftp-client程序,或者干脆关闭防火墙测试,如果必须在主动模式下公网使用,客户端防火墙需要放行本机1024以上端口,多数情况下这不现实,这才有了被动模式的普及。
修改了vsftpd端口范围后,防火墙规则是即时生效吗?
不是,vsftpd配置修改后需要重启服务,firewalld或iptables规则修改后也需要重载或重启防火墙服务,顺序建议是:先改配置,再重启服务,最后改防火墙规则,这样可以在测试时准确定位是服务端没起来还是防火墙拦截,验证时用firewall-cmd --reload就好,无需重启防火墙。
云服务器安全组和系统防火墙优先级怎么区分?
两者是叠加关系而非互相替代,数据包抵达服务器时,先经过安全组过滤,通过后才交给系统防火墙处理,只要有一层不放行,连接就会失败,配置FTP时需要同步检查这两层,安全组的端口段规则和系统防火墙的规则要完全一致,有个更省心的方案:把数据端口段设为1024-65535范围,但这样做会显著降低安全性,不建议在生产环境这么干。
防火墙本质上是帮你守住该开的门,而不是把门全焊死,FTP只要按“控制端口+数据端口段”的套路配置,不管跑在Windows还是Linux,不管在酷番云还是简米云,规则一通百通,下次遇到FTP连不上,先看端口段,再查安全组,基本不用折腾第二轮。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/581082.html




