Linux 之七 SSH、SSL、OpenSSH、OpenSSL、LibreSSL
??在上一篇博文 Linux 之四 Ubuntu 20.04 WiFi 無法使用、設置無法顯示、遠程桌面、SSH、Git、PPA 等各問題記錄 中,曾試圖使用遠程桌面功能來連接使用我的 Ubuntu 20.04,但實際情況是遠程桌面卡的是慘不忍睹,無奈還是得用 SSH 遠程登錄。
??在網上找了很多 SSH 相關的文章,好記性不如爛筆頭,這里整理一下,做個備忘錄!
SSH
??SSH 為 Secure Shell 的縮寫(雖然名字中有個 Shell,但他實際并不是 Shell),由互聯網工程任務組(Internet Engineering Task Force,IETF)的網絡小組(Network Working Group)所制定一個網絡協議。SSH 是一種建立在應用層基礎上的加密的網絡協議。但是,就和 SSL 類似,它有不是僅僅工作在應用層(映射到 TCP/IP 模型)!如下圖是 OSI 參考模型與 TCP/IP 模型對比:
??SSH 的經典用途是登錄到遠程電腦中執行命令。除此之外,SSH 也支持隧道協議、端口映射和 X11 連接。借助 SFTP 或 SCP 協議,SSH 還可以傳輸文件。
??SSH 協議有兩個主要版本,分別是 SSH-1 和 SSH-2,兩者不兼容。2006 年,SSH-2 協議成為了新的標準,而且目前我們使用的 SSH 大多數都是 SSH-2 版本的 SSH,其標準主要有 :
- RFC 4250 – The Secure Shell (SSH) Protocol Assigned Numbers
- RFC 4251 – The Secure Shell (SSH) Protocol Architecture
- RFC 4252 – The Secure Shell (SSH) Authentication Protocol
- RFC 4253 – The Secure Shell (SSH) Transport Layer Protocol
- RFC 4254 – The Secure Shell (SSH) Connection Protocol
- RFC 4255 – Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
- RFC 4256 – Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
- RFC 4335 – The Secure Shell (SSH) Session Channel Break Extension
- RFC 4344 – The Secure Shell (SSH) Transport Layer Encryption Modes
- RFC 4345 – Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
關于 RFC:
此外,關于 SSH 的幾個專有名詞也需要區分一下:
- SSH: 通用術語,指 SSH 協議 或 基于 SSH 協議的軟件產品
- SSH-1: SSH 協議版本 1。SSH 協議有多個修訂版,其中最為大家熟知的是 1.3 和 1.5
- SSH-2: SSH 協議版本 2。這是由 IETF 的 SECSH 工作組的若干標準文件中定義名稱
- SSH1: 通常代指 Tatu Yl?nen 實現的 SSH 協議版本 1 的軟件名字
- SSH2: SSH Communications Security, Inc. (http://www.ssh.com) 實現的 SSH 協議版本 2 的軟件名字,這是一個SSH 協議版本 2 的商業版軟件實現
- ssh: 全部小寫的 ssh 是 OpenSSH 中實現的 SSH 客戶端的軟件名字,這也是如今我們使用最多的 SSH 軟件。
歷史
架構
??SSH 的軟件架構采用了服務器-客戶端模式(Server - Client),默認的端口為 22。SSH 通過在網絡中創建安全隧道來實現 SSH 客戶端與服務器之間的連接。整體架構如下圖所示:
??SSH 協議有兩個主要版本,分別是 SSH-1 和 SSH-2,這兩個版本的協議是不兼容的!與 SSH-1 相比,SSH-2 進行了一系列功能改進并增強了安全性,還支持通過單個SSH 連接任意數量的 shell 會話。兩者架構對比如下所示:
??SSH-1 被設計為一個整體,在這個單個協議中定義了多個不同的功能,而 SSH-2 則被設計為分成不同的模塊層,共由三種協議組成:
- Transport Layer Protocol: 該協議兼容服務器身份驗證、私密性和完整性,具有完美的前向私密性。這一層可以提供可選的壓縮,并通過TCP/IP 連接運行,但也可以在任何其他可靠的數據流之上使用。
- User Authentication Protocol: 該協議向服務器驗證客戶端,并在傳輸層上運行。
- Connection Protocol: 該協議通過用戶認證協議將加密通道多路復用到多個邏輯通道。
OpenSSH
??SSH 只是一種協議,存在多種實現,既有商業實現,也有開源實現。目前,OpenSSH 是最流行的 SSH 實現,而且成為了大量操作系統的默認組件。OpenSSH 仍在積極維護中,而且已經支持 SSH-2 協議。從 7.6 版開始,OpenSSH 不再支持 SSH-1 協議。官網:https://www.openssh.com/ 。OpenSSH 主要包含以下工具:
- 客戶端工具 ssh、scp、sftp
- ssh:ssh 客戶端,是一個用于登錄到遠程計算機并在遠程計算機上執行命令的程序。
- scp:用于在網絡上的主機之間復制文件
- sftp:一個文件傳輸程序,類似于 ftp,它通過加密的 ssh 傳輸執行所有操作。
- 密鑰管理工具 ssh-add、ssh-keysign、ssh-keyscan、ssh-keygen
- ssh-add:用于將私鑰標識添加到身份驗證代理(ssh-agent)。在沒有參數的情況下運行時,它會添加文件 ?/.ssh/id_rsa,?/.ssh/id_dsa,?/ .ssh/id_ecdsa,?/.ssh/id_ecdsa_sk,?/.ssh/id_ed25519 和 ?/.ssh /id_ed25519_sk。加載私鑰后,ssh-add 將嘗試從以-cert.pub 結尾的文件中加載相應的證書信息。
- ssh-keysign:ssh 使用 ssh-keysign 訪問本地主機密鑰并生成基于主機身份驗證所需的數字簽名。默認情況下,該功能是被禁用的,且該程序一般不需要用戶調用,而是由 ssh 程序自動調用。
- ssh-keyscan:用于收集其他主機的公共 SSH 主機鍵的實用程序。它旨在幫助構建和驗證 SSH_KNOKN_HOSTS 文件。
- ssh-keygen:OpenSSH 身份驗證密鑰實用程序
- 服務端工具 sshd、sftp-server、ssh-agent
- sshd:即 OpenSSH Daemon,是 ssh 的守護程序,也即 SSH 的服務端程序。它通過不安全的網絡在兩個不受信任的主機之間提供安全的加密通信。
- ssh-agent:用來保存用于公鑰身份驗證的私鑰。通過使用環境變量,它可以在使用 ssh 登陸其他計算機時,定位并自動處理身份驗證。
- sftp-server:sftp 服務端程序,用來接收并處理來自 sftp 的連接。改程序通常也不需要由用戶調用,而是由 ssh 來調用
詳細的介紹及使用方法,可以參考 OpenSSH 官方文檔:https://www.openssh.com/manual.html。
??在這個架構中,SSH 軟件分成兩個部分:向服務器發出請求的部分,稱為客戶端(client),OpenSSH 的實現為 ssh;接收客戶端發出的請求的部分,稱為服務器(server),OpenSSH 的實現為 sshd。
??目前,SSH 已經成為了類 Unix 系統的標配組件,直接在 Ubuntu 終端中輸入 ssh -V 就可以查看 Ubuntu 自帶了 ssh 客戶端的版本,我這里的版本號是 OpenSSH_8.2p1。
然而 Ubuntu 默認并沒有安裝 ssh server,因此需要自己安裝:sudo apt-get install openssh-server,安裝之后,查看一下:
第一個查看安裝了 ssh 相關的包,第二個查看 ssh 服務器有沒有運行(ssh-agent 表示 ssh-client 啟動,sshd 表示 ssh-server 啟動)!
??注意,第一次安裝之后,SSH 服務端會被默認啟動,但是重啟電腦之后,SSH 服務端默認不會自動啟動。手動啟動的命令為:sudo service ssh start。當然,我們可以選擇將 SSH 服務端配置為開機自啟動。
??在早期的 Linux 中,rc.local 是在系統初始化級別腳本運行之后再執行的,可以安全地在里面添加想在系統啟動之后執行的腳本。然而,在比較新的 Linux 發行版已經沒有 rc.local 文件了,因為已經將其服務化了。直接使用命令:sudo systemctl enable ssh 表示開機自啟動 SSH 服務端。下面是一些常用命令:
??根據網友介紹,目前也可以手動添加 rc.local,在 exit 0 語句前加入:/etc/init.d/ssh start ,這樣使 SSH 服務端開啟自動啟動。具體方法參考:https://cloud.tencent.com/developer/article/1721972
??同樣,從 Windows 10 1803 版本開始,微軟也提供 OpenSSH 工具。直接在 Windows Terminal 中(CMD)輸入 ssh 就可以查看當前系統中的 SSH 版本,與 Ubuntu 不同的是,Windows 同時提供了 SSH 客戶端和服務端:
Windows 下如果要使用服務端需要進行一些配置。
配置
??SSH 的運行需要各種配置文件。SSH 客戶端的全局配置文件是 ssh_config,服務端的配置文件是 sshd_config,他們都位于 /etc/ssh 目錄下。這里需要注意,在 Windows 系統中,稍微有些不同。
Windows 系統中的 OpenSSH 默認沒有這兩個配置文件。例如,默認沒有服務端的配置文件 sshd_config,如果要運行服務端,會提示如下錯誤(Windows 上正確啟用 SSH 服務端需要從 設置 → 應用 →可選功能 中添加服務端,然后使用命令:net start sshd):
如果我們正常添加了 SSH 服務端,那么在 C:\ProgramData\ssh 下就會找到各種配置文件,如下圖所示:
此外,在 Windows 下,在用戶個人的配置文件在 用戶名/.ssh/config,優先級高于全局配置文件。
基本用法
??SSH 最常見的用途就是登錄服務器,這要求服務器安裝并正在運行 SSH 服務器軟件。以上面介紹的 OpenSSH 工具,來簡單介紹一下使用方法,從 Windows 遠程登錄 Ubuntu。首先,Ubuntu 必須要先啟動 SSH 服務器,方法如上面說的。否則將收到如下錯誤:
??最簡單的 SSH 登錄服務器的命令是:ssh hostname,hostname 可以是 IP 地址,也可以是域名。同時,我們還可以指定登錄遠程服務器的用戶名,命令為:ssh username@hostname。用戶名也可以使用 SSH 的 -l 參數指定,這樣的話,用戶名和主機名就不用寫在一起了:ssh -l username hostname。此外,SSH 默認的端口為 22,如果不使用默認的端口,則需要 -p 參數可以指定其他端口:ssh -p 6666 hostname。
??如果是第一次連接某一臺服務器,命令行會顯示一段文字(如上圖),表示不認識這臺機器,提醒用戶確認是否需要連接。其中的 ECDSA key fingerprint is SHA256:NhIe5F7qTvYgV7INlL5k0WYj4vc+P22d9d5yyPuSlDM. 就是服務器的公鑰的哈希值。一旦用戶確認連接之后,ssh 會將本機連接過的所有服務器公鑰的指紋,都儲存在本機的 ~/.ssh/known_hosts 文件中。每次連接服務器時,通過該文件判斷是否為陌生主機(陌生公鑰)。
SSL/TLS
??安全套接字層(Secure Socket Layer ,SSL)協議是一種認證和加密技術,通過伯克利套接字樣式 API 向 TCP 客戶提供安全服務。 最初是由 Netscape Communications Corporation(網景)公司開發,用于給客戶端和服務器通信的 HTTP 協議加密,以保證安全。
??雖然 SSH 在網絡通信安全中很流行,但是它并不是唯一的保證網絡通信安全的方案。身份驗證、加密和網絡安全早在 SSH 之前就已經出現了,SSL/TLS 就是其中的一個非常流行安全解決方案。
??1999 年,互聯網標準化組織 ISOC 接替 NetScape 公司,發布了 SSL 的升級版 Transport Layer Security(TLS)1.0 版的標準文檔 RFC2246,并在后續修訂了多個版本。如下表是 SSL/TLS 不同版本的發布情況:
| SSL1.0 | 1994 | 網景公司制定,但并未對外發布 |
| SSL2.0 | 1995 | 很快發現有嚴重漏洞,網景公司開始設計3.0。 2011 在 RFC6176 中被標記為廢棄 |
| SSL3.0 | 1996 | 2015 在 RFC7568 中被標記為廢棄 |
| TLS1.0 | 1999 | 2020 在 RFC8996 中被標記為廢棄 |
| TLS1.1 | 2006 | 2020 在 RFC8996 中被標記為廢棄 |
| TLS1.2 | 2008 | |
| TLS1.3 | 2018 |
??TLS 和 SSL 就是一個東西,TLS 是 SSL 的改進升級。當前使用最多的是 TLS1.2 和 TLS1.3。在實際使用中,仍然有很多文獻使用 SSL 這個名字,或者使用 SSL/TLS。實際情況是,SSL3.0 發布至今沒有更新過,且被發現了很多漏洞,現在還少使用 SSL3.0 了。
架構
??SSL/TLS 協議采用主從式架構模型,基本思路是采用公鑰加密法,即:客戶端先向服務器端索要公鑰,然后用公鑰加密信息,服務器收到密文后,用自己的私鑰解密。主要由 SSL record protocol、Handshake protocol、Change-cipher spec protocol、Alert protocol 組成。
- SSL Record Protocol: SSL Record 為 SSL 連接提供了加密(加密方法由 Handshake Protocol 確定)和消息完整性校驗這兩個功能。在 SSL 記錄協議中,應用程序數據被分成片段。片段可選擇被壓縮,然后附加由 SHA(安全散列協議)和 MD5(消息摘要)生成的算法生成的加密 MAC(消息認證碼)。之后,完成數據的加密,并且在最后加上一個 SSL 報頭,最終形成一條完整的報文。
- Handshake Protocol: 握手協議用于建立會話。該協議允許客戶端和服務器通過向對方發送一系列消息來彼此進行身份驗證。握手協議使用四個階段來完成其循環。
- Change-cipher Protocol: 該協議使用 SSL Record Protocol。除非完成握手協議,否則 SSL記錄輸出將處于掛起狀態。握手協議完成后,掛起狀態轉換為當前狀態。該 協議由單個消息組成,該消息長度為 1 字節,并且只能具有一個值。該協議的目的是使待定狀態復制到當前狀態。
- Alert Protocol: 該協議用于將 SSL 相關的警報傳達給對等實體。此協議中的每個消息包含 2 個字節。該層被進一步分成告警(不影響雙方連接)和致命錯誤(需要中斷雙方連接)兩部分。
關于 SSL/TLS 協議 每部分中詳細的定義,可以參見 https://en.wikipedia.org/wiki/Transport_Layer_Security#Protocol_details。
OpenSSL/LibreSSL
??SSL/TLS 協議的具體實現,在不同的操作系統中有多種存在。OpenSSL 就是 SSL/TLS 協議的一個開源實現。下圖是維基百科整理的各種 SSL/TLS 協議 實現對于 SSL/TLS 協議 版本的支持情況:
??從上上一節的圖中可以看到,Ubuntu 中的 OpenSSH 使用是 OpenSSL 1.1.1f 提供的加密算法庫。 微軟在 Win10 中集成的 OpenSSH 使用的就是 LibreSSL 加密算法庫。OpenSSL 開源加密庫之前發現的漏洞影響遍及整個互聯網。OpenBSD 的開發者為此而創建了 OpenSSL的 分支 LibreSSL,用戶編譯時可選擇鏈接到 LibreSSL 庫。許多大型公司出于安全,效率等考慮,會將 OpenSSH 集成到自己系統之后,用自己實現的算法替換這個算法庫。
??Heartbleed 漏洞的披露讓人們意識到 OpenSSL 就是這樣一個組件。這促使 Linux 基金會發起了 Core Infrastructure Initiative 倡議,資助關鍵基礎組件的開發和維護。就目前來看,OpenSSL 的維護要比 LibreSSL 要積極一些。而且 Linux 對于 LibreSSL 的支持明顯不如 OpenSSL。具體見 Github:
- OpenSSL: https://www.openssl.org/;官方 Github 庫: https://github.com/openssl/openssl
- LibreSSL: http://www.libressl.org/;官方 Github 庫: https://github.com/libressl-portable/
參考
10.https://en.wikipedia.org/wiki/Transport_Layer_Security
總結
以上是生活随笔為你收集整理的Linux 之七 SSH、SSL、OpenSSH、OpenSSL、LibreSSL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华大 MCU 之七 DMA 导致 SPI
- 下一篇: Linux 之八 完整嵌入式 Linux