
FTP 這個東西說起來老但真到要用的場合一點不含糊——老系統(tǒng)的對賬文件、設備日志回傳、第三方接口的批量數據交換很多還壓在它身上。而一旦連不上報出來的那兩句話往往只有兩種形態(tài)ftp connect: 拒絕連接和ftp connect: 沒有到主機的路由。前者是 TCP 層被人當面關上了門后者是網絡層壓根沒找到門在哪。這兩種報錯看起來都像“連不上”但排查路徑幾乎是兩條不同的路混著查只會把自己繞進去。這篇內容面向的是正在被 FTP 連接問題卡住的人不管是剛接手運維的新手還是寫了幾年腳本、被客戶一句“你們 FTP 連不上”懟回來的開發(fā)。下面我會把這兩類報錯的底層成因拆開講清楚再給出一套可以照著敲命令的分層排查流程最后附上被動模式、防火墻、云上安全組這些實際最容易翻車的環(huán)節(jié)。文中涉及的系統(tǒng)和配置均按通用發(fā)行版描述具體路徑以你自己環(huán)境為準。1. 先搞清楚兩種報錯到底差在哪很多人排查 FTP 的第一步是打開客戶端反復重連看運氣。這個動作除了消耗耐心沒有別的產出。真正該做的第一件事是把這兩句報錯翻譯成網絡分層里的具體位置。它們對應的不是同一個層也不是同一類故障。1.1 拒絕連接TCP 層收到的那個 RST 包拒絕連接Connection refused在協議層面的含義非常明確客戶端發(fā)出了 SYN對端回了一個 RST。這說明什么說明數據包已經成功到達了目標主機路由是通的目標主機的內核也正常處理了這個包只是內核告訴客戶端“這個端口上沒有任何進程在等你的連接”于是回了拒絕。這條鏈路里路由器、交換機、中間網絡設備全都是好的問題百分之百出在目標主機這一側的應用層或者主機防火墻層。你可以把它理解成地址找對了樓也進去了前臺告訴你“這個房間沒人”。具體到 FTP21 端口被拒絕最常見的幾個原因按出現頻率排大概是FTP 服務進程根本沒起來或者起來之后崩了服務起來了但只監(jiān)聽了127.0.0.1外部從公網或內網其它機器連進來就等不到主機防火墻用了REJECT --reject-with tcp-reset這類策略主動回 RST端口寫錯了客戶端連 21服務端改成了 2121或者中間做了端口映射但映射規(guī)則沒生效端口被別的進程占了FTP 啟動失敗表面上像是沒開。注意最后一條特別有迷惑性。systemctl status顯示 active但實際綁定失敗了這種情況在配置改過端口、或者機器上跑了兩套同類服務時很常見。1.2 沒有到主機的路由網絡層就已經斷了沒有到主機的路由No route to host是另一回事。它通常意味著客戶端的協議棧在發(fā)包階段就沒有找到可達路徑或者是中途收到了 ICMP 的不可達消息。跟“拒絕連接”比起來它更靠下、更靠前。典型場景有這么幾類。第一類是客戶端本機的路由表里沒有到目標網段的條目也沒有默認網關包發(fā)不出去。第二類是目標主機不在同一個二層網絡中間網關不認識這個網段。第三類是防火墻策略把包丟了并且回了一個 ICMP host prohibited客戶端就會把它解釋成“沒有到主機的路由”。第四類是 ARP 解析失敗同網段內目標主機沒響應 ARP 請求內核報 host unreachable。這里有個很關鍵的認知點沒有到主機的路由不一定真的是路由問題。如果防火墻用REJECT --reject-with icmp-host-prohibited客戶端收到的就是 ICMP 類型 3 代碼 10表現和真的路由不通幾乎一模一樣。我在實際排查里遇到過好幾次最后發(fā)現是目標機上的防火墻規(guī)則順序寫反了把允許規(guī)則放在了拒絕規(guī)則后面。而如果是DROP策略客戶端那邊通常表現為連接一直掛著最后超時而不是立刻報錯。所以“立刻報錯”和“轉圈到超時”是區(qū)分 REJECT 和 DROP 的一個很實用的手感。1.3 一張表分清兩類故障的邊界對比項拒絕連接沒有到主機的路由報錯層級傳輸層TCP網絡層IP/ICMP報文特征收到 RST收到 ICMP 不可達或本機路由失敗目標主機是否可達可達內核正常響應可能不可達也可能被策略偽裝成不可達服務是否在監(jiān)聽沒監(jiān)聽或監(jiān)聽地址不對與服務監(jiān)聽狀態(tài)基本無關常見原因服務未啟動、綁 127.0.0.1、防火墻 REJECT路由缺失、網關錯誤、防火墻 ICMP REJECT、網段隔離排查起點目標機ss -lntp客戶端ip route與ping把這張表記在心里后面所有動作都是往下鉆。拿反了方向就會出現“明明防火墻全放開了還是連不上”這種僵局因為問題根本不在防火墻的策略內容上而在包有沒有到。2. 排查前的準備把“分層”這件事落到命令行上分層排查不是一句口號它得變成一條固定順序的命令清單。順序對了一次就能把范圍砍掉一半順序亂了改了一堆配置問題還在原地。2.1 排查順序為什么必須是自下而上假如 FTP 連不上我先看服務狀態(tài)還是先 ping答案必須是先 ping。理由很直白如果網絡層都不通你去看/etc/vsftpd/vsftpd.conf里的每一個參數都是白費。反過來如果 ping 得通、端口探測被拒那再去查服務配置才有意義。我固定的排查順序是四步一步不跳鏈路與地址確認本機網卡有沒有地址、掩碼對不對、網關通不通網絡可達ping目標 IP看是超時、不可達還是通端口可達telnet或nc探 21 端口看是拒絕還是超時應用狀態(tài)服務進程、監(jiān)聽地址、配置文件、日志。這四步跑完故障基本已經被鎖死在某一層了。下面每一步我會展開說但順序千萬別換來換去。2.2 手上要備好的幾把工具工欲善其事工具先裝齊?;A鏡像里常常缺telnet和nc很多人到現場才發(fā)現敲不出來。ping基礎連通性幾乎所有系統(tǒng)自帶ip route/route -n看路由表和默認網關telnet或nc -vz探測端口判斷拒絕還是超時traceroute或mtr看路徑在哪一跳斷掉ss -lntp看本機監(jiān)聽端口和對應進程tcpdump抓包看 SYN 有沒有發(fā)出去、有沒有回包這是終極大招firewall-cmd --list-all/iptables -L -n -v看防火墻實際生效規(guī)則。提示在某些精簡系統(tǒng)上telnet客戶端和nc默認都沒裝。提前準備好比到了現場臨時找包要省太多時間。2.3 記錄基線信息別一上來就改配置我踩過最虧的一次坑是接手一臺別人配過的機器一上來就懷疑防火墻結果把本來正確的規(guī)則改壞了最后發(fā)現只是 FTP 配置里listenNO。從那以后我給自己定了個規(guī)矩動手之前先把現場信息原樣記錄一份。至少要記下這些目標機的ip addr、ip route、ss -lntp | grep 21、防火墻規(guī)則全量輸出、FTP 服務狀態(tài)與最近 50 行日志??蛻舳诉@邊記下ip route和ping結果。這些信息除了幫你定位還有一個作用——出問題時能快速回滾不至于越修越亂。2.4 用 tcpdump 看清 SYN 的去向這一步很多人覺得高級其實它是最樸素的判斷手段。在服務端執(zhí)行抓包同時在客戶端發(fā)起連接# 服務端抓 21 端口的包 tcpdump -i any -nn port 21 -c 20如果抓到了客戶端來的 SYN但服務端沒回 SYN-ACK那就是本機沒監(jiān)聽或者防火墻攔了如果回了 RST那就是端口沒人等對應“拒絕連接”如果壓根沒抓到 SYN問題在中間網絡或者路由對應“沒有到主機的路由”這一類。一次抓包能省掉半小時的猜測。3. 拒絕連接Connection refused的逐層拆解與修復確定是“拒絕連接”之后排查范圍就縮小到目標機內部了。下面這四步我基本按順序來絕大多數情況在第二步就能定位。3.1 第一步確認服務到底起沒起先在目標機上執(zhí)行systemctl status vsftpd看兩個東西Active那一行是active (running)還是failed以及下面日志里有沒有Failed to start之類的內容。如果狀態(tài)是 failed直接看日志journalctl -u vsftpd -n 80 --no-pager日志里常見的是配置文件語法錯誤、端口被占用、權限不足。比如500 OOPS: could not bind listening IPv4 socket基本就是端口被占了或者配置沖突。如果狀態(tài)是 running也別高興太早。繼續(xù)看監(jiān)聽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 第二步確認監(jiān)聽地址綁對沒綁對ss輸出里那個0.0.0.0:21和127.0.0.1:21的區(qū)別決定了外部能不能連進來。0.0.0.0表示監(jiān)聽所有 IPv4 地址127.0.0.1表示只聽本機回環(huán)。造成只聽回環(huán)的原因在 vsftpd 上通常是這兩行配置listenYES listen_address127.0.0.1listen_address一旦被指定成回環(huán)地址外部連接必然被拒。改法是把這一行注釋掉或者明確寫成機器的業(yè)務 IPlistenYES listen_ipv6NO # listen_address127.0.0.1改完記得systemctl restart vsftpd然后再用ss確認一次。這里有個細節(jié)listenYES和listen_ipv6YES不能同時打開否則 vsftpd 啟動會直接報錯退出而systemctl status有時候顯示得很含糊容易誤判成服務正常。3.3 第三步防火墻是 REJECT 還是 DROP監(jiān)聽沒問題端口也對外了那就要看防火墻。先確認防火墻狀態(tài)# firewalld 環(huán)境 firewall-cmd --state firewall-cmd --list-all # iptables 環(huán)境 iptables -L INPUT -n -v --line-numbers判斷的關鍵在于規(guī)則里用的是REJECT還是DROP。REJECT會往客戶端回一個消息DROP是直接丟棄、不回任何東西。所以客戶端立刻報“拒絕連接”多半是REJECT --reject-with tcp-reset客戶端一直轉圈到超時多半是DROP客戶端報“沒有到主機的路由”可能是REJECT --reject-with icmp-host-prohibited。放行 21 端口的寫法firewalld 環(huán)境下firewall-cmd --permanent --add-serviceftp firewall-cmd --reload或者按端口放行firewall-cmd --permanent --add-port21/tcp firewall-cmd --reloadiptables 環(huán)境下iptables -I INPUT -p tcp --dport 21 -j ACCEPT注意-I是插到鏈首-A是追加到鏈尾。如果原有規(guī)則里有前置的拒絕規(guī)則-A加在后面的允許規(guī)則根本不會被匹配到。這就是我在第 1 節(jié)提到的“規(guī)則順序寫反”的典型后果。注意改 iptables 規(guī)則前先確認有沒有持久化機制否則重啟后規(guī)則全丟第二天又是同一個故障。iptables-save配合netfilter-persistent或iptables-services是常見做法。3.4 第四步云主機上的安全組與端口映射如果目標機跑在云上主機內部防火墻全放開了還是拒絕連接那就要往上找一層。云平臺通常有獨立于操作系統(tǒng)的網絡訪問控制一般叫安全組或者網絡 ACL它在實例外面生效你在機器里iptables -L是看不到的。排查方式是登錄云控制臺找到該實例綁定的安全組看入方向規(guī)則里有沒有放行 21 端口源地址范圍是否覆蓋了你的客戶端 IP。這里最常見的兩個坑一是安全組只放行了內網地址而你從公網連二是規(guī)則的優(yōu)先級被更靠前的拒絕規(guī)則蓋掉了。還有一種情況是中間做了端口映射比如公網 2121 映射到內網 21。這時候客戶端必須連 2121連 21 自然是被拒。同時被動模式還要額外處理數據端口這個在第 5 節(jié)展開。3.5 驗證與回歸測試改完不要只在自己機器上試一次就收工。我的驗證清單是這樣的本機telnet 127.0.0.1 21確認服務活著同網段另一臺機器telnet 內網IP 21確認內網可達客戶端所在網絡telnet 公網IP 21確認外部可達用真實 FTP 客戶端登錄一次做一次ls和一次put重啟一次服務再重復第 4 步確認配置持久化沒問題。第 5 步很多人省掉結果下次機器重啟故障復現。配置這東西不重啟驗證一遍就等于沒改。4. 沒有到主機的路由No route to host的逐層拆解與修復這類報錯的排查思路和上一節(jié)完全不同。核心是回答一個問題包到底有沒有離開客戶端以及離開之后走到了哪一跳。4.1 先 ping 一下但 ping 不通不代表服務有問題第一步永遠是ping 目標IP。但要注意ping不通有三種可能含義完全不同Destination Host Unreachable本機或中間設備明確告訴你到不了路由或 ARP 有問題Request timeout包發(fā)出去了沒有任何回應可能是對方禁 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那所有跨網段的包都發(fā)不出去。再看本機地址和掩碼ip addr掩碼寫錯是很容易被忽略的坑。把/24寫成/16本機會認為整個192.168.0.0/16都在同一個二層網絡里于是對本來需要經過網關的地址直接發(fā) ARP 請求結果自然是 host unreachable。這種錯誤在手工配 IP 的機器上出現頻率相當高。4.3 防火墻 DROP 策略的典型表現前面說過DROP通常表現為超時而不是“沒有到主機的路由”但如果規(guī)則用的是REJECT --reject-with icmp-host-prohibited客戶端收到的就是 ICMP 類型 3 代碼 10報錯文案和真正的路由不通一模一樣。判斷方法是看目標機上的規(guī)則iptables -L INPUT -n -v --line-numbers如果看到類似這樣的規(guī)則REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited并且它排在允許 21 端口的規(guī)則前面那故障原因就找到了。處理方式是調整順序把允許規(guī)則插到它前面iptables -I INPUT 1 -p tcp --dport 21 -j ACCEPT-I INPUT 1里的1表示插到第一條。這個數字很關鍵插錯位置等于沒插。4.4 網段隔離、VLAN 與云上子網如果客戶端和服務端不在同一個二層網絡中間又有多層網絡設備那就要考慮策略隔離了。企業(yè)內網常見的做法是把辦公網、服務器網、測試網分到不同 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 主動模式與被動模式的本質區(qū)別FTP 用兩條連接一條控制連接走 21 端口一條數據連接傳文件??刂七B接永遠是客戶端主動連服務端這個沒問題。數據連接的方向取決于模式。主動模式PORT下服務端從自己的 20 端口主動連客戶端的一個隨機端口。問題在于客戶端通常在 NAT 或者防火墻后面服務端根本連不進去于是卡住。被動模式PASV下客戶端向服務端要一個端口服務端返回一個隨機高位端口客戶端主動去連這個端口。這個方向對客戶端友好所以現代客戶端默認都用被動模式。但被動模式又帶來一個新問題服務端返回的那個端口是隨機的防火墻如果只放行了 21數據連接必然被攔。表現出來就是登錄正常、列目錄正常一傳文件就超時。5.2 pasv_min_port 與 pasv_max_port 的配置解決辦法是把被動模式的端口范圍固定下來然后在防火墻上放行這一段。vsftpd 的配置是這樣pasv_enableYES pasv_min_port30000 pasv_max_port30100范圍選多大按并發(fā)連接數估。每個數據傳輸占一個端口理論最大并發(fā)數等于端口數量。一般內部使用 100 個端口足夠50 個并發(fā)以內完全扛得住。如果用戶量大可以放到 500 個。如果服務端在 NAT 后面還要加一行pasv_address告訴客戶端應該連哪個公網地址pasv_address公網IP這一行不加服務端會把內網地址返回給客戶端客戶端拿著一個內網 IP 去連自然連不上。這是我見過最多的被動模式故障原因沒有之一。5.3 防火墻放行數據端口配置改完防火墻同步放行firewall-cmd --permanent --add-port30000-30100/tcp firewall-cmd --reload云平臺的安全組也要同步加一條規(guī)則端口范圍寫30000-30100協議 TCP。這一步經常被漏掉因為在機器內部折騰半天都正常一出公網就廢。還有 SELinux 這一層。如果系統(tǒng)開了 SELinux 且策略比較嚴FTP 讀寫家目錄會被攔getenforce setsebool -P ftpd_full_access on-P表示持久化不加的話重啟就失效。改完用getsebool ftpd_full_access確認一下狀態(tài)是 on。6. 常見問題速查表與避坑經驗前面幾節(jié)講的是原理和流程這一節(jié)講的是我這些年實際踩出來的經驗。有些坑在文檔里不會寫但遇到了能讓人折騰一整天。6.1 排查速查表現象最可能的原因快速驗證處理動作立刻報拒絕連接服務未啟動 / 綁回環(huán)ss -lntp | grep 21啟動服務改listen_address立刻報拒絕連接服務正常防火墻 REJECTiptables -L -n -v放行 21注意規(guī)則順序轉圈后超時防火墻 DROPtcpdump看有無回包檢查 DROP 規(guī)則與安全組報沒有到主機的路由路由缺失或 ICMP REJECTip route、traceroute補路由或調整 REJECT 類型ping 通但端口不通服務未監(jiān)聽或端口錯誤nc -vz探端口核對端口與監(jiān)聽地址登錄成功但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里的重復報錯。所以看狀態(tài)一定要配合看日志和看監(jiān)聽??佣耐?iptables 忘了持久化。這個坑的殺傷力在于它有延遲——當天一切正常第二天機器重啟故障原樣復現而且看起來像是“莫名其妙又壞了”?,F在我的習慣是改完立刻iptables-save /etc/sysconfig/iptablesfirewalld 環(huán)境則確保每條命令都帶--permanent??尤蛻舳朔阑饓σ矓r。一直在服務端折騰最后發(fā)現是客戶端本機的出站規(guī)則攔了高位端口。被動模式下客戶端要連服務端的 30000 以上端口有些終端安全軟件默認只放行常用端口。這個排查起來很快在客戶端抓個包就一目了然??铀腘AT 環(huán)境下的pasv_address忘了配。表現是內網用戶全正常外網用戶一律傳不了文件。因為服務端返回的是內網地址外網客戶端拿著192.168.x.x去連當然連不上。這個問題的隱蔽性在于日志里看不出任何異常只能靠抓包或者看客戶端返回的 PASV 響應內容??游遒~號密碼對了但登錄被拒。這不是網絡問題是認證層。常見原因是ftpusers和user_list文件里默認拒絕了一批系統(tǒng)賬戶或者chroot_local_userYES配合家目錄可寫導致 vsftpd 拒絕登錄。日志在/var/log/secure里搜vsftpd關鍵字能直接看到原因。6.3 長期運維上的一點建議FTP 這套東西本身沒有健康檢查機制出問題往往是被動發(fā)現的。我的做法是在監(jiān)控里加兩個探測點一個是 21 端口的 TCP 連通性探測另一個是真實的登錄加列目錄操作頻率五分鐘一次。前者能發(fā)現服務掛了后者能發(fā)現被動模式配置被改壞了。另外配置變更一定要留記錄。FTP 的配置文件不長但每一項都影響面很大尤其是被動模式那幾行。我見過一次事故是有人為了“優(yōu)化性能”把pasv_min_port和pasv_max_port注釋掉了結果防火墻規(guī)則對應的端口段全部失效外網用戶全部傳不了文件而內網測試一切正常直到客戶投訴才發(fā)現。最后再分享一個小技巧排查 FTP 問題時盡量用命令行客戶端ftp或lftp而不是圖形客戶端。命令行會原樣輸出服務端的響應碼比如227 Entering Passive Mode (192,168,1,10,117,40)這里面的數字就是服務端返回的被動端口117*2564030000一眼就能看出它返回的是不是內網地址、端口在不在放行范圍內。圖形客戶端把這些信息全藏起來了排查時等于蒙著眼睛。我在實際處理這類問題的體會是FTP 報錯文案的區(qū)分度其實很高拒絕連接和沒有到主機的路由已經把排查方向指得很明確難的不是判斷而是忍住不跳過驗證步驟直接改配置。按鏈路、網絡、端口、應用這四層老老實實走一遍絕大多數問題在十分鐘內就能定位到具體那一行配置上。