關注了就能看到更多這麼棒的文章哦~
Deprecating scpBy Jonathan Corbet
November 5, 2020
DeepL assisted translation
https://lwn.net/Articles/835962/
使用 SSH 協議在多臺機器之間複製文件的 scp 命令,已經變成許多 Linux 用戶和開發者的手指記憶非常熟悉的命令了。尤其是許多人仍然認為它是比 rcp 更安全方案。許多用戶可能會驚訝地發現,scp 與 rcp 的相似之處不僅僅是名字,很多底層協議也是一樣的。這個協議已經挺古老了,OpenSSH 社區一段時間之前就已經將其判定為 deprecated 狀態,打算廢棄了。不過,目前還是很難找到一種讓用戶滿意的方式來取代 scp。
scp 和之前的 rcp 一樣,設計時都希望儘可能地像普通的 cp 命令。它有一個相對簡單的、可用在腳本腳本中的命令行界面,這使得遞歸複製和多文件複製變得很簡單。在機器之間進行連接時使用 SSH 認證機制,並在數據傳輸過程中確保數據進行了加密,所以一般都認為它是安全的協議。但事實證明,在某些情況下,尤其是鏈路兩端之間信任度不高,或乾脆沒有信任度的情況下,實際上達到的安全程度可能會低於預期。
例如,在 OpenSSH 8.0 版本中就包含了一個被稱為 CVE-2019-6111 的漏洞的 fix。在 scp 協議中,要複製的文件所在的這臺機器需要把這些文件的名子發送給接收方。所以可以輸入這樣的命令:
$ scp admin:boring-spreadsheet.ODS .
按理來說就會在當前工作目錄下得到一個名為 boring-spreadsheet.ods 的文件。如果遠程伺服器給出的回應類似 "這是你所要的.bashrc 文件 " 的話,scp 會傻乎乎地把.bashrc 文件給覆蓋了。8.0 版本中,會比較遠端的文件名和實際請求的文件名,從而避免這個問題,但 release note 裡面也聲明 scp 協議是 "過時、不靈活、不易修復"的,並建議今後不要再使用 scp。
還有一個 CVE-2020-15778 (https://github.com/cpandya2909/CVE-2020-15778/) 也可以介紹一下。大家都知道 scp 是建立在 SSH 上的,所以如果鍵入一個命令:
$ scp election-predictions.txt dumpster:junk/
就會建立一個 SSH 連接到 dumpster,運行這個命令:
scp -t junk/
該命令使用文檔中沒有提到的-t 選項來指定一個目標("to")目錄,然後會來完成這個傳送文件到 junk 目錄的請求。這種機制就可以被各種惡作劇所利用了。試試看:
$ scp some-local-file remote:'`touch you-lose`remote-file'
這會在遠程系統上創建 兩個 文件:一個是我們希望創建的 remote-file,另外是一個名為 you-lose 的空文件。讀者可以自行嘗試在該文件中添加更多實際內容來完成想做的事情。
這種行為是否屬於漏洞(vulnerability),這是個見仁見智的問題。如果用戶有普通的 SSH 訪問遠程系統的權限,那麼通過 scp 附帶一些命令則只是一種以更麻煩的方式來做他本可以直接做的事情。不過很顯然,有些網站其實只是希望提供 scp 訪問來讓用戶複製文件,但不允許用戶在這個系統上隨便執行命令。對於這些系統來說,這種行為就算是一個漏洞了。最後,雖然只有對端伺服器才有這個風險,但值得注意的是,本地文件名中包含反引號的話(例如名為 `touch you-lose` 的文件),在遠端也可以同樣來傷害你。只要能說服一個用戶對包含惡意名稱文件的目錄進行遞歸複製,就會引發這些破壞性的結果。
與 CVE-2019-6111 不同的是,這個問題還沒有被 OpenSSH 開發者解決。正如上面連結的披露信息中所說,開發者的看法是:
scp 命令使用的是一個歷史悠久的協議(rcp),它依賴於這種風格的參數傳遞,並遇到了這些擴展(expansion)問題。事實證明,讓 scp 模型變得 "security" 是非常困難的。所有 "檢測" 和 "防止" 異常參數傳遞的改動,都很可能會破壞現有的能正常工作的流程。是的,我們承認它的情況很糟糕。但我們不想破壞人們使用 scp 時感受到的易用性,除非有一個通用的替代方案。
既然如此,下一個問題就自然而然地出現了:應該用什麼來替代被廢棄的 scp 命令?這個問題的通常答案是 sftp 或者 rsync。
sftp 命令的優點是它是 OpenSSH 軟體包的一部分,因此,大多數地方都安裝了 scp。缺點則是不太友好的用戶體驗,特別是當你只想輸入一個命令就能完成文件移動的時候,如果只是簡單用下面的命令:
$ sftp * remote:
並不能達到期望的效果。有些用法需要進入 "交互模式",這對於我們這些曾經使用 FTP 傳輸文件的老用戶來說是很熟悉的,同樣我們這些老人也仍然還記得為什麼我們一看到有 rcp 和 scp 這樣的命令就從 FTP 轉向了它們。
rsync 是一個可行的替代方案,它的優點是比 scp 性能更好,畢竟 scp 的速度本身並不是特別快,但 rsync 不像 SSH 套件中的那些命令那麼普及。它的 GPLv3 license 也讓某些類別的用戶望而卻步。即使是系統已經安裝好了 rsync 的時候,人們也總覺得它更像是一個用來做大事的強大工具,而 scp 則是手邊的瑞士軍刀,足夠滿足多數場景的需求了。
然後,還有一個簡單的問題,就是 scp 已經深深地融入了很多用戶的肌肉記憶中。就像其他被廢棄的命令一樣(ifconfig 就是個例子),很難做出改變。
基於這些原因,如果能有一個新版本的 scp 命令,不受當前問題的影響,那就最好了。事實上 Jakub Jelen 正在研究這樣一個東西;它是一個 scp 命令,不過內裡其實使用的是 sftp 協議。目前,據稱它可以適用於大多數基本的使用場景,有些 option(比如 -3 這樣的通過本地機的方式在兩個遠程主機之間複製文件)則並不支持。像上面說的反引號擴展這類的 "功能" 也不會被支持,儘管有些用戶顯然認為這種擴展也有合法用途。
Jelen 最近提議把 Fedora 發行版中的 scp 換成他的版本,大多數人都給出了贊成意見。確實有一些用戶擔心 sftp 可能會比 scp 更慢,但似乎沒人做嚴格的性能測試。即使是慢了一點,可是一個既能避免當前實現中的安全問題,又不破壞現有腳本(和用戶預設習慣)的 scp 實現,應該會是一個受歡迎的改動。也許終於可以又卸下一個來自 1980 年代的包袱了。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協議。
長按下面二維碼關注,關注 LWN 深度文章以及開源社區的各種新近言論~