在整個通訊過程中,為實現SSH的安全連接,服務器端與客戶端要經歷如下五個階段:
1. 版本號協商階段
SSH目前包括SSH1和SSH2兩個版本,雙方通過版本協商確定使用的版本
具體步驟如下:
服務器打開端口22,等待客戶端連接。
客戶端向服務器端發起TCP初始連接請求。
TCP連接建立后,服務器向客戶端發送第一個報文,包括版本標志字符串,格式為“SSH-<主協議版本號>.<次協議版本號>-<軟件版本號>”,協議版本號由主版本號和次版本號組成,軟件版本號主要是為調試使用。
客戶端收到報文后,首先解析該數據包,通過與服務器端的協議版本號進行對比,決定要使用的協議版本號。如果服務器端的協議版本號比自己的低,且客戶端能支持服務器端的低版本,就使用服務器端的低版本協議號,否則使用自己的協議版本號。然后,客戶端回應服務器一個報文,包含了客戶端決定使用的協議版本號。
服務器比較客戶端發來的版本號,如果服務器支持該版本,則使用該版本,并進入密鑰和算法協商階段,否則,版本協商失敗,服務器端斷開TCP連接。
上述報文都是采用明文方式傳輸的。
2. 密鑰和算法協商階段
具體步驟如下:
服務器端和客戶端分別發送算法協商報文給對端,報文中包含自己支持的公鑰算法列表、加密算法列表、mac(Message Authentication Code,消息驗證碼)算法列表、壓縮算法列表等。
服務器端和客戶端根據對端和本端支持的算法列表得出最終使用的算法。任何一種算法協商失敗,都會導致服務器端和客戶端的算法協商過程失敗,服務器將斷開與客戶端的連接。
服務器端和客戶端利用DH交換(Diffie-Hellman Exchange)算法、主機密鑰對等參數,生成會話密鑰和會話ID,并完成客戶端對服務器身份的驗證。
通過以上步驟,服務器端和客戶端就取得了相同的會話密鑰和會話ID。對于后續傳輸的數據,兩端都會使用會話密鑰進行加密和解密,保證了數據傳送的安全。會話ID用來標識一個SSH連接,在認證階段,會話ID還會用于兩端的認證過程。
3. 認證階段
SSH提供兩種認證方法:
password認證:利用AAA(Authentication、Authorization、Accounting,認證、授權和計費)對客戶端身份進行認證。客戶端向服務器發出password認證請求,將用戶名和密碼加密后發送給服務器;服務器將該信息解密后得到用戶名和密碼的明文,通過本地認證或遠程認證驗證用戶名和密碼的合法性,并返回認證成功或失敗的消息。如果遠程認證服務器要求用戶進行二次密碼認證,則會在發送給服務器端的認證回應消息中攜帶一個提示信息,該提示信息被服務器端透傳給客戶端,由客戶端輸出并要求用戶再次輸入一個指定類型的密碼,當用戶提交正確的密碼并成功通過認證服務器的驗證后,服務器端才會返回認證成功的消息。
publickey認證:采用數字簽名的方法來認證客戶端。目前,設備上可以利用DSA和RSA兩種公鑰算法實現數字簽名。客戶端發送包含用戶名、公鑰和公鑰算法的publickey認證請求給服務器端。服務器對公鑰進行合法性檢查,如果不合法,則直接發送失敗消息;否則,服務器利用數字簽名對客戶端進行認證,并返回認證成功或失敗的消息
4. 會話請求階段
認證通過后,客戶端向服務器發送會話請求。服務器等待并處理客戶端的請求。請求被成功處理后,服務器會向客戶端回應SSH_SMSG_SUCCESS包,SSH進入交互會話階段;否則回應SSH_SMSG_FAILURE包,表示服務器處理請求失敗或者不能識別請求。
5. 交互會話階段
會話請求成功后,連接進入交互會話階段。在這個階段,數據被雙向傳送。客戶端將要執行的命令加密后傳給服務器,服務器接收到報文,解密后執行該命令,將執行的結果加密發送給客戶端,客戶端將接收到的結果解密后顯示到終端上。