器端徹底解決)
前陣子幫一位做嵌入式開發(fā)的朋友調(diào)一塊開發(fā)板他在MobaXterm上連SSH終端敲命令敲得飛起結(jié)果想從左側(cè)SFTP面板拖個編譯產(chǎn)物出來面板轉(zhuǎn)了幾圈彈了個連接關(guān)閉。他當場就吐槽這工具不行要換。我說先別急這個問題我前前后后幫人排查過不下幾十次從家用路由器到云服務(wù)器到開發(fā)板都遇到過十有八九不是MobaXterm的鍋而是SFTP這條通道的“保活”沒人管。這篇文章我就把這類問題徹底拆開講清楚從客戶端到服務(wù)端到網(wǎng)絡(luò)設(shè)備一條條說最后給你一套可以直接抄的穩(wěn)定方案。1. 別急著換工具先搞懂MobaXterm SFTP為什么會“說斷就斷”1.1 左側(cè)文件面板和終端會話其實是兩套“連接邏輯”很多人有個誤解覺得MobaXterm左側(cè)那個SFTP文件樹和右邊的終端窗口是同一個東西。實際上它倆共用的是同一個SSH登錄態(tài)但左側(cè)的文件瀏覽器本質(zhì)上是基于SFTP協(xié)議獨立建立的文件傳輸通道走的還是SSH的22端口不過它有自己的生命周期和超時策略。打個比方你把終端窗口當成和服務(wù)器之間的一條電話線左側(cè)SFTP面板就是這條電話線上的另一部子機。電話線本身沒掛斷但如果子機長期沒人說話交換機那頭可能就把這條空閑線路標記為“僵尸線路”隨時可能回收。SFTP面板只要有一段時間沒有文件操作比如列表、上傳、下載、刪除這條通道就是完全空閑的。空閑到一定程度服務(wù)器端或中間網(wǎng)絡(luò)設(shè)備就會主動把它清掉。這就是為什么你經(jīng)常看到終端窗口還活著左側(cè)面板卻斷了。因為終端窗口哪怕你沒敲命令SSH協(xié)議本身也會有窗口大小調(diào)整、心跳等交互而SFTP面板在沒有文件操作時是真的“零流量”最容易觸碰到各類超時閾值。1.2 超時斷連的四大常見“元兇”你對號入座一下我把這些年遇到的SFTP斷連案例做了個歸類絕大多數(shù)跑不出下面這四類原因。類別典型表現(xiàn)發(fā)生時段根因服務(wù)器端空閑斷開面板閑置幾分鐘后再操作就斷重新點一下又恢復(fù)閑置后第一次操作sshd_config里的ClientAlive參數(shù)未配置或過短NAT會話老化連續(xù)操作也會偶爾斷間隔很規(guī)律每隔幾分鐘一次家用路由器、云安全組、IDC防火墻回收空閑TCP會話網(wǎng)絡(luò)狀態(tài)變化斷網(wǎng)重連、Wi-Fi切換、電腦休眠喚醒后必斷網(wǎng)絡(luò)切換后TCP連接被中間狀態(tài)改變打斷客戶端未自動重建傳輸過載假死拖大文件或海量小文件時面板轉(zhuǎn)圈卡死傳輸過程中SFTP同步阻塞、界面刷新異常、連接被中斷第一類是最常見的很多人從頭到尾沒碰過服務(wù)器上的sshd_config那服務(wù)器自然按默認策略來。默認情況下很多發(fā)行版并沒有配置空閑檢測表面看“服務(wù)器不會主動斷”但一旦碰到NAT設(shè)備或云平臺會話老化連接照樣被攔腰切斷。第二類在家庭寬帶、辦公室內(nèi)網(wǎng)里極其普遍因為家用路由器的NAT會話表通常對空閑TCP連接有個老化時間一般在2到5分鐘超過這個時間沒有流量路由器就把這條映射從表里踢掉了。服務(wù)器端以為連接還在客戶端也以為連接還在實際中間鏈路已經(jīng)斷了這時候你再去點SFTP面板就會卡住直到超時。第三類和第四類屬于“偶發(fā)性”問題不按規(guī)律出現(xiàn)。Wi-Fi切換、電腦休眠、虛擬機快照恢復(fù)都會讓底層的TCP連接狀態(tài)失效。而傳大文件時面板卡死很多人誤判成斷連其實很多時候是MobaXterm的SFTP操作是同步阻塞的界面刷不過來看起來像“死了”。2. 客戶端側(cè)先動手MobaXterm保活參數(shù)這樣設(shè)最穩(wěn)2.1 SSH keepalive到底該填多少填了有什么用MobaXterm其實自帶了SSH層的保活機制只是默認不一定開啟或者參數(shù)不夠激進。打開方式非常簡單在菜單欄進入 Settings - Configuration切到 SSH 這個分類里面能看到 SSH keepalive 相關(guān)的選項。不同版本界面翻譯略有差異有的叫“SSH keepalive interval (seconds)”有的直接叫“Keepalive interval”中文化之后可能是“SSH 保持連接間隔”。它的原理是在SSH連接空閑時客戶端定期往服務(wù)器發(fā)一個非常輕量的消息告訴服務(wù)器“我還活著別把我這條連接清了”。這個保活包不攜帶業(yè)務(wù)數(shù)據(jù)開銷可以忽略不計。我推薦把間隔設(shè)置成30秒到60秒之間。如果你所在網(wǎng)絡(luò)環(huán)境經(jīng)常斷選30秒更穩(wěn)妥如果走的是云服務(wù)器可以放寬到60秒。有些資料讓你填5秒10秒沒必要因為保活包太密集在某些防火墻眼里反而像掃描流量而且白白增加無意義的包量。注意這里有個坑MobaXterm的全局SSH keepalive不一定對所有會話生效。某些版本里單個會話的配置路徑是右鍵左側(cè)會話 - Edit session - Network Settings里面也有獨立的keepalive設(shè)置。如果你全局設(shè)置了但某個會話老斷去這個會話自己的配置里也看一眼兩處都設(shè)置一致才省心。我之前就遇到過用戶只在全局開了結(jié)果他那個會話單獨關(guān)閉了keepalive折騰了半天。2.2 傳大文件卡死、面板刷不出來單獨開一個SFTP會話更省心左側(cè)面板斷連讓人煩躁的另一個場景是傳大文件。尤其是直接鼠標拖拽幾個GB的文件MobaXterm界面會長時間無響應(yīng)進度條不走面板看著像“斷連”。這不一定真的是網(wǎng)絡(luò)斷了而是SFTP整個會話正處于一個同步等待狀態(tài)UI和底層傳輸互相阻塞造成“假死”。我的建議是把“瀏覽文件”和“傳輸文件”這兩件事分開。如果只是偶爾傳個大文件直接在MobaXterm頂部新建一個獨立的 SFTP 會話New session - SFTP填寫同樣的服務(wù)器地址、端口、賬號密碼進去之后就是一個純文件管理界面。這個界面和你的SSH終端互不干擾傳輸大文件時就算界面卡住SSH終端照常能用傳輸完成與否也更容易判斷。還有一類場景是傳海量小文件比如一個目錄下有成千上萬個配置文件。用SFTP面板全選拖拽十有八九會卡。原因是SFTP協(xié)議本身是“一問一答”式的交互模式每個文件都要經(jīng)歷打開、傳輸、關(guān)閉、確認等多次往返文件一多整個過程被無限拉長中間任何一次網(wǎng)絡(luò)抖動都可能讓整個任務(wù)失敗。這種情況我更建議現(xiàn)場打包壓縮用 tar 在服務(wù)器端打一個包再傳或者直接用 scp、rsync 這類工具在終端里跑至少能看到進度、能斷點續(xù)傳。MobaXterm免費版雖然對會話數(shù)量有限制但獨立SFTP會話這種用法是不受影響的放心用。3. 不用只改客戶端服務(wù)器端這幾個參數(shù)才是治本關(guān)鍵3.1 sshd_config 里的 ClientAlive / TCPKeepAlive別再照抄不懂的“最佳實踐”客戶端開保活只解決了一半問題另一半在服務(wù)器端。很多教程讓你改 /etc/ssh/sshd_config但只說“把下面的內(nèi)容加上”不說參數(shù)的意思結(jié)果有人照抄完反而更糟。我先把這幾個參數(shù)講明白。# 服務(wù)器每隔多少秒向客戶端發(fā)送一次存活探測消息 ClientAliveInterval 60 # 客戶端連續(xù)多少次沒響應(yīng)服務(wù)器才判定連接死亡 ClientAliveCountMax 3 # 啟用TCP層keepalive TCPKeepAlive yes # 關(guān)閉DNS反向解析加快連接速度 UseDNS noClientAliveInterval 是服務(wù)器主動探測客戶端的時間間隔單位秒。60秒就是每分鐘探測一次。ClientAliveCountMax 是連續(xù)幾次探測無響應(yīng)就斷開設(shè)成3意味著客戶端最多180秒沒反應(yīng)才會被服務(wù)器殺掉。這兩個參數(shù)配合起來效果是只要網(wǎng)絡(luò)鏈路還在服務(wù)器每60秒發(fā)一次探測連接就一直保持“活躍”狀態(tài)如果客戶端真的沒了180秒后自動回收不占資源。TCPKeepAlive 是更底層的TCP心跳默認本身是yes但很多人不知道它的探測周期是按系統(tǒng)TCP參數(shù)走的Linux默認一般是7200秒也就是兩小時才探測一次對防斷連幾乎沒意義。所以真正起作用的還是前面的ClientAlive系列參數(shù)。還有一個特別容易被忽略的UseDNS no。默認情況下SSH服務(wù)器收到連接后會嘗試反向解析客戶端的IP到域名如果DNS響應(yīng)慢連接建立過程就會卡很久間接導(dǎo)致客戶端在等待握手時超時。尤其是內(nèi)網(wǎng)環(huán)境很多機器根本沒有PTR記錄DNS查詢要一路等到超時。加上 UseDNS no 能明顯加快連接建立速度算是個讓整體體驗更順的附帶優(yōu)化。3.2 面向SFTP專用賬號的 Match User 配置安全又干凈如果你這臺服務(wù)器上面跑著專門的SFTP賬號只允許別人上傳下載文件不想讓對方登錄shell執(zhí)行命令那有個更規(guī)范的配置方式。在sshd_config里用 Match User 把這類用戶單獨約束起來強制走 internal-sftp命令執(zhí)行功能直接關(guān)掉。Subsystem sftp internal-sftp Match User sftpuser ForceCommand internal-sftp ChrootDirectory /home/sftpuser PasswordAuthentication yes PermitTTY no X11Forwarding no AllowTcpForwarding no這里面的關(guān)鍵是 ForceCommand internal-sftp。它強制該用戶登錄后只能進入SFTP子系統(tǒng)連shell都不加載這樣Shell啟動腳本里那些亂七八糟的輸出就根本不會出現(xiàn)從根上杜絕了后面要講的“received message too long”這類報錯。ChrootDirectory 則把用戶鎖定在指定目錄里他只能看到這個目錄下的文件安全性上了一個臺階。注意一個坑ChrootDirectory 指定的目錄屬主必須是root權(quán)限必須是755不能是用戶自己擁有。很多人配完發(fā)現(xiàn)SFTP連不上日志報錯基本都是因為目錄屬主寫成了sftpuser。這個細節(jié)不遇到一遍根本不會記住我吃過一次虧后來給別人排錯也經(jīng)常看到同樣的問題。配置改完記得重啟服務(wù)很多發(fā)行版用 systemctl restart sshdCentOS 6這種老系統(tǒng)是 service sshd restart別搞混。重啟前最好先 sshd -t 檢查一下語法防止配錯了直接連不上最后還得去VNC控制臺救場。4. 直接抄作業(yè)一套在云服務(wù)器/虛擬機/開發(fā)板上都能用的穩(wěn)定配置4.1 Windows端MobaXterm推薦配置清單先說Windows側(cè)也就是MobaXterm本身。按下面這個列表逐項檢查每項都不復(fù)雜。打開 Settings - Configuration - SSH把 SSH keepalive interval 設(shè)置為 30單位是秒。如果你經(jīng)常在網(wǎng)絡(luò)差的環(huán)境可以改成15但沒必要低于10。在左側(cè)會話欄右鍵你的SSH會話 - Edit session - Network Settings同樣的keepalive選項也設(shè)置為30和全局保持一致避免某個會話單獨覆蓋掉全局配置。把 SSH 連接的“Remote environment”設(shè)置為“User environment”還是“Login shell”保持默認即可。真正需要在意的是不要在里面附加自動執(zhí)行命令比如“登錄后自動跑一個tail -f”因為這類命令會改變終端行為也容易干擾SFTP通道。如果MobaXterm本身有代理設(shè)置在 Settings - Proxy 里確認是“No proxy”。很多人以前用過代理后來換了網(wǎng)絡(luò)環(huán)境忘了改回來SSH一直走一個失效的代理表現(xiàn)就是連不上、易斷。MobaXterm默認會自動檢查更新這個不影響連接穩(wěn)定性但在弱網(wǎng)環(huán)境下彈更新窗口會讓人分心建議在 Settings - General 里關(guān)掉。4.2 Linux服務(wù)器端推薦配置清單服務(wù)器端我直接給一套經(jīng)過驗證的配置。注意所有參數(shù)都只影響新建立的SSH會話改完重啟sshd后需要重新連接一次才生效。# 修改 /etc/ssh/sshd_config Port 22 Protocol 2 # 連接保活 ClientAliveInterval 60 ClientAliveCountMax 3 TCPKeepAlive yes # 連接加速 UseDNS no # GSSAPI認證在內(nèi)網(wǎng)環(huán)境經(jīng)常拖慢連接建議關(guān)閉 GSSAPIAuthentication no # 使用內(nèi)置SFTP子系統(tǒng) Subsystem sftp internal-sftpGSSAPIAuthentication 是很多人忽略的一項。默認開啟時SSH連接建立階段會嘗試Kerberos類的GSSAPI認證如果服務(wù)器和客戶端都不在同一個域環(huán)境這個嘗試會白白消耗幾秒甚至更久。內(nèi)網(wǎng)、家庭網(wǎng)絡(luò)、開發(fā)板場景直接關(guān)掉連接體驗會快一大截。改完后執(zhí)行 sshd -t 檢查語法然后 systemctl restart sshd。注意重啟不會影響當前已連接的會話只影響新連接所以可以放心操作。4.3 不同場景下的參數(shù)怎么微調(diào)上面這套參數(shù)是“通用底盤”不同使用環(huán)境還要微調(diào)一下。使用場景保活間隔建議特殊注意事項云服務(wù)器公網(wǎng)連接30秒到60秒檢查云安全組是否放行22端口修改端口后要同步安全組虛擬機NAT模式30秒NAT模式下宿主機重啟、網(wǎng)絡(luò)重連都會斷建議改用橋接模式或保持VMware網(wǎng)絡(luò)穩(wěn)定虛擬機橋接模式60秒相當于直接連局域網(wǎng)斷連概率低嵌入式開發(fā)板30秒開發(fā)板網(wǎng)卡休眠、供電不穩(wěn)、IP變動是主要斷連原因公司內(nèi)網(wǎng)跳板機60秒中間可能有防火墻參數(shù)太激進反而被限流云服務(wù)器場景有個額外建議能用密鑰登錄就盡量用密鑰別用密碼。原因是密碼認證在某些安全策略下會觸發(fā)頻繁的會話重建或要求重新驗證而密鑰登錄建立的長連接更穩(wěn)定也少了每次輸密碼的體驗割裂感。虛擬機場景最容易忽略的是“宿主機網(wǎng)絡(luò)切換”。比如你在筆記本上用VMware跑了一臺Ubuntu筆記本從家里Wi-Fi切到手機熱點虛擬機的NAT網(wǎng)絡(luò)會跟著重建之前建立的SSH連接全部失效SFTP面板自然必斷。這個問題改參數(shù)解決不了只能重連建議固定用橋接模式并給虛擬機配置靜態(tài)IP能少很多麻煩。開發(fā)板場景則要注意IP地址漂移。開發(fā)板默認可能走DHCP路由器重啟后分配了不同IPMobaXterm里保存的還是老IP表現(xiàn)為連不上或SFTP面板反復(fù)斷開。給開發(fā)板在路由器里做IP-MAC綁定或者直接在板子上配靜態(tài)IP比調(diào)整任何SSH參數(shù)都有效。5. 和SFTP斷連一起出現(xiàn)的“疑難雜癥”一次說清5.1 報錯“received message too long 1416128883”的真相與處理這個報錯在MobaXterm連接一些配置過的Linux服務(wù)器時特別常見很多人在網(wǎng)上搜了一圈也找不到能看懂的答案。我第一次遇到時也懵了什么 message too longSFTP協(xié)議還能收到這么長的消息其實這個數(shù)字非常有意思。把它從十進制轉(zhuǎn)成十六進制是 0x54686973對應(yīng)ASCII碼正好是“This”這個單詞的開頭。也就是說你的SFTP客戶端本來在等一個二進制協(xié)議包結(jié)果收到的卻是一條以“This”開頭的普通文本消息。SFTP協(xié)議里每條消息的前4個字節(jié)代表長度這段普通文本的長度字段自然就是亂七八糟的客戶端解析出來就是一個巨大的“too long”報錯。那這段文本是哪來的絕大多數(shù)是用戶登錄時shell的環(huán)境腳本里打印了東西。比如 /etc/motd、/etc/issue.net、用戶家目錄下的.bashrc里寫了一句 echo Welcome ...或者某個腳本執(zhí)行時輸出了提示文字。SSH終端連接時這些文本顯示出來沒問題但SFTP通道是純二進制協(xié)議通道任何非協(xié)議內(nèi)容都會被當成協(xié)議來解析于是炸了。處理辦法有三個層級。最徹底的辦法是給SFTP專用用戶加 ForceCommand internal-sftp讓它根本不加載shell上面說的那些輸出就全部繞開了。不愿意動賬號結(jié)構(gòu)的就清理shell啟動腳本里的輸出內(nèi)容重點查 .bashrc、.bash_profile、/etc/profile、/etc/motd 這幾個文件。還有一種臨時辦法是在客戶端連接方式上做文章比如用SFTP專用客戶端連接時指定不加載shell但MobaXterm左側(cè)面板沒這么細的選項所以最靠譜的還是前兩種。遇到這個報錯千萬別重裝MobaXterm它完全不是客戶端的問題。5.2 連接不上虛擬機/云主機的排查順序這個標題對應(yīng)的熱搜詞一直居高不下說明很多人卡在“壓根連不上”這個更前面的問題。如果你連MobaXterm的SSH都連不上更別談左側(cè)SFTP了按下面這個順序排查基本十分鐘內(nèi)能定位問題。第一步先ping一下目標主機IPping不通說明網(wǎng)絡(luò)層就沒通檢查虛擬機網(wǎng)絡(luò)模式、云服務(wù)器安全組、本地防火墻物理鏈路都看一遍。第二步ping通了但22端口連不上用MobaXterm自帶的端口測試工具或者本機 telnet ip 22 測一下端口狀態(tài)。端口不通去目標主機上看 sshd 是否正在運行systemctl status sshd然后看本地防火墻是否放行了22端口。第三步如果把SSH端口改成了非常規(guī)端口比如2222記得云服務(wù)器安全組也要放行2222虛擬機的防火墻也要放行對應(yīng)端口。最后MobaXterm自身也可能有代理干擾檢查 Settings - Proxy 是否為 No proxy。這個我前面提過但排查時仍然值得第一個排除因為太隱蔽了。還有一類情況是虛擬機里安裝了ufw或firewalld默認策略把22端口拒絕了。很多人改了sshd_config里的Port卻沒同步防火墻策略結(jié)果ssh -p 2222 連不上原以為是配置改壞了實際是防火墻只放行了默認的22。這種問題看系統(tǒng)日志 /var/log/messages 或 journalctl -u sshd 都能看到線索。5.3 密碼無法輸入、終端卡頓、中文亂碼這些小坑MobaXterm使用中還有幾個高頻小問題經(jīng)常和斷連問題一起被提到順手一塊說。很多人說“密碼無法輸入”實際是SSH登錄狀態(tài)下密碼輸入不回顯這是正常現(xiàn)象不是鍵盤壞了。你正常打完整串密碼按回車就行。如果你真想粘貼密碼MobaXterm終端里CtrlV是不行的要按 ShiftInsert或者鼠標右鍵選擇粘貼。我在給別人遠程指導(dǎo)時經(jīng)常讓他們先確認鍵盤右上角大小寫燈因為密碼里大小寫混用的人特別多輸錯幾次之后自己都以為是軟件問題。終端卡頓這事多半是MobaXterm渲染問題或者你開了太多側(cè)邊欄工具。建議在 Settings - Configuration - Terminal 里把回滾行數(shù)從默認的很大值調(diào)低比如5000行以內(nèi)再禁用不必要的“Dashboard”自動刷新。如果你同時開了多個會話每一個都實時滾動日志卡頓幾乎是必然的。另外MobaXterm免費版默認會檢測新版本弱網(wǎng)下檢測動作本身也會卡一下界面不在設(shè)置里關(guān)掉的話隔幾天就煩一次。中文亂碼的問題要分兩頭說。MobaXterm終端里中文顯示亂碼先看會話連接的編碼設(shè)置把終端編碼改成UTF-8再確認服務(wù)器端locale正確執(zhí)行 echo $LANG正常應(yīng)該輸出帶UTF-8字樣的內(nèi)容比如 en_US.UTF-8 或 zh_CN.UTF-8。如果服務(wù)器沒有生成對應(yīng)locale執(zhí)行 locale-gen 或修改 /etc/default/locale 后重啟。開發(fā)板場景有點特殊經(jīng)常是MobaXterm里能顯示中文但開發(fā)板自帶的屏幕終端卻亂碼這種一般是開發(fā)板本地終端字體缺少中文點陣或者內(nèi)核終端編碼設(shè)置不對和MobaXterm沒有關(guān)系把注意力放到開發(fā)板的終端配置和字庫上才對路。5.4 順手提升幸福感中文化、時間戳、腳本穩(wěn)定上傳最后聊幾個能讓日常使用舒服不少的小功能都算不上“解決斷連”但能顯著提升效率。MobaXterm本身支持中文界面在 Settings - General - Language 里選擇中文重啟后就是中文版。之前有人問我MobaXterm怎么設(shè)置中文就是這個路徑。不過我個人其實更推薦保留英文界面因為很多技術(shù)文檔和配置截圖都是英文界面對照起來方便而且菜單項的中英文翻譯在不同版本間有差異反而容易產(chǎn)生理解偏差。時間戳功能非常實用。菜單欄 Terminal - Toggle timestamps開啟后終端每行輸出前面會帶上當前時間。排查問題需要確定某條日志是幾點幾分打印的時候這個功能簡直救命。尤其是調(diào)試網(wǎng)絡(luò)超時類問題你需要判斷服務(wù)器到底是在哪個時間點斷開的時間戳能直接幫你判斷是網(wǎng)絡(luò)問題還是服務(wù)器主動斷開。再說一個偏運維向的場景熱搜里有“shell腳本連接sftp服務(wù)器命令”說明不少人想在腳本里自動化上傳下載文件。用腳本連SFTP時除了前面說的保活參數(shù)還要在腳本里加上超時重試邏輯。比如用 sftp -o ConnectTimeout10 限制連接超時時間傳輸大文件時配合文件校驗傳完比對大小或md5防止網(wǎng)絡(luò)異常導(dǎo)致半截文件。腳本跑在定時任務(wù)里的時候一旦目標服務(wù)器暫時不可達沒有超時限制的腳本會一直掛在那里直到任務(wù)僵死這種問題在凌晨的定時任務(wù)里出現(xiàn)的概率特別高別問我怎么知道的。如果你也被MobaXterm左側(cè)SFTP斷連折磨過上面這套從客戶端到服務(wù)端的組合配置基本能解決九成以上的問題。我個人最推薦的最小配置是客戶端keepalive設(shè)30秒服務(wù)器端ClientAliveInterval設(shè)60秒、ClientAliveCountMax設(shè)3再加UseDNS no。這套組合在云服務(wù)器、虛擬機、開發(fā)板三種環(huán)境我都驗證過至少能讓左側(cè)面板的斷連頻率從“時報”降到“幾乎不再犯”。如果你是那種長時間掛機、偶爾切回來看一眼的使用習慣建議再在會話配置里把“連接斷開后自動重連”一并打開省得每次手動點一下。畢竟工具始終是工具穩(wěn)定連接這件事把能配置的參數(shù)都配到位剩下才輪到懷疑工具不行。