1. 引言

本文將詳細解釋對於每位工程師來說幾乎每天都會使用的「SSH」為何如此安全,以及其通信背後的過程。

2. SSH連線的全貌

首先,來看看從客戶端嘗試連接伺服器到安全通信開始的整體流程,在這個過程中發生這些互動。

接下來我們將逐步深入分析這些步驟。

3. 第1-2步:通信前的協商

在正式通信開始之前,客戶端和伺服器需要決定「使用哪種協議(加密方式)進行通信」的規則。

  • 版本交換:首先,雙方互相傳遞SSH的版本號。例如:「SSH-2.0-OpenSSH_8.2p1」。如果版本不相符,連接會在此時斷開。
  • 算法交換:接著,雙方會提供可用的加密技術列表。具體來說,對以下四種算法進行交換,雙方同意使用的方式:
    1. 鍵交換算法(例如: ecdh-sha2-nistp256
    2. 伺服器主機金鑰算法(例如: ecdsa-sha2-nistp256
    3. 對稱加密算法(例如: [email protected]
    4. 訊息認證碼(MAC)算法(例如: [email protected]

這一階段中,有意讓對方使用較舊(脆弱)算法的攻擊稱為「降級攻擊」。近期的SSH客戶端/伺服器已採取措施,默認禁用不安全的算法。

4. 第3-4步:主機認證與會話金鑰生成

當加密方式的規則確定後,接下來就開始確認通信對象和加密準備。

  • 主機認證:這一步是確認「目標伺服器是否真的為所需伺服器」。伺服器會將其「主機金鑰(私鑰)」簽名的數據發送給客戶端。客戶端則使用預先知道的(或在首次連接時保存的)伺服器的「主機金鑰(公鑰)」來驗證簽名。

    • 這一機制防止了中間人攻擊(Man-in-the-Middle Attack)
    • 在客戶端那邊,驗證後的伺服器主機金鑰會保存在 ~/.ssh/known_hosts 文件中。首次SSH連線經常出現的「確定要繼續連線嗎(是/否)?」是因為這個文件中還沒有鍵。
  • 鍵交換(DH/ECDH):確認主機安全後,將生成僅用於此次通信的「一次性金鑰(會話金鑰)」。此時「公鑰加密」技術發揮作用。

    • 通過迪菲-赫爾曼(DH)鍵交換,即使通信過程被竊聽,竊聽者也無法得知,客戶端和伺服器之間可以安全共享同一把「會話金鑰」。
    • 而這把會話金鑰將是接下來所有通信的加密「對稱金鑰」。

5. 第5步:用戶認證

確認了目標伺服器是正確的,且已做好加密準備後,最後一步是確認登錄伺服器的用戶是否「被允許的本人」。

  • 公鑰認證:用戶將其擁有的「私鑰」簽名的數據發送給伺服器,作為密碼的替代。伺服器使用預先登記的用戶「公鑰」來驗證簽名。
    • 因為不會將固定的資料像密碼一樣傳送到網路上,所以安全性非常高,暴力破解攻擊的風險也降低了。

6. 第6-7步:加密通信與防止篡改

所有準備工作完成後,從這裡開始,lscd等命令將安全地傳輸。

  • 加密通信(AES/ChaCha20):利用第4步生成的「會話金鑰」來加密所有通信內容。這樣一來,第三者無法窺探數據。
  • MAC(HMAC):檢查傳送的數據是否在途中被改寫(完整性)的機制。對會話金鑰和通信內容計算哈希值(MAC值)並加註於數據上。接收方同樣計算MAC值,並驗證與收到的MAC值是否一致。如不一致,則認為數據已被篡改,將直接丟棄。

7. 總結

您是否理解了SSH為何安全的背後步驟?
在理解理論的基礎上,最後透過「設置」來強化其安全性。以下介紹Linux中SSH的主要設定檔。

伺服器端的加固: /etc/ssh/sshd_config

如要管理伺服器,此檔案的設定是必須的,用以定義外部連線規則。

  • 禁用密碼認證與禁止root登錄

    # 禁止使用密碼登錄(僅允許公鑰認證)
    PasswordAuthentication no
    # 禁止root用戶直接登錄
    PermitRootLogin no
  • 使用強加密金鑰:建議RSA最少2048位,或使用更現代的Ed25519。

    # 使用Ed25519生成密鑰
    ssh-keygen -t ed25519
  • 禁止弱加密算法:舊的加密算法具有漏洞。僅允許推薦的強算法。

    # /etc/ssh/sshd_config 的設定範例
    KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256
    Ciphers [email protected],[email protected],[email protected]
    MACs [email protected],[email protected],[email protected]

客戶端設定: ~/.ssh/config

客戶端側透過~/.ssh/config來定義用戶個人的連接設定。(系統全域設定在 /etc/ssh/ssh_config

使用類似 ssh -i ~/.ssh/my_key.pem [email protected] -p 2222 的長命令可簡化為 ssh myserver

  • ~/.ssh/config 的設定範例

    # 創建命令: touch ~/.ssh/config && chmod 600 ~/.ssh/config
    # Web伺服器的連接設定
    Host web-server
      HostName 192.168.1.10
      User webadmin
      Port 22
      IdentityFile ~/.ssh/web_server_key
    
    # DB伺服器的連接設定
    Host db-server
      HostName db.example.com
      User dbuser
      Port 2222
      IdentityFile ~/.ssh/db_server_key
      # 每10秒發送存活確認包
      ServerAliveInterval 10
    
    # 連接GitHub的設定
    Host github.com
      HostName github.com
      User git
      IdentityFile ~/.ssh/id_ed25519_github

配置好後,您只需輸入 ssh web-serverssh db-server,即能以指定用戶、金鑰和端口進行連接。

正確理解SSH的機制,優化伺服器和客戶端雙方的設定,讓日常開發幸運且安全地進行。


原文出處:https://qiita.com/whoami_priv/items/9f165f8dfd95edb169b7


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝11   💬6   ❤️9
458
🥈
我愛JS
📝1   💬5   ❤️4
90
🥉
AppleLily
📝1   💬4   ❤️1
50
#4
💬1  
5
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次