OpenSSH/SSH 協議
OpenSSH 使用 SSH 協議,該協議透過 TCP 連線。通常,每個 TCP 連線都會建立一個 SSH 會話,但如果計劃使用多路複用,則可以將多個會話複用到單個 TCP 連線上。當前的安全外殼協議集是 SSH2。它是對舊的、已棄用的 SSH1 協議的重寫。它在安全性、效能和可移植性方面都進行了重大改進。現在預設使用 SSH2,並且 SSH1 支援已從客戶端和伺服器中刪除。

安全外殼協議是一個開放標準。因此,它是與供應商無關的,並由網際網路工程任務組 (IETF) 維護。當前協議在RFC 4250 到RFC 4256 中有描述,並由 IETF secsh 工作組進行標準化。SSH2 的總體結構在RFC 4251,安全外殼 (SSH) 協議架構中進行了描述。
SSH 協議由三層組成:傳輸層、身份驗證層和連線層。
- SSH-CONNECT – 連線層執行在使用者身份驗證協議之上。它將許多不同的併發加密通道多路複用到經過身份驗證的連線上的邏輯通道中。它允許隧道登入會話和 TCP 轉發。它為這些通道提供流控制服務。此外,還可以協商各種特定於通道的選項。此層管理 SSH 會話、會話多路複用、X11 轉發、TCP 轉發、shell、遠端程式執行、呼叫 SFTP 子系統。
- SSH-USERAUTH – 使用者身份驗證層對客戶端到伺服器進行身份驗證。它使用已建立的連線,並在傳輸層之上執行。它提供了幾種使用者身份驗證機制。這些包括密碼身份驗證、公鑰或基於主機的身份驗證機制、挑戰響應、可插拔身份驗證模組 (PAM)、通用安全服務應用程式程式設計介面 (GSSAPI) 甚至加密狗。
- SSH-TRANS – 傳輸層透過 TCP 提供伺服器身份驗證、機密性和資料完整性。它透過演算法協商和金鑰交換來實現這一點。金鑰交換包括伺服器身份驗證,並最終導致加密安全連線:它提供完整性、機密性和可選壓縮。 [1]
當前協議 SSH2 與已棄用的 SSH1 協議之間的差異之一是 SSH2 使用主機金鑰進行身份驗證。而 SSH1 使用伺服器金鑰和主機金鑰來進行身份驗證。關於協議本身,RFC 4251 [2] 中已經更詳細和權威地介紹了這些內容,因此這裡無法新增更多內容。
SSH 檔案傳輸協議 (SFTP) 是一種二進位制協議,用於提供安全的檔案傳輸、訪問和管理。
SFTP 由 Markus Friedl 在 2000 年 11 月 OpenSSH 2.3.0 版本釋出時新增到了伺服器端。Damien Miller 在 2.5.0 版本釋出時為客戶端添加了對 SFTP 的支援。從那時起,許多人都在客戶端和伺服器端添加了功能。
對於基本的檔案傳輸,只需要在執行 OpenSSH 伺服器的機器上擁有一個帳戶。SFTP 支援內置於 OpenSSH 伺服器軟體包中。與舊的 FTP 相比,SFTP 協議從一開始就被設計得儘可能安全,無論是登入還是資料傳輸。
除非用例要求公開可用的、只讀的下載,否則不要嘗試使用 FTP。FTP 協議本身固有地不安全。它非常適合只讀、公開資料傳輸。例如,程式 vsftpd 和 proftpd 就伺服器軟體本身而言是安全的,但協議本身仍然不安全。換句話說,程式本身或多或少是安全的,如果你需要提供只讀的、公開可用的下載,那麼 FTP 可能是合適的工具。否則,請忘記 FTP。當用戶請求“FTP”時,他們通常並不特指 1971 年RFC 114 中描述的舊檔案傳輸協議,而是泛指一種檔案傳輸方法,而解決此問題的方法有很多。這一點尤其正確,因為他們請求的下一部分通常是如何使其安全。術語“FTP”經常被泛化地用來表示任何檔案傳輸實用程式,就像“Coke”這個詞在美國南部的一些地方被用來表示任何碳酸飲料,而不只是可口可樂一樣。請考慮使用 SFTP,或對於更大的組,甚至 SSHFS、Samba 或 AFS。雖然舊的 FTP 在實現其主要目標方面非常成功,即透過允許網路上任何主機上的使用者使用任何合作主機上的檔案系統來促進網路計算機的使用,但它無法變得安全。對此無能為力,所以現在是時候克服它了。
再說一次,問題在於 FTP 協議本身。 [3] 使用 FTP 時,資料、密碼和使用者名稱都是未加密地來回傳送的。 [4] 客戶端子網、伺服器子網或兩者之間的任何子網上的任何人都可以“嗅探”使用 FTP 時的密碼和資料。透過額外的努力,可以將 FTP 包裹在 SSL 或 TLS 中,從而建立 FTPS。但是,將 FTP 隧道化到 SSL/TLS 上非常複雜,而且不是最佳解決方案。
不幸的是,由於名稱混淆以及包裹 FTP 在 SSL 中以提供 FTPS 這種複雜、挑剔的任務所產生的大量帖子和討論,這種錯誤的方式仍然經常出現在有關檔案傳輸的網路搜尋中。相比之下,簡單的、相對無痛的解決方案消失了,因為很少需要釋出如何執行這些操作。此外,一個簡單的解決方案可以用很少的幾行甚至一個答案來概括。因此,網路上仍然有很多關於“保護”FTP 的討論,而關於使用 SFTP 的討論卻很少。本書希望打破這一惡性迴圈:困難的任務意味著大量的討論和噪音,大量的討論和噪音意味著強大的網路存在感,強大的網路存在感意味著較高的 Google 排名。
SFTP 工具非常普遍,但可能被認為是理所當然的,因此被忽視。SFTP 工具易於使用,並且比舊的 FTP 客戶端功能更強大。事實上,在可用性方面已經取得了很大的進步。並不缺乏用於傳輸檔案的常見、基於 GUI 的 SFTP 客戶端:Filezilla、Konqueror、Dolphin、Nautilus、Cyberduck、Fugu 和 Fetch 位居榜首,但還有更多。大多數是免費軟體。再說一次,這些 SFTP 客戶端非常易於使用。例如,在 Konqueror 中,只需輸入 sftp 伺服器的 URL,其中伺服器名稱或地址為 xx.yy.zz.aa。
sftp://xx.yy.zz.aa
如果需要從特定目錄開始,則也可以指定該目錄。
sftp://xx.yy.zz.aa/var/www/pictures/
值得了解的一個特殊客戶端是sshfs。使用sshfs作為SFTP客戶端,另一臺機器可以作為您機器本地檔案系統上的一個開放資料夾訪問。透過這種方式,您通常用來處理檔案的任何程式,例如LibreOffice、Inkscape或Gimp,都可以透過該資料夾訪問遠端機器。
FTP 誕生於 1970 年代。它是久經考驗的功臣,但來自一個時代,那個時代如果你在網路上,你就應該在那裡,如果有問題,通常可以透過簡短的電話或一兩封電子郵件解決。它以未加密的方式傳送登入名、密碼和所有資料,供任何人攔截。FTP 客戶端可以使用被動或主動模式連線到 FTP 伺服器。FTP 的主動和被動模式[5] 使用兩個埠,一個用於控制,一個用於資料。在 FTP 主動模式下,客戶端與 FTP 伺服器建立連線後,它允許伺服器發起傳入連線以進行資料傳輸。在 FTP 被動模式下,客戶端與 FTP 伺服器建立連線後,伺服器會響應有關資料傳輸的第二個埠的資訊,然後客戶端發起第二個連線。FTP 現在最相關的應用是匿名 FTP,它仍然非常適合無需登入即可進行只讀下載。FTP 仍然是傳輸只讀資料的途徑之一,就像使用網路(HTTP 或 HTTPS)或 Bittorrent 等 P2P 協議一樣。因此,除了 FTP 之外,還有其他選擇可以提供只讀下載。最近,對於小檔案,首選 HTTPS;對於大檔案或大量檔案,首選 Bittorrent。
可以透過工具tcpdump來演示舊協議 FTP 如何不安全。它可以顯示在匿名 FTP 會話期間(或任何 FTP 會話)網路上發生了什麼。檢視tcpdump的手冊頁以瞭解各個引數的說明,下面的用法示例顯示了從客戶端到伺服器以及反之的第一批 FTP 或 FTP-Data 資料包。
下面的輸出顯示了從tcpdump輸出中摘錄的部分,該輸出捕獲了 FTP 客戶端和 FTP 伺服器之間的資料包,每行一個數據包。
$ sudo tcpdump -q -s 0 -c 10 -A -i eth0 \
"tcp and (port ftp or port ftp-data)"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
…
:18:36.010820 IP desk.55227 > server.ftp: tcp 16 E..D..@.@.....1.[.X.....G.r. ........l..... ."......USER anonymous
:18:36.073192 IP server.ftp > desk.55227: tcp 0 E..4jX@.7.3.[.X...1..... ...G.r#........... ....."..
:18:36.074019 IP server.ftp > desk.55227: tcp 34 E..VjY@.7.3.[.X...1..... ...G.r#....Y...... ....."..331 Please specify the password.
:18:36.074042 IP desk.55227 > server.ftp: tcp 0 E..4..@.@..+..1.[.X.....G.r# ..)........... ."......
:18:42.098941 IP desk.55227 > server.ftp: tcp 23 E..K..@.@.....1.[.X.....G.r# ..)....gv..... .".w....PASS user@example.net
:18:42.162692 IP server.ftp > desk.55227: tcp 23 E..KjZ@.7.3.[.X...1..... ..)G.r:........... .....".w230 Login successful.
…
:18:43.431827 IP server.ftp > desk.55227: tcp 14 E..Bj\@.7.3.[.X...1..... ..SG.rF.....j..... ....."..221 Goodbye.
…
正如在第 3 行和第 7 行中看到的那樣,伺服器的文字等資料是可見的。在第 1 行和第 5 行中,使用者輸入的文字是可見的,在這種情況下,它包括用於登入的使用者名稱稱和密碼。幸運的是,該會話是匿名 FTP,它是隻讀的,用於下載。匿名 FTP 是釋出下載資料的一種非常有效的方式。對於匿名 FTP,使用者名稱始終是 "anonymous",密碼是使用者的電子郵件地址,並且伺服器的資料始終是隻讀的。
如果您已經安裝了 OpenSSH 伺服器包,則無需進一步配置伺服器即可開始使用 SFTP 進行檔案傳輸。雖然相比而言,FTPS 比 FTP 安全得多。如果您想要遠端遠端登入訪問,那麼應該避免使用 FTP 和 FTPS。避免使用它們的一個非常重要的原因是節省工作量。
FTPS 是透過 SSL 或 TLS 隧道化的 FTP。FTP 的目標是鼓勵使用遠端計算機,這與網路一起取得了成功。FTPS 的目標是保護登入和傳輸,這是使用舊協議保護檔案傳輸的必要步驟。但是,由於 SFTP 的部署非常容易,而且大多數系統現在都包含圖形和基於文字的 SFTP 客戶端,因此對於大多數情況而言,FTPS 實際上可以被認為是過時的。
您可以在 FTP 和 FTPS 的請求 for Comments (RFC) 中找到一些很好的背景資料。在那裡,SFTP 甚至 HTTPS 更加匹配,並且在很大程度上取代了 FTPS。請參閱有關客戶端應用程式的部分,瞭解可用的 SFTP 客戶端。
特權分離是指將程序分成多個子程序,每個子程序只對系統中的特定部分擁有足夠的訪問許可權,以執行其工作。特權分離的目標是將任何損壞隔離,並防止損壞的程序訪問系統的其他部分。其基本原則是最小特權,即每個程序只有完成任務所需的特權,不多也不少。目前是這樣的[6]
sshd [listener] | exec | sshd-session [privsep monitor] | | | exec | | | sshd-auth: [net unpriv] | fork (after auth completes) | sshd-session [postauth unpriv]
首先,一個特權二進位制檔案監聽傳入連線。
$ ps -a -x -w -o user,pid,ppid,args | grep '[s]shd'
root 2460 1 sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups (sshd)
連線開始後,它會被傳遞給一個單獨的特權監控器二進位制檔案(在下文中顯示為 PID 46495),該二進位制檔案以 'sshd' 帳戶在非特權 exec 下執行(在下文中顯示為 PID 96923)以處理身份驗證。
$ ps -a -x -w -o user,pid,ppid,args | grep '[s]shd'
root 2460 1 sshd: /usr/sbin/sshd [listener] 1 of 10-100 startups (sshd)
root 46495 2460 sshd-session: fred [priv] (sshd-session)
sshd 96923 46495 sshd-auth: fred [net] (sshd-auth)
'sshd' 擁有的 fork 被終止,如果身份驗證成功,一個新的程序由已驗證的帳戶擁有,從監控器中分叉(在下文中顯示為 PID 94635)以處理會話本身。
$ ps -a -x -w -o user,pid,ppid,args | grep '[s]shd'
root 2460 1 sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups (sshd)
root 46495 2460 sshd-session: fred [priv] (sshd-session)
fred 94635 46495 sshd-session: fred@ttyp1 (sshd-session)
這是一個正在進行的工作,未來的發展可能會將身份驗證後的非特權程序移入一個單獨的二進位制檔案。行動式版本可能會獲得一個 PAM 幫助程式二進位制檔案,它將由特權分離監控器呼叫。
自版本 3.3[7] 起,特權分離成為 OpenSSH 的預設設定。從版本 5.9 開始,特權分離進一步對特權分離子程序可以執行的系統呼叫施加強制限制。其目的是防止被入侵的特權分離子程序被用來攻擊其他主機,無論是透過開啟套接字進行代理,還是透過探測本地核心攻擊面。[8] 自版本 6.1 起,這種沙箱已成為預設設定。

OpenSSH 中的特權分離是透過使用多個級別的訪問許可權(有些級別較高,有些級別較低)來執行sshd(8)及其子系統和元件來實現的。SSH 伺服器 ➊ 最初使用特權程序 ➋,然後建立一個非特權程序 ➌ 來處理網路流量。使用者經過身份驗證後,會建立另一個非特權程序 ➍,該程序擁有已驗證使用者的特權。請參閱 "OpenSSH 特權分離的時序圖"。正如在圖中看到的那樣,總共運行了四個程序來建立一個 SSH 會話。一個程序(伺服器)保持執行,監聽新連線並生成新的子程序。
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER PID PPID STAT STARTED COMMAND
root 1473 1 I 05:44:01 sshd: /usr/sbin/sshd [listener] 0 of 10-10
正是這個特權程序監聽來自客戶端的初始連線。在這裡,它正在等待並監聽埠 22。
$ netstat -ntlp | awk '/sshd/ || NR<=2'
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1473/sshd
tcp6 0 0 :::22 :::* LISTEN 1473/sshd
在初始連線建立後,在等待使用者 'fred' 的密碼身份驗證時,一個特權監控器程序監督 'sshd' 使用者的非特權程序,該程序處理與遠端使用者的客戶端的聯絡。
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER PID PPID S STARTED COMMAND
root 1473 1 S 05:44:12 sshd: /usr/sbin/sshd [listener] 1 of 10-10
root 9481 1473 S 14:40:37 sshd: fred [priv]
sshd 9482 9481 S 14:40:37 sshd: fred [net]
然後,在身份驗證完成後,為使用者 'fred' 建立一個會話後,會建立一個新的特權監控器程序來監督以使用者 'fred' 身份執行的程序。此時,以使用者 'sshd' 身份執行的另一個程序已經消失。
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER PID PPID S STARTED COMMAND
root 1473 1 S 05:44:12 sshd: /usr/sbin/sshd [listener] 0 of 10-10
root 9481 1473 S 14:40:37 sshd: fred [priv]
fred 9579 9481 S 14:42:02 sshd: fred@pts/30
再次強調,這是針對舊的特權分離方法。
- ↑ "OpenSSH 手冊頁". OpenSSH. 檢索於 2011-02-17.
- ↑ "RFC 4251:安全 Shell (SSH) 協議體系結構". 2006. 檢索於 2013-10-31.
- ↑ "為什麼您需要停止使用 FTP". JDPFu.com. 2011-07-10. 檢索於 2012-01-09.
- ↑ Manolis Tzanidakis (2011-09-09). "停止使用 FTP!如何安全地傳輸檔案". Wazi. 檢索於 2012-01-09.
- ↑ Jay Ribak (2002). "主動 FTP 與被動 FTP,權威解釋". Slacksite.com. 檢索於 2020-03-20.
- ↑ "9.8 中的 sshd 二進位制檔案拆分?". openssh-unix-dev 郵件列表. 2024-07-17. 檢索於 2024-07-30.
- ↑ Nils Provos (2003). "特權分離的 OpenSSH". 密歇根大學. 檢索於 2011-02-17.
- ↑ "OpenSSH 5.9 版本說明". OpenSSH. 2011-09-06. 檢索於 2012-11-17.