SSH 協議基本原理及 wireshark 抓包分析


內容簡介:我們經常會使用我們也明白這是使用了SSH協議進行登陸,但我們想知道的是,為什么可以使用SSH協議進行登陸,而且為什么使用SSH就是安全的,其背后的原理是什么?下面我們就一起來探討下這幾個話題。

本文轉載自:https://juejin.im/post/5baaf517e51d453df0442dce,本站轉載出於傳遞更多信息之目的,版權歸原作者或者來源機構所有。

一、SSH協議簡介

我們經常會使用 ssh username@hostIp 命令登陸我們的 linux 服務器,如下圖所示:

SSH 協議基本原理及 wireshark 抓包分析

我們也明白這是使用了SSH協議進行登陸,但我們想知道的是,為什么可以使用SSH協議進行登陸,而且為什么使用SSH就是安全的,其背后的原理是什么?下面我們就一起來探討下這幾個話題。

當然啦!如果現在你手頭上有相關公網可訪問的雲主機,那么請你登陸你的雲主機,然后執行 grep sshd.*Failed /var/log/secure 命令看看,或許你會驚訝的發現有很多輸出日志,你就會明白到底有多少人想嘗試登陸你的主機了。

簡單地說,SSH協議是建立在不安全的網絡之上的進行遠程安全登陸的協議。它是一個協議族,其中有三個子協議,分別是:

  • 1、傳輸層協議 [SSH-TRANS] :提供 服務器 驗證、完整性和保密性功能,建立在傳統的TCP/IP協議之上。
  • 2、驗證協議 [SSH-USERAUTH] :向服務器驗證客戶端用戶,有基於用戶名密碼和公鑰兩種驗證方式,建立在傳輸層協議 [SSH-TRANS] 之上。
  • 3、連接協議 [SSH-CONNECT] :將加密隧道復用為若干邏輯信道。它建立在驗證協議之上。
SSH 協議基本原理及 wireshark 抓包分析

這里不對SSH協議做更加詳細的介紹,我們可以自行百度一下。下面的寫作思路將先通過wireshire抓包分析SSH協議上述三個流程,最后將提出整個學習過程中小編遇到的問題進行探討。

二、SSH協議握手過程分析

在接着下面的內容之前,這里有幾個概念非常重要!

  • 1、 會話密鑰 key :key是通過客戶端和服務器之間通過諸如D-H算法協商出來的。
  • 2、 公鑰 pub key :pub key成為 服務器主機密鑰server_host_key ,用於 SSH-TRANS 傳輸協議進行服務器驗證,說白了就是客戶端去驗證服務器用的

SSH協議握手過程大致流程如下圖所示:

SSH 協議基本原理及 wireshark 抓包分析

下面是小編通過wireshire工具抓的數據包,讓我們分別一步步進行分析:

SSH 協議基本原理及 wireshark 抓包分析
  • 1、TCP三次握手建立連接

我們都知道,TCP協議有個叫三次握手的過程,從上面圖中可以看出序號(647-649)即是TCP連接建立過程。

NO. 描述 seq Win ACK 解釋
647 第一次握手 0 8192 seq = 0表示客戶端當前的TCP包序列號
648 第二次握手 0 14600 1 seq = 0,表示服務器端當前的TCP包序列號
ack = 1(客戶端seq + 1),表示對客戶端第 seq = 0 的TCP包進行應答
649 第三次握手 1 65536 1 seq = 1,表示客戶端端當前的TCP包序列號
ack = 1(服務器seq + 1),表示對服務器端第 seq = 0 的TCP包進行應答
  • 2、SSH版本協議交換

上圖序號(647-649)即是SSH版本協議交換過程。

NO. 描述 解釋
650 協議版本協商 服務器將自己的SSH協議版本發送到客戶端,格式為: SSH-protoversion(版本號)-softwareversion(自定義) SP(空格一個,可選) comments(注釋,可選) CR(回車) LF(換行)
651 協議版本協商 客戶端將自己的SSH協議版本發送到服務器,格式為: SSH-protoversion(版本號)-softwareversion(自定義) SP(空格一個,可選) comments(注釋,可選) CR(回車符) LF(換行符)

這一步其實沒什么高大上的內容,就是發送一個格式為 SSH-protoversion-softwareversion SP comments CR LF 的字節流而已。

  • 3、密鑰協商key

上圖序號(652-677)即是SSH版本協議交換過程。

密鑰協商過程從客戶端和服務器相互發出 Key Exchange Init 請求開始,主要是告訴對方自己支持的相關加密算法列表、MAC算法列表等。

SSH 協議基本原理及 wireshark 抓包分析

最后協商成功之后,將會生成一個對稱加密 會話密鑰key 以及一個 會話ID ,在這里要特別強調,這個是對稱加密密鑰key,不要和公鑰相混淆了,公鑰和密鑰在上面開頭已經着重強調兩者的區別了,公鑰是給客戶端去驗證服務器用的。

在這一步中,公鑰會從服務器傳送到客戶端:

SSH 協議基本原理及 wireshark 抓包分析

而會話密鑰是通過D-H算法計算出來的,不會在網絡上傳輸,其破解的難度取決於離散對數的破解難度,一般不會被破解的,有興趣的可以自行了解該算法原理。

下面我將貼出 Key Exchange Init 發送的請求包數據分析

SSH 協議基本原理及 wireshark 抓包分析
NO. 描述 解釋
1 kex_algorithms 密鑰交換算法,里邊即包含我們使用的D-H算法,用於生成會話密鑰
2 server_host_key_algorithms 服務器主機密鑰算法,可以采用 ssh-rsa,ssh-dss,ecdsa-sha2-nistp256 ,有公鑰和私鑰的說法,公鑰即我們上面講到的pub key,對於公鑰私鑰的概念,可以參見 understanding public key private key concepts
3 encryption_algorithms_client_to_server 對稱加密算法,常用的有 aes128-cbc,3des-cbc
4 mac_algorithms_client_to_server MAC算法,主要用於保證數據完整性
5 compression_algorithms_client_to_server 壓縮算法
  • 4、認證階段

上圖序號(678-680)即是SSH版本認證階段。

  • 1、基於賬號和口令的驗證方式

    客戶端將自己的 用戶名 + 密碼 用上面生成的 會話密鑰key 進行加密之后傳送到服務器端進行驗證,服務器端驗證通過,則響應成功,否則在進行有限次(推薦是20次)重新認證。至於服務器是怎么驗證的,是否結合了會話ID小編也不清楚,網上眾說紛紜。

    注意,用戶名和密碼是采用上面密鑰協商階段生成的會話密鑰key進行加密的,包括后面的連接會話階段所傳送的數據都是,不要認為是采用服務器的pub key加密的

  • 2、基於公鑰和私鑰的驗證方式

    這種方式也稱為免密登陸。簡單地說,就是客戶端自己生成公鑰私鑰(通常采用ssh-keygen程序生成),然后將公鑰以某種方式(通常是手動添加)保存到服務器 ~/.ssh/authorized_keys 文件中,以后服務器都會接受客戶端傳過來的經過會話密鑰加密過的公鑰,然后解密得到公鑰之后和本地 authorized_keys 配置的公鑰是否相等,如果是,則允許登陸。

如果你配過github或者gitlab的公鑰,其實第二種方式認證方式很好理解,因為github它們也是采用SSH協議進行代碼克隆的,沒有配置公鑰好像是不允許克隆的。

三、相關問題

  • 1、密鑰協商階段安全嗎?有沒有中間人攻擊的情況!

就我的理解,第一次總是不安全的。為什么呢?上面說到協商過程中,服務器會將自己的公鑰 server_host_key_algorithms 發送給客戶端,但是客戶端無法保證它拿到的公鑰就是目標服務器所發出來的,很可能有個中間人攔截了你的請求,然后中間人發了另外一個公鑰給到你客戶端,這就不安全了!這也很好解釋了為什么我們第一次登陸的時候,Shell終端總是會出現這個提示的原因:

SSH 協議基本原理及 wireshark 抓包分析

這也是將確認權留給客戶端自己去判斷的一種策略。相反,如果想要更加安全,那么我們可以采用第二種認證方式進行登陸。由於提示的是經過MD5之后的公鑰,那么我們怎么判斷這個值是有效的呢?請看下面第3個疑問。

  • 2、傳輸協議協商出來的會話密鑰和會話ID到底有什么作用?

會話密鑰:對稱加密算法的密鑰,用於對通信數據進行加解密,會話ID有點像WEB中的Session,就是用來表示每一個會話的,同時在認證階段也起判斷是否同一會話有效的作用。

  • 3、既然密碼驗證登陸,那么客戶端第一次登陸的時候如何驗證服務器公鑰的正確性?

請你告訴小編吧!小編苦於找不到答案!

四、其他

下面是相關資料文檔:

我們可能會問了,既然有了SSH協議文檔,那么假如我們想要照着文檔寫一個實現出來,那么應該怎么去入手呢?其實SSH中的傳輸協議 [SSH-TARNS] 是基於TCP協議的,因此我們可以從創建一個最基本Java Socket套接字開始,逐步實現SSH的傳輸協議、認證協議以及連接協議。如果你對實現過程感興趣,可以研究下 ganymed-ssh2-build209.jar 中的源碼,結合SSH協議RFC文檔,你就會發現,其實SSH協議中的協商和認證過程,其實都是通過Socket輸入流、輸出流的形式實現的。小編自己擼到協商階段果斷放棄,原因是不懂得算法太多了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM