我在終端里執行了一次看似無害的遷移:將bash與zsh的職責分離,清空了.bashrc,讓終端環境變得無比整潔。第二天打開Obsidian,卻發現Git同步已經悄然罷工,提示git@github.com: Permission denied (publickey)。初看像是切換到zsh搞壞了Obsidian,但shell本不該背這個鍋——問題的本質是ssh-agent的作用域沒有穿透圖形界面程序的進程邊界。下面這份記錄,就是我如何一步步揪出元兇,又如何在Flatpak沙盒的圍欄里摸索修復之路的過程。
檢查終端里的SSH狀態,一切正常:echo "$SSH_AUTH_SOCK"返回/run/user/1000/gcr/ssh,ssh-add -l也能列出work-github和personal-github兩個密鑰。然而Obsidian的Git插件卻反復索要passphrase,完全無視已經加載的私鑰。終端下的zsh能走通,圖形界面下啟動的Obsidian卻請求失敗,這就把問題清晰拆成兩個世界:命令行與桌面應用的認證通道是割裂的。從shell里啟動的ssh-agent,其環境變量只對被這個shell fork出的子進程可見;而Obsidian是由桌面環境直接調起,它根本不會讀取.zshrc,也永遠觸碰不到那個ssh-agent的套接字。所以這根本不是shell配置的事故,而是一場針對系統登錄會話設計的深度診斷。
一個自然而然的疑問浮現:以前把所有環境變量塞進.bashrc時,Obsidian Git明明工作得好好的,這又怎么解釋?答案繞不開GNOME Keyring,也就是那個常被稱為gcr的組件。gcr-ssh-agent與GNOME的登錄會話深度集成,只要登錄密鑰環被解鎖,它就會自動向系統廣播SSH密鑰的可用性。這意味著舊配置下的Obsidian從來沒依賴過shell初始化的ssh-agent,它自始至終都在直接與gcr通信,由GNOME Keyring在背后默默填充之前保存的passphrase。也就是說,原來的順暢并非因為passphrase自動跳過,而是因為GNOME Keyring這個幕后管家在替用戶一次次地完成私鑰的解鎖工作。
既然gcr-ssh-agent曾經能覆蓋桌面應用,我首先想到的修復方向,就是讓終端、編輯器、Obsidian乃至Flatpak程序全部通過同一個gcr套接字完成認證。這個套接字路徑統一為/run/user/1000/gcr/ssh,我通過flatpak override命令將gcr的運行時目錄和SSH_AUTH_SOCK環境變量暴露給了Obsidian的Flatpak沙盒,命令如下:flatpak override --user --filesystem=xdg-run/gcr --env=SSH_AUTH_SOCK=/run/user/1000/gcr/ssh md.obsidian.Obsidian。當時的效果立竿見影,GitHub認證通過,我一度認為問題已經根治。
重啟之后,一切又回到了原點。這次的表現更詭異:ssh-add -l仍然能列出兩個密鑰,但ssh -T github-personal卻直接掛起,簽名請求如同掉進了黑洞。詳細的調試日志暴露了關鍵細節:GitHub在ssh連接過程中確實接受了公鑰(Server accepts key: id_ed25519_personal),可就在進入signing using ssh-ed25519步驟時,整個流程僵住,再也沒有回音。gcr-ssh-agent對簽名任務的袖手旁觀,使得整個認證管道卡在了最后一厘米。
另一條線索則來自一個看似無意義的現象:執行ssh-add -D刪除所有身份標識后,ls再次列出密鑰,就像刪除從未生效。這暴露出gcr的自動發布機制——只要密鑰環里存有私鑰信息,gcr就會立即將它們重新推送給ssh-agent,哪怕這個自動恢復后的狀態已經無法完成簽名操作。也就是說,gcr-ssh-agent此時的緩存是一個殘廢的鏡像,它能列出密鑰輪廓,卻已喪失真正的加簽能力。面對這個半死不活的狀態,我想要去Seahorse中刪除對應的SSH密鑰條目,卻發現那項操作很可能連實際存放在~/.ssh/目錄下的id_ed25519_personal私鑰文件也一并抹去,風險高到讓人停手。
問題至此被充分剖開:不是zsh背叛了Obsidian,而是ssh-agent的進程作用域根本就是按樹狀繼承的,桌面啟動器這棵大樹并不承認shell枝杈上掛載的認證代理。GNOME Keyring雖然試圖在會話層級彌合這一裂谷,卻因為自身緩存與簽名操作的斷裂,最終引發了更隱蔽的假通過。而對于被Flatpak沙盒包裹的Obsidian而言,它對外部文件系統和環境變量的訪問又被加上了一層隔離,除非精確地通過override指令開窗,否則根本無法嗅探到桌面級代理的套接字。三套機制——shell初始化、GNOME會話服務、Flatpak沙盒——彼此重疊又相互遮蔽,讓一次本應簡潔的shell遷移,演變成一臺多陣營的信號斷連劇。
這次追蹤也留下了清晰的教訓:別再假設終端與GUI應用共用同一個認證上下文。如果你正在把shell從bash遷移到zsh,不妨順手檢查一下SSH_AUTH_SOCK的實際來源,確認桌面環境與Flatpak套件是否都能通過同一路徑看到你的私鑰。有時真正的問題并不是配置寫錯了,而是你以為已經交給系統代理的事情,其實從未走出那個shell進程的子進程圈子。當一切風平浪靜時,可能是GNOME Keyring在替你負重前行;但當它的自動發布邏輯出現裂痕,你才會突然發現,自己已經被困在好幾個沙盒的迷宮中心。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.