☰
阿里云FTP报错425?vsftpd被动模式与安全组配置全解
2026/10/17 10:17:19 网站建设 项目流程

1. 问题场景与报错拆解

1.1 一条几乎让所有FTP新手都头疼的报错

如果你在地铁上、工位上,或者深更半夜还盯着屏幕折腾“阿里云搭建 ftp 服务器”,大概率已经见过下面这段对话:

Connected to 49.xxx.xxx.xxx. 220 (vsFTPd 3.0.3) Name (49.xxx.xxx.xxx:root): test 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> ls 200 PORT command successful. Consider using PASV. 425 Failed to establish connection. ftp>

登录成功、密码验证通过、服务端也响应了,但一执行ls就立刻翻车。200 PORT command successful. Consider using PASV.后面跟着425 Failed to establish connection.,然后整个会话就像被掐住脖子一样,什么都做不了。

我第一次遇到这个报错时,第一反应是“防火墙没放行端口”,于是把 21 端口在安全组和系统防火墙里放了一遍又一遍,甚至一度怀疑是阿里云的入方向规则和本地网络冲突。折腾了大半天才搞清楚:这不是简单的端口没放开,而是FTP协议本身的工作模式在云服务器环境下“水土不服”。这篇文章会把这个问题从头到尾拆开,从协议原理讲到云服务器环境的特殊坑点,再给出一套可以直接照抄的完整配置流程,帮你在二十分钟内把这事搞定。

1.2 主动模式与被动模式的底账

要理解 425 报错,必须先看清 FTP 的两种数据传输模式。

FTP 使用两条通道:一条叫控制连接(通常走 21 端口),负责传递指令和响应;另一条叫数据连接,负责实际传输目录列表或文件内容。问题是,这条数据连接的建立方式有两种完全不同的玩法。

主动模式(Active Mode,PORT)

客户端在控制连接上发送PORT 192,168,1,100,10,50这样的命令,意思是“我在某个 IP 的某个端口上等着,你(服务器)主动连接过来”。

这里有个关键点:服务器是主动方,它从自己的 20 端口发起连接,去连客户端指定的那个高位端口。

被动模式(Passive Mode,PASV)

客户端发送PASV命令后,服务器回应227 Entering Passive Mode (49,xxx,xxx,xxx,200,10),告诉客户端“我在这个 IP 的 20010 端口上等你来连接”。这回客户端变成了主动方,由它去连服务器开出来的数据端口。

回到报错本身:当你看到200 PORT command successful.,意味着你手头的FTP客户端默认在发PORT命令,也就是要求服务器反过来连你。这与云服务器默认的安全策略天然冲突,接下来的内容会详细解释这个“冲突”到底是怎么发生的。

1.3 425报错的真实含义

服务器回应425 Failed to establish connection.,翻译成人话就是:服务器收到了你的PORT命令,也愿意配合你的主动模式去连你指定的那个地址和端口,但是——连不上。

为什么会连不上?因为服务器尝试用它的 20 端口去连接客户端的 IP:Port 时,这个连接请求被拦掉了。最常见的拦截点有三个:

  1. 你所在本机的防火墙/杀毒软件拦住了来自外网的主动连接;
  2. 你家或者公司的路由器/NAT 设备没有做端口转发,服务器根本找不到“你”;
  3. 云服务器侧因为net.ipv4.ip_forward、iptables状态跟踪模块缺失,放行了第一个数据包却放行不了后续的包。

这里面最坑的一点是,425 Failed to establish connection.往往并不会告诉你到底是哪一环被拦了。客户端日志里只有一句话,服务端日志(/var/log/vsftpd.log)里可能也只写着CONNECT: Client "49.xxx.xxx.xxx", "Connection refused",信息量少得可怜。所以接下去要做的,是把这条链路从头到尾捋一遍,找到那个真正卡住你的环节。

2. 云环境下FTP失败的根因链条

2.1 默认配置下vsftpd在做什么

很多教程会教你装 vsftpd 之后直接systemctl start vsftpd就算完成。这个操作本身没错,但在云服务器上,默认配置几乎必踩坑。因为 vsftpd 默认会同时支持主动和被动模式,而主动模式在云环境下就是一个“陷阱”。

看一段典型的 vsftpd 默认配置文件(/etc/vsftpd/vsftpd.conf):

anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen_ipv6=NO pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES

看到connect_from_port_20=YES没有?这一项表示在主动模式下,vsftpd 使用 20 端口作为数据连接源端口。问题是,云服务器安全组如果没有放行 20 端口,或者本地客户端所在网络拒收外网主动连接,这条数据通道就立不起来。

更麻烦的是,默认情况下 vsftpd 没有显式声明被动端口范围。如果客户端改用PASV模式(这也是报错信息里那句Consider using PASV.在提醒你的事),vsftpd 会动态分配一个高位端口——一般是 1024 到 65535 之间的任意端口。这就让安全组规则变得非常难配:难道要把所有高位端口全部放行?那样安全风险太大了。

所以,云服务器上跑 FTP 必须把被动端口范围固定下来,比如pasv_min_port=30000和pasv_max_port=30010,然后只放行这一段端口。这可能是整个配置过程中最重要的一步,没有之一。

2.2 云服务器的三层拦截

先说本地虚拟机或公司内网服务器。在那里跑 FTP,通常只需要关心服务器本机的防火墙。但在云服务器(无论哪家云厂商)上,流量要过三层关卡:

第一层:云平台安全组。阿里云 ECS 的控制台里有一份入方向规则列表。默认情况下只放行 22、3389 等少数端口,21 端口需要手动添加规则。很多人配了 21 端口,结果数据连接走的是 30000+ 的高位端口,安全组里没有对应规则,数据通道直接中断。

第二层:操作系统防火墙。云服务器镜像默认开启 firewalld 或 ufw,它们的规则是独立于云平台安全组的。即使安全组放行了 21 和 30000-30010,本机防火墙不放行,数据连接依然进不来。

第三层:内核连接跟踪模块。这一层最容易忽略。FTP 的主动模式太特立独行——数据连接的建立方向和控制命令是反着来的。Linux 内核的conntrack(连接跟踪)机制如果不知道“这是 FTP 的数据连接”,就会把数据包当成无关联的新连接。若防火墙规则里没有显式放行这些端口,数据包就会被丢弃。

这也能解释为什么很多人在本地测试时一切正常,一放到云服务器就 425。本地如果没开防火墙,或者防火墙比较宽松,三层拦截只碰到一层甚至一层都碰不到;在云服务器上,三层拦截是叠加的,任何一层出问题都会导致最终连接失败。

2.3 为什么本地测试“一切正常”

这个现象很迷惑人:同样的配置,在本地用ftp 192.168.1.100测,ls正常,上传下载也正常;一换成阿里云的公网 IP,就 425。

原因在于,192.168.1.100在同一个局域网内,服务器去连你的 IP:Port 时,中间没有 NAT 设备,也没有安全组拦截。数据包从服务器网卡出来,一路直达你的电脑,畅通无阻。

但公网环境下,你的电脑在某个局域网里(比如公司网络),服务器看到的你的 IP 是路由器做了 NAT 之后的公网出口地址,而你的PORT命令里填的可能还是你本机的局域网 IP,比如192.168.1.100。服务器试着去连接192.168.1.100:port,结果这个地址在公网根本路由不到。于是425 Failed to establish connection.就如期而至了。

这也是为什么PORT模式在公网环境里几乎不可用——它对客户端的网络环境要求极为苛刻,客户端必须拥有公网 IP,且中途没有任何 NAT 和防火墙。相比之下,PASV模式把所有连接压力都放在服务器侧,只要服务器按被动端口范围开放端口,客户端不管在什么网络环境里都能连上。

3. 完整实操:从安装到跑通FTP服务

3.1 系统环境与前提检查

下面这套流程以 CentOS 7.9 + vsftpd 为例。我个人经常在阿里云 ECS 上这么干,其他发行版(Ubuntu / Debian)差异不大,只是防火墙命令略有区别。

先确认系统版本和是否已安装 vsftpd:

cat /etc/redhat-release rpm -qa | grep vsftpd

如果没有安装,直接装:

yum install -y vsftpd

同时建议装一个 lftp 或 ftp 客户端用于本机验证。云服务器上默认可能没有 FTP 客户端,也可以用yum install -y ftp装上。

3.2 固定被动端口范围

打开/etc/vsftpd/vsftpd.conf,直接修改或追加以下内容。我个人习惯把跟被动模式相关的配置集中在文件末尾,方便日后排查:

# 允许本地用户登录 local_enable=YES write_enable=YES local_umask=022 # 主动模式允许但从 20 端口发起 connect_from_port_20=YES # 被动模式端口范围固定为 30000-30010 pasv_enable=YES pasv_min_port=30000 pasv_max_port=30010 pasv_address=<你的云服务器公网IP> # 指定被动模式下返回给客户端的IP pasv_addr_resolve=YES

我把pasv_address叫做“公网IP开关”,因为它直接影响227 Entering Passive Mode (49,xxx,xxx,xxx,xxx,xxx)这行响应里返回的 IP 地址。如果不填,vsftpd 会拿网卡上的私网 IP 来回应客户端。在阿里云这种典型的环境里,ECS 内网 IP 是 172.16.x.x 或 192.168.x.x,客户端拿到这个地址根本连不上。

注意:如果服务器做了公网 IP 映射(比如经典网络里的公网 IP 映射到私网 IP),pasv_address必须填公网 IP。如果是同一台 ECS 上绑定了弹性公网 IP,也填公网 IP。

另外,如果你的 IP 是动态的(极少数情况),可以把pasv_addr_resolve=YES打开,然后pasv_address填一个域名。这样每次解析域名就能拿到最新 IP,但在阿里云固定公网 IP 的场景下,直接填 IP 更省事。

3.3 创建FTP用户并限制目录

如果直接用 root 登录 FTP,vsftpd 会拒绝(默认配置里root在/etc/vsftpd/user_list或/etc/vsftpd/ftpusers里)。为了安全,我通常会单独建一个系统用户,比如叫ftpuser:

useradd -d /data/ftp -s /sbin/nologin ftpuser mkdir -p /data/ftp chown -R ftpuser:ftpuser /data/ftp passwd ftpuser

-s /sbin/nologin表示这个用户不能登录 shell,只能用于 FTP 访问,兼顾了安全性。之后你还可以在 vsftpd.conf 里加上这几行,把用户限制在自己的家目录里,避免他跑到系统其他目录去:

chroot_local_user=YES allow_writeable_chroot=YES

如果不加allow_writeable_chroot=YES,有些版本会因为你把/data/ftp设置为用户家目录且目录可写而直接拒绝登录,并报500 OOPS: vsftpd: refusing to run with writable root inside chroot()。这个坑在 CentOS 7 上很常见,很多新手会跑来问为什么登录直接被拒,其实就是少了这一行。

3.4 安全组规则配置

到阿里云控制台,找到你的 ECS 实例,进入“安全组”,添加入方向规则:

端口范围协议授权对象用途
21TCP0.0.0.0/0FTP 控制连接
20TCP0.0.0.0/0主动模式数据连接(可选)
30000-30010TCP0.0.0.0/0被动模式数据连接

我见过有人只放行 21 和一个被动端口,结果文件传不上去。FTP 目录列表和文件传输都会使用数据连接,如果被动端口只有一个,多个传输任务同时进行时,第二个任务会因为没有可用端口而失败。所以固定 10 个左右的端口范围是最稳妥的,对日常使用完全够用。

授权对象0.0.0.0/0表示允许所有 IP 访问。如果要求更安全,可以填你本地的出口公网 IP。但要注意,出口 IP 会动态变化,一旦变了就会把自己挡在外面。

3.5 系统防火墙放行

CentOS 7 默认用 firewalld,操作如下:

firewall-cmd --permanent --add-port=21/tcp firewall-cmd --permanent --add-port=20/tcp firewall-cmd --permanent --add-port=30000-30010/tcp firewall-cmd --reload

如果用的是 iptables 管理,核心概念是一样的,只是命令不同:

iptables -I INPUT -p tcp --dport 21 -j ACCEPT iptables -I INPUT -p tcp --dport 20 -j ACCEPT iptables -I INPUT -p tcp --dport 30000:30010 -j ACCEPT

别忘了保存规则。否则服务器重启后,这些 iptables 规则就没了。

这里有个细节:如果你既开了 firewalld 又装了 iptables-services,两者管理的是同一套规则表?其实不是,firewalld 底层虽然也用 netfilter,但它有自己的一套规则管理方式。建议只留一个防火墙服务,两个都开容易互相打架,排查时非常痛苦。

3.6 加载FTP连接跟踪模块

这一步是针对主动模式和被动模式都适用的一层保障。Linux 内核的nf_conntrack_ftp模块能够让 conntrack 正确识别 FTP 数据连接。

modprobe nf_conntrack_ftp

想让它在系统重启后自动加载,可以写到/etc/modules-load.d/ftp.conf里,内容就一行nf_conntrack_ftp。

为什么需要这步?因为防火墙在处理状态化连接时,会跟踪每个连接的状态。FTP 的数据连接新建方向和命令通道不一致,conntrack 如果不认识这个协议,数据包建立的新连接就会被防火墙规则拦下。加载这个模块后,防火墙能识别出这是某个 FTP 会话的数据连接,自动放行。

实测效果很明显:只配了安全组和 firewalld,但不加载nf_conntrack_ftp,主动模式照样可能 425。加载之后,主动模式在某些受限场景下也能正常工作(前提是你本地允许外网主动连接)。

3.7 启动服务并验证

配置完成后执行:

systemctl start vsftpd systemctl enable vsftpd

然后看服务状态:

systemctl status vsftpd ss -tlnp | grep -E '21|3000'

看到 21 端口在监听,30000-30010 端口在监听(vsftpd 会在收到 PASV 请求时动态监听其中某个端口,所以这里可能只看到 21 端口一直存在),基本就绪。

用客户端连一次,注意这次要切换到被动模式。命令行ftp工具默认可能是主动模式,你可以在ftp>提示符下手动输入passive或pwd(部分系统里passive命令不可用,可以输pass切换,不同版本有差异)。更省事的办法是直接用lftp:

lftp ftpuser@49.xxx.xxx.xxx -e "set ftp:passive-mode yes; ls; quit"

如果目录列表正常输出,说明被动模式和端口放行都已经生效。你也可以顺手试一下主动模式:

lftp ftpuser@49.xxx.xxx.xxx -e "set ftp:passive-mode no; ls; quit"

在云服务器场景下,后面的主动模式大概率仍然失败,但没关系,我们跑通被动模式就达到目的了。强烈建议日常使用全部被动模式。

4. 常见问题速查与避坑实录

4.1 PASV地址返回内网IP,客户端死活连不上

现象:登录没问题,ls也能触发,但响应是227 Entering Passive Mode (172,16,0,10,117,44),紧接着425 Failed to establish connection.

原因:客户端拿到的是 ECS 内网 IP,比如 172.16.0.10。这个地址在公网路由不到,客户端去连接自然失败。

解决:在 vsftpd.conf 里设置pasv_address=为 ECS 公网 IP。设置完重启systemctl restart vsftpd再试。注意,不要在配置里同时设置pasv_address和pasv_addr_resolve=YES却没提供域名,那样 vsftpd 会尝试解析一个空字符串,反而出错。

4.2 “Consider using PASV”提示很刺眼但无害

现象:客户端输出200 PORT command successful. Consider using PASV.然后就没有然后了,有些客户端会卡住。

原因:这句提示只是服务器在“好心”提醒你:主动模式可能不通,试试被动模式。如果你用的是 FileZilla,默认就是被动模式,通常不会出现这句。出现这句说明你的客户端配置成了主动模式,或自动退回到了主动模式。

排查顺序:先在客户端把传输模式强制设为“被动”。FileZilla 在“设置 -> 传输 -> FTP”里的“被动模式”勾上;命令行客户端切换方式见上文。如果切了被动模式还是 425,再看227响应里返回的 IP 和端口是否可访问——用telnet <公网IP> 30000测一下端口通不通。

4.3 端口范围开得特别大但依然失败

现象:安全组放行了 1024-65535,防火墙也放行了,被动模式还是连不上。

原因:端口放行范围太广不会导致失败,但可能有另一个坑——云厂商安全组规则有上限,或者你放行规则写错了协议类型(比如填成了 UDP 而不是 TCP)。另外,ECS 实例如果绑定了多个网卡,vsftpd 可能默认监听在错误的网卡上,导致公网流量进不来。

排查思路:先用ss -tlnp | grep vsftpd确认监听地址是 0.0.0.0 还是网卡地址;再用控制台的“安全组规则”页面核对协议和端口范围;最后在另一台机器上telnet 公网IP 30000验证端口连通性。

4.4 FileZilla连上了但列目录卡死

现象:输入账号密码后,状态栏显示Listing /...,然后一直转圈,最后超时。

原因:目录列表也是一个数据连接过程。FileZilla 默认采用被动模式,但如果你之前在某处把模式切成了主动,也会遇到这个问题。另一个常见因素是本地或服务器侧的代理干预了 FTP 流量。

处理:打开“站点管理器”,选中你的站点,“传输设置”里的“被动模式”确保选中。同时确认 vsftpd 配置里pasv_address是公网 IP,pasv_min_port/pasv_max_port与实际放行端口一致。

4.5 明明重启vsftpd了却还是旧配置

现象:改了配置、重启了服务,行为还是老样子。

原因:配置文件写错位置。有些教程会让人在/etc/vsftpd/vsftpd_user_conf或/etc/vsftpd/conf.d/下加配置片段,如果你的版本没有加载这个目录,配置就不会生效。

验证:执行vsftpd -olisten=YES这种参数只是在本次启动时生效,不够直观。更推荐用grep -v '^#' /etc/vsftpd/vsftpd.conf | grep -v '^$'把所有有效配置项列出来,检查pasv_min_port等是否真的在里面。如果配置被文件内的重复项覆盖(比如前面写了一个值后面又写了一个),最终生效的是靠后的那个值。

4.6 上传大文件时中途断开

现象:传小文件没问题,一传几百 MB 的包就断。

原因:可能是运营商或云平台的空闲连接超时把连接断了;也可能是被动端口只有一个,传输过程中另一个连接请求抢占端口。更常见的原因是,客户端和服务器之间的 NAT 会话超时比 FTP 数据连接的静默期更短。

建议:把被动端口范围设成 10 个以上,上传时给 FileZilla 启用“保持连接活跃”,或者用lftp的set net:timeout 30提高容忍度。

4.7 多用户场景下的隔离与权限

如果你给多个同事各开一个 FTP 账号,建议每个用户单独设置目录:

useradd -d /data/ftp/user1 -s /sbin/nologin user1 useradd -d /data/ftp/user2 -s /sbin/nologin user2 mkdir -p /data/ftp/user1 /data/ftp/user2 chown -R user1:user1 /data/ftp/user1 chown -R user2:user2 /data/ftp/user2

然后保持chroot_local_user=YES,每个用户就只能在/data/ftp/user1、/data/ftp/user2里活动了。

4.8 安全加固:就算跑通了也别裸奔

我见过不少教程,讲完systemctl start vsftpd就结束了。但 FTP 本身就是明文协议,账号密码在网络上裸奔,所以至少在云服务器层面做几件小事:

  1. 限制可以登录 FTP 的用户,在/etc/vsftpd/user_list里把不想开放的用户名写进去;
  2. 设置max_clients=10限制并发连接数;
  3. 用vsftpd自带的deny_email_enable或tcp_wrappers做访问源限制;
  4. 如果条件允许,优先考虑 SFTP,SSH 自带的子系统就能做文件传输,不用额外开 FTP 端口,安全性高很多。

这次遇到 425 报错,回头看其实是PORT主动模式在云环境里走不通,服务端友好地提醒你换PASV,而你——包括当年的我——根本没看懂这句提醒的含义。配好被动模式、固定端口范围、放行安全组和系统防火墙,再给pasv_address填上公网 IP,这个问题基本就消失了。

我在实际配置里最后踩的一次坑,是在安全组里漏放了 30000-30010 段的某个小尾巴,当时227返回的端口是 30005,我只放行了 30000-30004,日志里反复出现Failed to establish connection。所以建议忘掉单端口思维——FTP 天然是多端口协作的协议,把端口段当做一个整体来管理,思路会清晰很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询