ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

FTP连接失败排查:拒绝连接与没有到主机的路由分层定位

FTP连接失败排查:拒绝连接与没有到主机的路由分层定位 FTP 这个东西说起来老但真到要用的场合一点不含糊——老系统的对账文件、设备日志回传、第三方接口的批量数据交换很多还压在它身上。而一旦连不上报出来的那两句话往往只有两种形态ftp connect: 拒绝连接和ftp connect: 没有到主机的路由。前者是 TCP 层被人当面关上了门后者是网络层压根没找到门在哪。这两种报错看起来都像“连不上”但排查路径几乎是两条不同的路混着查只会把自己绕进去。这篇内容面向的是正在被 FTP 连接问题卡住的人不管是刚接手运维的新手还是写了几年脚本、被客户一句“你们 FTP 连不上”怼回来的开发。下面我会把这两类报错的底层成因拆开讲清楚再给出一套可以照着敲命令的分层排查流程最后附上被动模式、防火墙、云上安全组这些实际最容易翻车的环节。文中涉及的系统和配置均按通用发行版描述具体路径以你自己环境为准。1. 先搞清楚两种报错到底差在哪很多人排查 FTP 的第一步是打开客户端反复重连看运气。这个动作除了消耗耐心没有别的产出。真正该做的第一件事是把这两句报错翻译成网络分层里的具体位置。它们对应的不是同一个层也不是同一类故障。1.1 拒绝连接TCP 层收到的那个 RST 包拒绝连接Connection refused在协议层面的含义非常明确客户端发出了 SYN对端回了一个 RST。这说明什么说明数据包已经成功到达了目标主机路由是通的目标主机的内核也正常处理了这个包只是内核告诉客户端“这个端口上没有任何进程在等你的连接”于是回了拒绝。这条链路里路由器、交换机、中间网络设备全都是好的问题百分之百出在目标主机这一侧的应用层或者主机防火墙层。你可以把它理解成地址找对了楼也进去了前台告诉你“这个房间没人”。具体到 FTP21 端口被拒绝最常见的几个原因按出现频率排大概是FTP 服务进程根本没起来或者起来之后崩了服务起来了但只监听了127.0.0.1外部从公网或内网其它机器连进来就等不到主机防火墙用了REJECT --reject-with tcp-reset这类策略主动回 RST端口写错了客户端连 21服务端改成了 2121或者中间做了端口映射但映射规则没生效端口被别的进程占了FTP 启动失败表面上像是没开。注意最后一条特别有迷惑性。systemctl status显示 active但实际绑定失败了这种情况在配置改过端口、或者机器上跑了两套同类服务时很常见。1.2 没有到主机的路由网络层就已经断了没有到主机的路由No route to host是另一回事。它通常意味着客户端的协议栈在发包阶段就没有找到可达路径或者是中途收到了 ICMP 的不可达消息。跟“拒绝连接”比起来它更靠下、更靠前。典型场景有这么几类。第一类是客户端本机的路由表里没有到目标网段的条目也没有默认网关包发不出去。第二类是目标主机不在同一个二层网络中间网关不认识这个网段。第三类是防火墙策略把包丢了并且回了一个 ICMP host prohibited客户端就会把它解释成“没有到主机的路由”。第四类是 ARP 解析失败同网段内目标主机没响应 ARP 请求内核报 host unreachable。这里有个很关键的认知点没有到主机的路由不一定真的是路由问题。如果防火墙用REJECT --reject-with icmp-host-prohibited客户端收到的就是 ICMP 类型 3 代码 10表现和真的路由不通几乎一模一样。我在实际排查里遇到过好几次最后发现是目标机上的防火墙规则顺序写反了把允许规则放在了拒绝规则后面。而如果是DROP策略客户端那边通常表现为连接一直挂着最后超时而不是立刻报错。所以“立刻报错”和“转圈到超时”是区分 REJECT 和 DROP 的一个很实用的手感。1.3 一张表分清两类故障的边界对比项拒绝连接没有到主机的路由报错层级传输层TCP网络层IP/ICMP报文特征收到 RST收到 ICMP 不可达或本机路由失败目标主机是否可达可达内核正常响应可能不可达也可能被策略伪装成不可达服务是否在监听没监听或监听地址不对与服务监听状态基本无关常见原因服务未启动、绑 127.0.0.1、防火墙 REJECT路由缺失、网关错误、防火墙 ICMP REJECT、网段隔离排查起点目标机ss -lntp客户端ip route与ping把这张表记在心里后面所有动作都是往下钻。拿反了方向就会出现“明明防火墙全放开了还是连不上”这种僵局因为问题根本不在防火墙的策略内容上而在包有没有到。2. 排查前的准备把“分层”这件事落到命令行上分层排查不是一句口号它得变成一条固定顺序的命令清单。顺序对了一次就能把范围砍掉一半顺序乱了改了一堆配置问题还在原地。2.1 排查顺序为什么必须是自下而上假如 FTP 连不上我先看服务状态还是先 ping答案必须是先 ping。理由很直白如果网络层都不通你去看/etc/vsftpd/vsftpd.conf里的每一个参数都是白费。反过来如果 ping 得通、端口探测被拒那再去查服务配置才有意义。我固定的排查顺序是四步一步不跳链路与地址确认本机网卡有没有地址、掩码对不对、网关通不通网络可达ping目标 IP看是超时、不可达还是通端口可达telnet或nc探 21 端口看是拒绝还是超时应用状态服务进程、监听地址、配置文件、日志。这四步跑完故障基本已经被锁死在某一层了。下面每一步我会展开说但顺序千万别换来换去。2.2 手上要备好的几把工具工欲善其事工具先装齐。基础镜像里常常缺telnet和nc很多人到现场才发现敲不出来。ping基础连通性几乎所有系统自带ip route/route -n看路由表和默认网关telnet或nc -vz探测端口判断拒绝还是超时traceroute或mtr看路径在哪一跳断掉ss -lntp看本机监听端口和对应进程tcpdump抓包看 SYN 有没有发出去、有没有回包这是终极大招firewall-cmd --list-all/iptables -L -n -v看防火墙实际生效规则。提示在某些精简系统上telnet客户端和nc默认都没装。提前准备好比到了现场临时找包要省太多时间。2.3 记录基线信息别一上来就改配置我踩过最亏的一次坑是接手一台别人配过的机器一上来就怀疑防火墙结果把本来正确的规则改坏了最后发现只是 FTP 配置里listenNO。从那以后我给自己定了个规矩动手之前先把现场信息原样记录一份。至少要记下这些目标机的ip addr、ip route、ss -lntp | grep 21、防火墙规则全量输出、FTP 服务状态与最近 50 行日志。客户端这边记下ip route和ping结果。这些信息除了帮你定位还有一个作用——出问题时能快速回滚不至于越修越乱。2.4 用 tcpdump 看清 SYN 的去向这一步很多人觉得高级其实它是最朴素的判断手段。在服务端执行抓包同时在客户端发起连接# 服务端抓 21 端口的包 tcpdump -i any -nn port 21 -c 20如果抓到了客户端来的 SYN但服务端没回 SYN-ACK那就是本机没监听或者防火墙拦了如果回了 RST那就是端口没人等对应“拒绝连接”如果压根没抓到 SYN问题在中间网络或者路由对应“没有到主机的路由”这一类。一次抓包能省掉半小时的猜测。3. 拒绝连接Connection refused的逐层拆解与修复确定是“拒绝连接”之后排查范围就缩小到目标机内部了。下面这四步我基本按顺序来绝大多数情况在第二步就能定位。3.1 第一步确认服务到底起没起先在目标机上执行systemctl status vsftpd看两个东西Active那一行是active (running)还是failed以及下面日志里有没有Failed to start之类的内容。如果状态是 failed直接看日志journalctl -u vsftpd -n 80 --no-pager日志里常见的是配置文件语法错误、端口被占用、权限不足。比如500 OOPS: could not bind listening IPv4 socket基本就是端口被占了或者配置冲突。如果状态是 running也别高兴太早。继续看监听ss -lntp | grep -E :(21|ftp)正常应该看到类似LISTEN 0 32 0.0.0.0:21 0.0.0.0:* users:((vsftpd,pid1234,fd3))的输出。如果这里是127.0.0.1:21那就是下一个问题了。3.2 第二步确认监听地址绑对没绑对ss输出里那个0.0.0.0:21和127.0.0.1:21的区别决定了外部能不能连进来。0.0.0.0表示监听所有 IPv4 地址127.0.0.1表示只听本机回环。造成只听回环的原因在 vsftpd 上通常是这两行配置listenYES listen_address127.0.0.1listen_address一旦被指定成回环地址外部连接必然被拒。改法是把这一行注释掉或者明确写成机器的业务 IPlistenYES listen_ipv6NO # listen_address127.0.0.1改完记得systemctl restart vsftpd然后再用ss确认一次。这里有个细节listenYES和listen_ipv6YES不能同时打开否则 vsftpd 启动会直接报错退出而systemctl status有时候显示得很含糊容易误判成服务正常。3.3 第三步防火墙是 REJECT 还是 DROP监听没问题端口也对外了那就要看防火墙。先确认防火墙状态# firewalld 环境 firewall-cmd --state firewall-cmd --list-all # iptables 环境 iptables -L INPUT -n -v --line-numbers判断的关键在于规则里用的是REJECT还是DROP。REJECT会往客户端回一个消息DROP是直接丢弃、不回任何东西。所以客户端立刻报“拒绝连接”多半是REJECT --reject-with tcp-reset客户端一直转圈到超时多半是DROP客户端报“没有到主机的路由”可能是REJECT --reject-with icmp-host-prohibited。放行 21 端口的写法firewalld 环境下firewall-cmd --permanent --add-serviceftp firewall-cmd --reload或者按端口放行firewall-cmd --permanent --add-port21/tcp firewall-cmd --reloadiptables 环境下iptables -I INPUT -p tcp --dport 21 -j ACCEPT注意-I是插到链首-A是追加到链尾。如果原有规则里有前置的拒绝规则-A加在后面的允许规则根本不会被匹配到。这就是我在第 1 节提到的“规则顺序写反”的典型后果。注意改 iptables 规则前先确认有没有持久化机制否则重启后规则全丢第二天又是同一个故障。iptables-save配合netfilter-persistent或iptables-services是常见做法。3.4 第四步云主机上的安全组与端口映射如果目标机跑在云上主机内部防火墙全放开了还是拒绝连接那就要往上找一层。云平台通常有独立于操作系统的网络访问控制一般叫安全组或者网络 ACL它在实例外面生效你在机器里iptables -L是看不到的。排查方式是登录云控制台找到该实例绑定的安全组看入方向规则里有没有放行 21 端口源地址范围是否覆盖了你的客户端 IP。这里最常见的两个坑一是安全组只放行了内网地址而你从公网连二是规则的优先级被更靠前的拒绝规则盖掉了。还有一种情况是中间做了端口映射比如公网 2121 映射到内网 21。这时候客户端必须连 2121连 21 自然是被拒。同时被动模式还要额外处理数据端口这个在第 5 节展开。3.5 验证与回归测试改完不要只在自己机器上试一次就收工。我的验证清单是这样的本机telnet 127.0.0.1 21确认服务活着同网段另一台机器telnet 内网IP 21确认内网可达客户端所在网络telnet 公网IP 21确认外部可达用真实 FTP 客户端登录一次做一次ls和一次put重启一次服务再重复第 4 步确认配置持久化没问题。第 5 步很多人省掉结果下次机器重启故障复现。配置这东西不重启验证一遍就等于没改。4. 没有到主机的路由No route to host的逐层拆解与修复这类报错的排查思路和上一节完全不同。核心是回答一个问题包到底有没有离开客户端以及离开之后走到了哪一跳。4.1 先 ping 一下但 ping 不通不代表服务有问题第一步永远是ping 目标IP。但要注意ping不通有三种可能含义完全不同Destination Host Unreachable本机或中间设备明确告诉你到不了路由或 ARP 有问题Request timeout包发出去了没有任何回应可能是对方禁 ping也可能是防火墙 DROPName or service not known这是域名解析问题压根还没到网络层。关键认知是服务器禁 ping 是很常见的加固手段ping 不通不代表 FTP 连不上。所以 ping 只能作为参考不能作为结论。真正有决定性的还是端口探测nc -vz -w 3 目标IP 21或者telnet 目标IP 21看返回是Connection refused、Connection timed out还是No route to host。这三者的含义和排查方向完全不同前面表格里已经对上了。4.2 路由表与网关检查确认是本机路由问题时先看路由表ip route输出里要关注两件事有没有到目标网段的具体路由以及default via后面那个网关地址是不是当前网段的合法地址。如果默认网关写错了比如网段是192.168.10.0/24网关却写成了192.168.20.1那所有跨网段的包都发不出去。再看本机地址和掩码ip addr掩码写错是很容易被忽略的坑。把/24写成/16本机会认为整个192.168.0.0/16都在同一个二层网络里于是对本来需要经过网关的地址直接发 ARP 请求结果自然是 host unreachable。这种错误在手工配 IP 的机器上出现频率相当高。4.3 防火墙 DROP 策略的典型表现前面说过DROP通常表现为超时而不是“没有到主机的路由”但如果规则用的是REJECT --reject-with icmp-host-prohibited客户端收到的就是 ICMP 类型 3 代码 10报错文案和真正的路由不通一模一样。判断方法是看目标机上的规则iptables -L INPUT -n -v --line-numbers如果看到类似这样的规则REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited并且它排在允许 21 端口的规则前面那故障原因就找到了。处理方式是调整顺序把允许规则插到它前面iptables -I INPUT 1 -p tcp --dport 21 -j ACCEPT-I INPUT 1里的1表示插到第一条。这个数字很关键插错位置等于没插。4.4 网段隔离、VLAN 与云上子网如果客户端和服务端不在同一个二层网络中间又有多层网络设备那就要考虑策略隔离了。企业内网常见的做法是把办公网、服务器网、测试网分到不同 VLANVLAN 之间的访问由三层设备上的 ACL 控制。ACL 默认拒绝的时候表现出来就是“没有到主机的路由”。云上的情况类似但对象换成了子网和路由表。两个子网之间如果没有对等连接或者路由条目包就出不去。这时候在实例内部怎么改防火墙都没用得去网络配置层面加路由。排查手段是traceroutetraceroute -n -T -p 21 目标IP-T表示用 TCP 探测-p 21指定端口。看输出在哪一跳开始出现* * *就能大致判断阻断点在哪一层设备上。如果第一跳就是星号问题在本机或网关如果中间几跳正常、最后断了问题在靠近目标的一侧。4.5 复现验证方法改完路由或者 ACL 之后验证要覆盖两个方向。正向验证是从客户端 ping 和探端口反向验证是从服务端 ping 客户端同时看服务端有没有收到 SYN# 服务端抓包确认有 SYN 进来 tcpdump -i any -nn tcp port 21 and tcp[tcpflags] tcp-syn ! 0抓到 SYN 说明网络通了剩下的就是应用层的事抓不到说明包还在路上被拦着。这个判定比反复改配置靠谱得多。5. 连上了却传不了文件被动模式那些坑端口通了、登录成功了、ls也出来了结果put一个文件卡死不动——这是 FTP 最经典的“第二步故障”。它跟前面两类报错不是一回事但对使用者的感受是一样的连不上。5.1 主动模式与被动模式的本质区别FTP 用两条连接一条控制连接走 21 端口一条数据连接传文件。控制连接永远是客户端主动连服务端这个没问题。数据连接的方向取决于模式。主动模式PORT下服务端从自己的 20 端口主动连客户端的一个随机端口。问题在于客户端通常在 NAT 或者防火墙后面服务端根本连不进去于是卡住。被动模式PASV下客户端向服务端要一个端口服务端返回一个随机高位端口客户端主动去连这个端口。这个方向对客户端友好所以现代客户端默认都用被动模式。但被动模式又带来一个新问题服务端返回的那个端口是随机的防火墙如果只放行了 21数据连接必然被拦。表现出来就是登录正常、列目录正常一传文件就超时。5.2 pasv_min_port 与 pasv_max_port 的配置解决办法是把被动模式的端口范围固定下来然后在防火墙上放行这一段。vsftpd 的配置是这样pasv_enableYES pasv_min_port30000 pasv_max_port30100范围选多大按并发连接数估。每个数据传输占一个端口理论最大并发数等于端口数量。一般内部使用 100 个端口足够50 个并发以内完全扛得住。如果用户量大可以放到 500 个。如果服务端在 NAT 后面还要加一行pasv_address告诉客户端应该连哪个公网地址pasv_address公网IP这一行不加服务端会把内网地址返回给客户端客户端拿着一个内网 IP 去连自然连不上。这是我见过最多的被动模式故障原因没有之一。5.3 防火墙放行数据端口配置改完防火墙同步放行firewall-cmd --permanent --add-port30000-30100/tcp firewall-cmd --reload云平台的安全组也要同步加一条规则端口范围写30000-30100协议 TCP。这一步经常被漏掉因为在机器内部折腾半天都正常一出公网就废。还有 SELinux 这一层。如果系统开了 SELinux 且策略比较严FTP 读写家目录会被拦getenforce setsebool -P ftpd_full_access on-P表示持久化不加的话重启就失效。改完用getsebool ftpd_full_access确认一下状态是 on。6. 常见问题速查表与避坑经验前面几节讲的是原理和流程这一节讲的是我这些年实际踩出来的经验。有些坑在文档里不会写但遇到了能让人折腾一整天。6.1 排查速查表现象最可能的原因快速验证处理动作立刻报拒绝连接服务未启动 / 绑回环ss -lntp | grep 21启动服务改listen_address立刻报拒绝连接服务正常防火墙 REJECTiptables -L -n -v放行 21注意规则顺序转圈后超时防火墙 DROPtcpdump看有无回包检查 DROP 规则与安全组报没有到主机的路由路由缺失或 ICMP REJECTip route、traceroute补路由或调整 REJECT 类型ping 通但端口不通服务未监听或端口错误nc -vz探端口核对端口与监听地址登录成功但ls卡住被动模式端口被拦客户端开 PASV 调试日志固定 pasv 端口段并放行登录成功但put失败目录权限或 SELinuxls -ld、getenforce改权限或开ftpd_full_access重启后故障复现配置未持久化重启再测一遍iptables-save、--permanent6.2 几个我踩过的坑坑一systemctl status是 active但端口没起来。有一次配置文件里listen和listen_ipv6同时为 YESvsftpd 启动后立刻退出但 systemd 的重启策略让它反复拉起status看到的永远是 active。真正定位是靠journalctl里的重复报错。所以看状态一定要配合看日志和看监听。坑二改完 iptables 忘了持久化。这个坑的杀伤力在于它有延迟——当天一切正常第二天机器重启故障原样复现而且看起来像是“莫名其妙又坏了”。现在我的习惯是改完立刻iptables-save /etc/sysconfig/iptablesfirewalld 环境则确保每条命令都带--permanent。坑三客户端防火墙也拦。一直在服务端折腾最后发现是客户端本机的出站规则拦了高位端口。被动模式下客户端要连服务端的 30000 以上端口有些终端安全软件默认只放行常用端口。这个排查起来很快在客户端抓个包就一目了然。坑四NAT 环境下的pasv_address忘了配。表现是内网用户全正常外网用户一律传不了文件。因为服务端返回的是内网地址外网客户端拿着192.168.x.x去连当然连不上。这个问题的隐蔽性在于日志里看不出任何异常只能靠抓包或者看客户端返回的 PASV 响应内容。坑五账号密码对了但登录被拒。这不是网络问题是认证层。常见原因是ftpusers和user_list文件里默认拒绝了一批系统账户或者chroot_local_userYES配合家目录可写导致 vsftpd 拒绝登录。日志在/var/log/secure里搜vsftpd关键字能直接看到原因。6.3 长期运维上的一点建议FTP 这套东西本身没有健康检查机制出问题往往是被动发现的。我的做法是在监控里加两个探测点一个是 21 端口的 TCP 连通性探测另一个是真实的登录加列目录操作频率五分钟一次。前者能发现服务挂了后者能发现被动模式配置被改坏了。另外配置变更一定要留记录。FTP 的配置文件不长但每一项都影响面很大尤其是被动模式那几行。我见过一次事故是有人为了“优化性能”把pasv_min_port和pasv_max_port注释掉了结果防火墙规则对应的端口段全部失效外网用户全部传不了文件而内网测试一切正常直到客户投诉才发现。最后再分享一个小技巧排查 FTP 问题时尽量用命令行客户端ftp或lftp而不是图形客户端。命令行会原样输出服务端的响应码比如227 Entering Passive Mode (192,168,1,10,117,40)这里面的数字就是服务端返回的被动端口117*2564030000一眼就能看出它返回的是不是内网地址、端口在不在放行范围内。图形客户端把这些信息全藏起来了排查时等于蒙着眼睛。我在实际处理这类问题的体会是FTP 报错文案的区分度其实很高拒绝连接和没有到主机的路由已经把排查方向指得很明确难的不是判断而是忍住不跳过验证步骤直接改配置。按链路、网络、端口、应用这四层老老实实走一遍绝大多数问题在十分钟内就能定位到具体那一行配置上。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表