實踐)
WSL2 裝好之后,大部分人停在能在 Windows 里敲 Linux 命令這一步就滿足了。但只要你有第二臺機器——哪怕只是同一張桌子上的另一臺筆記本、一臺平板,或者公司里那臺常年開著的編譯服務(wù)器——你很快就會碰到一個很具體的需求:我要從別的設(shè)備直接連進這臺 WSL2,而不是每次都先遠程桌面到 Windows 再開個終端窗口。這時候 NAT 模式就開始礙事了。這篇內(nèi)容講的就是我在這條路上來回折騰了幾輪之后沉淀下來的做法:把 WSL2 的網(wǎng)絡(luò)入口打通,用 SSH 作為統(tǒng)一入口,再讓 VSCode 的 Remote-SSH 直接落在這個入口上。適合已經(jīng)用過 WSL2、能看懂基本 Linux 命令、但被 IP 漂移和端口轉(zhuǎn)發(fā)折磨過的開發(fā)者;如果你剛裝完 WSL2,建議先跑通基礎(chǔ)環(huán)境再回來看,不然容易被細節(jié)淹沒。1. 先想清楚:我為什么要逃離 NAT 模式1.1 那個每次重啟都會變的 172 開頭的地址WSL2 默認跑在一個輕量虛擬機里,Windows 主機構(gòu)建了一個虛擬網(wǎng)卡給它做 NAT 轉(zhuǎn)發(fā)。你在 WSL2 里執(zhí)行ip addr,大概率會看到eth0上掛著一個172.x.x.x的地址。這個地址不是你路由器分配的,是 WSL 內(nèi)部的虛擬 DHCP 給的,而且每次wsl --shutdown之后再啟動,它大概率會變。這就是一切麻煩的源頭。我最早的做法很樸素:需要從別的機器連進來時,先跳回 Windows 敲一遍wsl hostname -I把地址抄下來,再去另一臺機器上ssh user172.x.x.x。第一次還能忍,第三次就開始煩了,因為你永遠在重復(fù)同一件事,而且這個地址不能寫進任何配置文件,更不能寫進腳本——寫了第二天就失效。真正讓我下決心改造的,是我把一份構(gòu)建腳本扔到另一臺機器上跑,腳本里硬編碼了 WSL 的地址,隔天早上定時任務(wù)全線失敗。所以這里要先明確一個判斷標準:如果你的使用場景里,連接發(fā)起方永遠是 Windows 主機自己,那么 NAT 模式完全夠用,你甚至不需要任何額外配置,localhost轉(zhuǎn)發(fā)已經(jīng)幫你處理好了。只有當(dāng)連接發(fā)起方是別的設(shè)備或者別的容器時,你才需要往下走。1.2 局域網(wǎng)里那臺設(shè)備連不進來的真實原因很多人第一反應(yīng)是防火墻,關(guān)掉防火墻發(fā)現(xiàn)還是連不上,就懵了。其實原因很簡單:NAT 模式下,WSL2 的那臺虛擬機和你的物理局域網(wǎng)之間隔了一層地址轉(zhuǎn)換。局域網(wǎng)里的設(shè)備發(fā)包給 Windows 主機的 IP,Windows 收到了,但它不知道該轉(zhuǎn)發(fā)給內(nèi)部的哪臺虛擬機,于是直接丟棄。這不是防火墻攔的,是壓根沒有路由規(guī)則。這就解釋了為什么在 Windows 主機上ssh localhost能通,換成ssh 192.168.1.x就不通——前者走的是 WSL 自己注冊的本地回環(huán)轉(zhuǎn)發(fā),后者走的是物理網(wǎng)卡,兩條路徑完全不同。理解這一點非常關(guān)鍵,后面所有方案的取舍都建立在它之上:我們要做的不是打開某個開關(guān),而是在 NAT 邊界上鑿一個洞,或者干脆換掉 NAT 這層結(jié)構(gòu)。順便說一個常見誤解:有人會去 WSL2 里執(zhí)行ip route看到默認網(wǎng)關(guān)是172.x.x.1,就以為把這個網(wǎng)關(guān)改成路由器地址就能橋接。改完之后大概率是徹底斷網(wǎng),因為 WSL 的虛擬交換機不認外部的 MAC 和路由,恢復(fù)起來還得wsl --shutdown重來。這條路我試過,浪費時間,不建議。2. 三條技術(shù)路線的真實取舍,別在錯誤的方向上耗時間2.1 端口轉(zhuǎn)發(fā):最土但最可控的方案netsh interface portproxy是 Windows 自帶的端口轉(zhuǎn)發(fā)工具,原理是在 Windows 主機上監(jiān)聽一個端口,把流量轉(zhuǎn)發(fā)到 WSL2 的內(nèi)部地址。命令長這樣,需要管理員權(quán)限的 PowerShell:# 假設(shè) WSL2 當(dāng)前地址是 172.28.100.5,想把宿主機的 2222 端口轉(zhuǎn)到 WSL 的 22 netsh interface portproxy add v4tov4 listenport2222 listenaddress0.0.0.0 connectport22 connectaddress172.28.100.5配套還要放行防火墻:New-NetFirewallRule -DisplayName WSL SSH 2222 -Direction Inbound -Protocol TCP -LocalPort 2222 -Action Allow這個方案最大的優(yōu)點是不改變?nèi)魏尉W(wǎng)絡(luò)結(jié)構(gòu),失敗了刪掉規(guī)則就恢復(fù)原樣,風(fēng)險極低。缺點是它把IP 會變這個問題原封不動地留給了你:WSL 重啟、地址變了,轉(zhuǎn)發(fā)規(guī)則還指向舊地址,連接就會超時,而且超時的表現(xiàn)和服務(wù)沒起來幾乎一模一樣,排查起來很迷惑。我的處理辦法是寫一個開機腳本,每次 WSL 啟動后自動刷新轉(zhuǎn)發(fā)規(guī)則。核心邏輯就是取當(dāng)前地址、刪舊規(guī)則、加新規(guī)則。這個腳本我放在任務(wù)計劃里,登錄時觸發(fā)。它不優(yōu)雅,但運行了一年多沒出過問題,原因很簡單:它把不確定性收斂到了一個地方,你只需要盯住這一個腳本有沒有跑成功。2.2 鏡像網(wǎng)絡(luò)模式:最接近橋接體驗的官方路子如果你用的是較新的 Windows 11 和較新的 WSL 版本,有一個更干凈的選擇:鏡像網(wǎng)絡(luò)模式(mirrored networking)。它讓 WSL2 直接復(fù)用 Windows 主機的網(wǎng)絡(luò)接口和地址,不再單獨做一層 NAT。開啟方式是在用戶目錄下建一個.wslconfig文件,路徑是C:\Users\你的用戶名\.wslconfig,內(nèi)容:[wsl2] networkingModemirrored保存后執(zhí)行wsl --shutdown,等幾秒再啟動,進去ip addr,你會發(fā)現(xiàn)網(wǎng)絡(luò)接口變了,地址和 Windows 主機在同一網(wǎng)段。此時在 WSL2 里跑的服務(wù),Windows 上用localhost:端口能直接訪問,局域網(wǎng)里的其他設(shè)備用Windows 主機的 IP 端口也能直接訪問,不需要任何portproxy規(guī)則。這個模式之所以被很多人叫作橋接,是因為從使用體驗上看它確實達到了橋接的效果:同一網(wǎng)段、可直接被外部訪問、不用轉(zhuǎn)發(fā)。但從實現(xiàn)上說它不是二層橋接,只是把主機的網(wǎng)絡(luò)棧共享給了 WSL。這個區(qū)別在實際使用中通常無關(guān)緊要,但在排查問題時很重要——比如你會發(fā)現(xiàn) WSL 里看到的網(wǎng)卡列表和 Windows 上高度一致,包括那些虛擬網(wǎng)卡,這就是共享網(wǎng)絡(luò)棧的直接體現(xiàn)。鏡像模式有一個必須注意的前提:它要求較新的 WSL 版本??梢韵扰躻sl --version看一眼,如果命令本身報錯說不認識,說明版本偏舊,先升級。另外在某些企業(yè)環(huán)境里,主機的網(wǎng)絡(luò)策略或安全軟件會對這種共享棧的行為有額外限制,表現(xiàn)是開起來之后主機自己斷網(wǎng)了,遇到這種情況直接改回默認模式,別硬剛。2.3 想用 Hyper-V 外部虛擬交換機做真橋接?我勸你放棄網(wǎng)上不少教程會告訴你:打開 Hyper-V 管理器,創(chuàng)建一個外部虛擬交換機綁定物理網(wǎng)卡,然后把 WSL 的虛擬網(wǎng)卡掛上去,這樣就實現(xiàn)了真正的橋接。這個說法在早期的 Hyper-V 虛擬機上成立,但在 WSL2 上基本行不通。原因是 WSL2 的虛擬網(wǎng)卡由 WSL 自己管理,并不會以可以隨意掛載到外部交換機的形式暴露出來,你在 Hyper-V 管理器里往往找不到對應(yīng)的可操作對象。更糟的是,一旦你在 Hyper-V 里創(chuàng)建了綁定物理網(wǎng)卡的外部交換機,Windows 主機的網(wǎng)絡(luò)配置可能被改寫,輕則 IP 變了,重則直接斷網(wǎng),而恢復(fù)過程需要刪掉交換機、重置網(wǎng)卡,有時候還得重啟。我在這上面栽過一次,當(dāng)時以為是自己操作不對,反復(fù)試了三遍,每次都把主機網(wǎng)絡(luò)搞掛,最后確認這條路在 WSL2 上就是不成立的。把三條路線放在一起對比,結(jié)論就很清楚了:方案外部設(shè)備可訪問IP 是否穩(wěn)定對主機網(wǎng)絡(luò)的侵入性恢復(fù)難度適用場景netsh 端口轉(zhuǎn)發(fā)是,但要放行防火墻否,需腳本刷新低,僅增加轉(zhuǎn)發(fā)規(guī)則刪規(guī)則即可老版本系統(tǒng)、企業(yè)受限環(huán)境鏡像網(wǎng)絡(luò)模式是,直接可達是,跟隨主機地址中,改變網(wǎng)絡(luò)棧結(jié)構(gòu)改回配置重啟新版本系統(tǒng),首選Hyper-V 外部交換機理論可行,實際難不確定高,可能打斷主機網(wǎng)絡(luò)高,常需重啟修復(fù)不建議我的實際選擇是:主力機用鏡像網(wǎng)絡(luò)模式,備用機上留一套端口轉(zhuǎn)發(fā)腳本兜底。兩套方案并存聽起來冗余,但正是這套冗余讓我在換機器、重裝系統(tǒng)、版本回退的幾種情況下都沒有卡住過。3. 讓 sshd 在 WSL2 里真正跑起來并活過重啟3.1 安裝與 sshd_config 里真正需要改的那幾行網(wǎng)絡(luò)通了只是修好了路,還得有個服務(wù)在門口收件。WSL2 的發(fā)行版里默認通常沒裝 SSH 服務(wù)端,先裝:sudo apt update sudo apt install -y openssh-server裝完之后先別急著改配置,直接sudo service ssh start,然后在 Windows 上試著連一次。先跑通默認配置,再逐項加固,這個順序很重要。我見過太多人一上來就把PermitRootLogin、PasswordAuthentication、AllowUsers全改了,結(jié)果連不上,還得回頭一項項排查到底是哪一行出的問題。默認配置跑通之后,打開/etc/ssh/sshd_config,真正需要動的其實就三處:# 明確監(jiān)聽所有地址,排除只綁回環(huán)的可能 ListenAddress 0.0.0.0 # 端口按需改,避開 Windows 主機上可能已被占用的 22 Port 2222 # 密鑰登錄為主,密碼登錄視安全要求關(guān)閉 PubkeyAuthentication yes PasswordAuthentication no這里解釋一下為什么把端口改掉。Windows 10/11 自帶一個可選的 OpenSSH Server 功能,如果你之前手滑裝過并啟用了它,Windows 側(cè)的 22 端口就被占了。此時你在 WSL 里也開 22,再用端口轉(zhuǎn)發(fā)或者鏡像模式,就會出現(xiàn)連接上了但認證的是 Windows 那個服務(wù)的詭異現(xiàn)象——表現(xiàn)是用戶名密碼怎么輸都不對,而且報錯信息完全看不出是連錯了地方。換一個非標準端口(2222、2202之類)能一勞永逸地躲開這個坑。改完配置先用sudo sshd -t做語法檢查,這個命令只校驗不啟動,能提前發(fā)現(xiàn)拼寫錯誤。確認無誤再重啟服務(wù)。3.2 密鑰登錄:那兩個權(quán)限數(shù)字比密鑰本身更容易出錯生成密鑰對在 Windows 側(cè)做就行,ssh-keygen -t ed25519 -f $HOME\.ssh\id_ed25519_wsl,然后把公鑰內(nèi)容追加到 WSL2 里的~/.ssh/authorized_keys。這一步看起來簡單,但權(quán)限問題幾乎人人都踩過。OpenSSH 對權(quán)限的檢查非常嚴格,而且它的檢查邏輯在服務(wù)端:如果~/.ssh或authorized_keys的權(quán)限過于寬松(比如組用戶或其他用戶可寫),它會靜默拒絕使用這個密鑰,日志里可能只有一句很含糊的 Authentication refused: bad ownership or modes。修復(fù)方式:chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys還有兩個容易忽略的點。第一,~/.ssh的所有上級目錄也不能對組用戶或其他用戶可寫,如果你把家目錄權(quán)限改成了777,密鑰同樣會失效。第二,如果 WSL2 里的用戶是通過 Windows 用戶映射進來的,注意authorized_keys要放在實際登錄用戶的家目錄下,而不是 root 的目錄下。我見過有人把公鑰追加到了sudo之后的 root 家目錄,然后一直困惑為什么用普通用戶登錄不進去。密鑰驗證是否真的生效,有個快速判斷方法:ssh -v看輸出里有沒有Offering public key以及緊隨其后的Server accepts key。如果只有前者沒有后者,基本就是服務(wù)端權(quán)限檢查沒過;如果連前者都沒有,說明客戶端的IdentityFile路徑寫錯了。這個二分法能省掉大量瞎猜的時間。3.3 開機自啟:別指望手動service ssh startWSL2 的實例在你不使用時會自動休眠,下次訪問時重新拉起。這意味著你手動start的 sshd,在下一次實例重啟后就不在了。表現(xiàn)是今天配好了,明天早上連不上,進去一看進程沒了。這個問題如果不解決,整套配置就是一次性的。兩種接管方式。第一種是啟用 systemd,在/etc/wsl.conf里寫:[boot] systemdtrue保存后wsl --shutdown,重進,systemctl status能正常輸出就說明 systemd 起來了,然后sudo systemctl enable --now ssh即可實現(xiàn)開機自啟。這是目前更推薦的方式,因為很多其他服務(wù)也依賴 systemd。第二種是不啟用 systemd,直接用wsl.conf的 boot 命令:[boot] command service ssh start這個方式更輕,不改變 init 系統(tǒng),適合那些不想動 systemd 的環(huán)境。缺點是它只能執(zhí)行單條命令,想同時啟動多個服務(wù)就得包一層腳本。我的建議是:如果你的發(fā)行版和 WSL 版本支持 systemd,就用 systemd。理由不是 systemd 更好,而是生態(tài)更一致——你在別的 Linux 機器上學(xué)到的systemctl enable經(jīng)驗可以直接復(fù)用,不用為 WSL 單獨記一套。4. 把 VSCode 的 Remote-SSH 接到這個入口上4.1 config 文件怎么寫才不用每次輸一堆參數(shù)VSCode 的 Remote-SSH 擴展讀取的是標準 SSH 配置文件,Windows 側(cè)路徑是C:\Users\用戶名\.ssh\config。寫好之后 VSCode 左側(cè)遠程資源管理器里會直接列出這個主機名,點一下就能連:Host wsl-dev HostName 127.0.0.1 Port 2222 User devuser IdentityFile ~/.ssh/id_ed25519_wsl ServerAliveInterval 30 ServerAliveCountMax 3這里有幾個參數(shù)值得說明。HostName填127.0.0.1是配合端口轉(zhuǎn)發(fā)或鏡像模式的寫法,因為最終暴露端口的是 Windows 主機;如果你走的是純局域網(wǎng)直連,就填主機的局域網(wǎng) IP。ServerAliveInterval 30是每 30 秒發(fā)一次心跳,配合ServerAliveCountMax 3,能在網(wǎng)絡(luò)短暫抖動時避免連接被判定為斷開——WSL2 實例休眠再喚醒的場景下,這個設(shè)置能顯著減少連接已關(guān)閉的提示頻率。IdentityFile里的~在 Windows 的 SSH 客戶端下會解析到用戶目錄,一般沒問題,但如果你在 VSCode 里遇到找不到密鑰的報錯,直接改成絕對路徑C:/Users/xxx/.ssh/id_ed25519_wsl,注意用正斜杠。還有一個細節(jié):改完 config 之后,如果連接行為沒變化,可能是 VSCode 緩存了舊配置。這時候執(zhí)行一次命令面板里的Remote-SSH: Kill VS Code Server on Host,清掉遠端的服務(wù)端進程,再重連,通常就恢復(fù)正常了。4.2 首次連接會遇到的三道坎第一道是 host key 確認。首次連接會彈出一個指紋確認,選繼續(xù)即可。但如果你之前用同一個 IP 和端口連過別的機器,會遇到REMOTE HOST IDENTIFICATION HAS CHANGED的硬性拒絕。這是因為舊指紋還留在known_hosts里。處理方式是ssh-keygen -R [127.0.0.1]:2222,注意帶端口時要加方括號和引號,不帶端口的話格式不同,寫錯了刪不掉。這個報錯看起來嚇人,實際上是保護機制在正常工作,不用緊張。第二道是遠端服務(wù)端安裝。Remote-SSH 連接成功后,會在遠端自動下載并安裝一個輕量的服務(wù)端組件。這個過程需要遠端能訪問下載源。如果 WSL2 里的網(wǎng)絡(luò)出口有問題,就會卡在 Setting up SSH Host 這一步很久最后失敗。遇到這種情況,可以看 VSCode 的輸出面板里 Remote-SSH 通道的具體報錯,通常會給出下載地址和失敗原因。實在裝不上,也可以手動把安裝包放進遠端指定目錄,不過這條路比較繞,優(yōu)先解決網(wǎng)絡(luò)出口問題。第三道是擴展的安裝位置。這是新手最容易困惑的地方:Remote-SSH 連上之后,你的工作區(qū)在遠端,大部分擴展需要安裝到遠端。在擴展面板里,已安裝的擴展會顯示一個在 SSH: wsl-dev 上安裝的按鈕,點一下才會在遠端生效。像語言服務(wù)、調(diào)試器、格式化工具這些必須裝遠端;主題、快捷鍵這類界面相關(guān)的裝本地就行。搞混了的表現(xiàn)是擴展明明裝了但就是不工作,排查半天發(fā)現(xiàn)裝錯了位置。4.3 WSL 擴展和 Remote-SSH,到底該用哪個這里必須說清楚一個容易混淆的點:VSCode 有一個官方的 WSL 擴展,它直接對接 WSL2 實例,不需要 SSH,也不需要網(wǎng)絡(luò)配置,打開文件夾時選 Connect to WSL 就行。那既然有這個,為什么還要折騰 Remote-SSH?答案是使用場景不同。WSL 擴展要求 VSCode 跑在 Windows 主機上,它通過本地管道和 WSL 通信。如果你的開發(fā)機就是這臺 Windows,那 WSL 擴展是更省事的選擇,網(wǎng)絡(luò)部分完全不用管。但如果你的場景是:代碼跑在 A 機器的 WSL2 里,而你在 B 機器上寫代碼,那 WSL 擴展就無能為力了,因為它只能連本機的 WSL。這時候 Remote-SSH 才是正解,因為它本質(zhì)上是通過 SSH 連一臺 Linux 機器,至于那臺機器是物理機、虛擬機還是 WSL2,它并不關(guān)心。我自己的用法是兩者并存:坐在主力機前的時候,用 WSL 擴展,啟動快、零配置;出門用筆記本的時候,用 Remote-SSH 連回主力機的 WSL2。兩個入口指向同一份代碼,互不干擾。需要注意的是,不要在兩邊同時打開同一個項目并同時修改,雖然不會立刻沖突,但文件監(jiān)聽和自動格式化可能互相打架,造成難以復(fù)現(xiàn)的奇怪問題。5. 那些讓我卡了半天的坑,以及我的排查順序5.1 服務(wù)在跑但連不上:從監(jiān)聽地址開始查最典型的現(xiàn)象:WSL2 里ps aux | grep sshd明明有進程,service ssh status也說 running,但外面就是連不上。這時候別急著懷疑網(wǎng)絡(luò),先確認它到底監(jiān)聽在哪個地址上:ss -tlnp | grep sshd如果輸出是127.0.0.1:2222而不是0.0.0.0:2222或[::]:2222,那問題就找到了——它只監(jiān)聽回環(huán),外部流量進不來。原因通常是sshd_config里有ListenAddress 127.0.0.1的殘留,或者被某個覆蓋配置改掉了。改成0.0.0.0重啟即可。我的排查順序固定為四步,基本能覆蓋九成情況:第一步看監(jiān)聽地址(ss -tlnp),第二步從本機連一次(ssh -p 2222 user127.0.0.1,排除認證問題),第三步從 Windows 連一次(區(qū)分是 WSL 內(nèi)部問題還是轉(zhuǎn)發(fā)問題),第四步從局域網(wǎng)第三臺設(shè)備連一次(區(qū)分是主機防火墻問題還是路由問題)。每一步只增加一個變量,這樣一旦某一步失敗,問題范圍立刻縮小一半。5.2 開了鏡像模式,宿主機反而連不上了這個坑很反直覺:改配置之前l(fā)ocalhost能連,改成鏡像模式之后反而連不上了。原因通常是端口沖突——鏡像模式下,WSL2 和 Windows 主機共享網(wǎng)絡(luò)端口空間,如果 Windows 上已經(jīng)有進程占了那個端口(比如前面提過的 Windows 自帶 SSH 服務(wù)占了 22),WSL 里的服務(wù)就綁不上,或者綁上了但流量被 Windows 那個進程接走了。驗證方法很直接:在 Windows 上netstat -ano | findstr :2222,看有沒有別的 PID 占著。有的話要么換端口,要么把占用進程停掉。我現(xiàn)在的習(xí)慣是給 WSL 的 SSH 固定用一個不常見的端口,徹底避開這類沖突,省得每次都要查。還有一種情況是防火墻的配置文件區(qū)分。Windows 防火墻對專用網(wǎng)絡(luò)和公用網(wǎng)絡(luò)的規(guī)則是分開的,你放行了專用網(wǎng)絡(luò),但當(dāng)前網(wǎng)卡被識別成公用網(wǎng)絡(luò),規(guī)則就不生效。表現(xiàn)是主機自己能連、局域網(wǎng)連不上。檢查方式是看網(wǎng)絡(luò)屬性里的配置文件類型,如果顯示公用,要么切換成專用,要么在防火墻規(guī)則里把公用網(wǎng)絡(luò)也勾上。5.3 IP 漂移導(dǎo)致的間歇性失敗,以及我怎么把它固定下來端口轉(zhuǎn)發(fā)方案下,最煩的不是配置麻煩,而是它會在你完全沒預(yù)期的時候失效。某天早上連不上,進去一看,WSL 地址從172.28.100.5變成了172.30.200.8,轉(zhuǎn)發(fā)規(guī)則還指著舊地址。這種失敗沒有任何報錯提示,只有超時,很容易誤判成服務(wù)掛了。我的解決辦法是把刷新邏輯寫成一個 PowerShell 腳本,登錄時自動執(zhí)行:$wslIp (wsl hostname -I).Trim().Split( )[0] if ($wslIp) { netsh interface portproxy delete v4tov4 listenport2222 listenaddress0.0.0.0 2$null netsh interface portproxy add v4tov4 listenport2222 listenaddress0.0.0.0 connectport2222 connectaddress$wslIp Write-Output 已刷新轉(zhuǎn)發(fā)規(guī)則 - $wslIp }這個腳本的關(guān)鍵在于先刪后加,因為add一個已存在的規(guī)則會報錯,而delete一個不存在的規(guī)則也會報錯,所以用2$null把刪除時的噪音吞掉。腳本執(zhí)行完可以用netsh interface portproxy show all確認當(dāng)前規(guī)則指向的地址是不是最新的。說到底,這個腳本解決的不是技術(shù)問題,而是把需要人工記住的事變成機器自動做的事。這類自動化在小規(guī)模環(huán)境里往往被忽略,覺得手動改一下也就半分鐘,但半分鐘乘以一年兩百次,加上每次都要重新回憶命令語法的時間成本,賬就不一樣了。6. 跑穩(wěn)之后我把配置固化下來的幾個習(xí)慣配置這東西,只要不落到文件里,過三個月自己都想不起來當(dāng)初改了什么。我現(xiàn)在給自己定了兩條規(guī)矩:第一,所有非默認的改動都寫進版本管理的 dotfiles 倉庫,包括.wslconfig、sshd_config的差異部分、Windows 側(cè)的 SSH config 和那個刷新腳本;第二,在倉庫根目錄放一個README,只寫為什么這么配而不寫怎么配,因為怎么配網(wǎng)上到處都有,為什么這么配才是三個月后真正需要的信息。具體到版本管理,sshd_config我不直接覆蓋系統(tǒng)文件,而是維護一份片段,用的時候手動合并或用配置片段目錄加載。這樣做的好處是系統(tǒng)升級時不會因為文件被改過而彈出一堆交互詢問。.wslconfig直接在倉庫里放一份完整版本,換機器時拷過去就行,內(nèi)容少,維護成本低。還有一個容易被忽略的固化點:把驗證步驟寫成腳本。我寫了一個很短的健康檢查腳本,依次檢查 sshd 進程、監(jiān)聽地址、Windows 側(cè)轉(zhuǎn)發(fā)規(guī)則、防火墻規(guī)則是否存在,全部通過就打印一行 OK。每次換機器或者系統(tǒng)大版本更新后跑一遍,比手動一項項確認快得多,也避免了以為配好了其實漏了一步的尷尬。最后分享一個我在反復(fù)重裝中總結(jié)出來的小經(jīng)驗:先跑通最小路徑,再逐層加固。最小路徑指的是:默認 sshd 配置 密碼登錄 端口轉(zhuǎn)發(fā),能在另一臺機器上ssh進去看到提示符,這一步通了,后面所有的密鑰、端口改號、systemd 接管、鏡像模式,都只是在這條已驗證的路徑上做替換,任何一步出問題都可以立刻回退到上一步可用的狀態(tài)。反過來,如果一上來就把所有優(yōu)化項全堆上去,一旦不通,你面對的是一堆未知變量的組合,排查成本會翻好幾倍。這套思路我在別的環(huán)境配置上也一直在用,屢試不爽。