A. SSH的工作原理
傳統的網路服務程序,比如 FTP , POP , Telnet ,本質上都是不安全的,因為它們在網路上用明文傳送數據、用戶賬號和用戶口令,很容易受到 中間人 攻擊方式的攻擊,攻擊者會冒充真正的伺服器接收用戶傳給伺服器的數據,然後再冒充用戶把數據傳給真正的伺服器。
為了滿足安全性的需求, IETF 的網路工作小組制定了 Secure Shell (縮寫為 SSH ),這是一項創建在 應用層 和 傳輸層 基礎上的安全協議,為計算機上的 Shell 提供安全的傳輸和使用環境。
SSH 是目前較可靠,專為遠程登錄會話和其他網路服務提供安全性的協議。利用 SSH 協議可以有效防止遠程管理過程中的信息泄漏問題。通過 SSH 可以對所有傳輸的數據進行加密,也能夠防止DNS欺騙和IP欺騙。
本文將會重點討論 SSH 中用到的加密演算法和建立安全連接的過程。
為了保證信息傳輸的安全性, SSH 使用了對稱加密、非對稱加密和散列等技術。
對稱密鑰加密又稱為對稱加密、私鑰加密、共享密鑰加密,是密碼學中一類加密演算法。這類演算法在加密和解密時使用相同的密鑰,或是使用兩個可以簡單地相互推算的密鑰。
SSH 使用對稱密鑰加密整個連接過程中傳輸的信息。值得注意的是,用戶自己創建的public/private密鑰對僅僅用於驗證,不會用在加密連接上。對稱加密允許對密碼進行身份驗證,以防止第三方窺探。
共享密鑰通過密鑰交換演算法生成,它可以讓雙方在完全沒有對方任何預先信息的條件下通過不安全信道創建起一個密鑰。客戶端和服務端都參與了這個過程,過程的細節將在後面闡述。
生成的密鑰將用來加密這次會話過程中客戶端和服務端傳輸的數據。這個過程會在驗證客戶身份之前完成。
SSH 支持多種對稱密鑰演算法,包括AES,Blowfish,3DES,CAST128和Arcfour。客戶端和服務端可以配置採用演算法的列表。客戶端列表中第一個能被服務端支持的演算法將被採用。
比如在Ubuntu 14.04上,客戶端和服務端默認的配置如下: aes128-ctr , aes192-ctr , aes256-ctr , arcfour256 , arcfour128 , [email protected] , [email protected] , [email protected] , aes128-cbc , blowfish-cbc , cast128-cbc , aes192-cbc , aes256-cbc , arcfour 。
也就是說,如果兩台Ubuntu 14.04採用默認配置,它們總是會採用 aes128-ctr 演算法來加密連接。
在非對稱加密方法中,需要一對密鑰,一個是私鑰,一個是公鑰。這兩個密鑰數學相關。用公鑰加密後所得的信息,只能用私鑰才能解密。如果知道了其中一個,並不能計算另外一個。因此,如果公開了一對密鑰中的一個,並不會危害到另外一個的秘密性質。
SSH 在一些地方使用了非對稱加密。
在密鑰交換過程中使用到了非對稱加密。在這個階段,客戶端和服務端生成臨時密鑰對,並且交換公鑰來生成共享密鑰。
在身份驗證的過程中也使用了非對稱加密。 SSH 密鑰對用來向服務端驗證客戶端身份。客戶端創建一對密鑰,然後將公鑰上傳到遠程伺服器上,寫入文件 ~/.ssh/authorized_keys 。
在創建共享密鑰後,客戶端必須向服務端證明身份。服務端會使用文件中的公鑰加密一段信息,並將加密後的信息發送給客戶端。如果客戶端可以能夠破解這段信息,那麼就能夠證明自己擁有相關的私鑰。之後服務端會為客戶端設置shell環境。
散列是電腦科學中一種對資料的處理方法,它通過某種特定的演算法將要檢索的項與涌來檢索的索引關聯起來,生成一種便於搜索的數據結構(散列表)。它也常用做一種資訊安全的方法,由一串資料中經過散列演算法計算出來的資料指紋,來識別檔案和資料是否有被篡改。
SSH 主要使用了散列消息認證碼(Keyed-hash message authentication code,縮寫為HMAC),來確認消息沒有被篡改。
上面提到的對稱加密協商過程中,會使用消息認證碼(MAC)演算法。這個演算法會從客戶端支持的演算法中選出。
在密鑰協商完成後,所有的消息都必須攜帶MAC,用於通信雙方驗證消息的一致性。MAC值由共享密鑰,消息的分組序列和實際消息內容計算得到。
在對稱加密區域之外,MAC本身作為分組的最後部分被發送。研究者通常建議先機密數據,然後計算MAC
SSH 協議採用客戶端-服務端模型對兩方進行身份驗證,並對它們之間的數據進行加密。
服務端在指定埠監聽連接請求。它負責協商安全連接,認證連接方,並為客戶端生成正確的shell環境。
客戶端負責協商安全連接,驗證伺服器的身份是否與以前記錄的信息相匹配,並提供憑證進行身份驗證。
SSH會話分為兩個階段。第一個是同意和建立加密來保護未來的溝通。第二個階段是對用戶進行身份驗證,並發現是否應該授予對伺服器的訪問許可權。
當客戶端發起請求後,服務端返回支持的協議版本。如果客戶端可以匹配其中一個協議版本,則連接繼續。服務端會提供它的公共主機密鑰,客戶端可以用這個密鑰來驗證服務端是否合法。
此時,通信雙方採用迪菲-赫爾曼演算法來協商會話密鑰。
該演算法的大致過程如下:
用於其餘連接的共享密鑰加密被稱為二進制數據包協議。上述過程允許雙方平等地參與生成共享密鑰。
生成的密鑰是對稱密鑰,這意味著用於加密消息的密鑰也可以用於解密。其目的是將後面的通信包裝在不能被外部人員解密的加密隧道中。
在生成會話密鑰後,就開始進行用戶身份驗證。
根據伺服器接受的方式,有幾種不同的方法可用於身份驗證。
最簡單的方法是密碼驗證,其中伺服器要求客戶端輸入嘗試登陸賬號的密碼。密碼是通過協商加密發送的。
雖然密碼被加密,但由於密碼的復雜性受到限制,因此通常不建議使用此方法。與其他身份驗證的方法相比,自動腳本相對容易攻破正常長度的密碼。
最為推薦的選擇是使用SSH密鑰對。SSH密鑰對是非對稱密鑰。
公鑰用於加密只能用私鑰解密的數據。公鑰可以自由共享,因為沒有從公鑰中導出私鑰的方法。
驗證流程如下:
可以看到,密鑰的不對稱性允許服務端使用公鑰加密消息給客戶端。然後,客戶端可以通過正確解密消息來證明它擁有私鑰。
筆者本科專業是信息安全,不過畢業後並沒有從事安全行業,工作4年課堂上學習的知識基本忘的差不多了。
而SSH算是工作中最常用到的東西之一,其工作原理涉及不少密碼學的東西。
寫這篇博文,一是希望能幫助讀者了解SSH,二也是希望自己能撿起一些專業知識。在互聯網/軟體相關行業里,不論是否從事安全工作,了解這些東西都是很有必要的。
B. ssh原理及應用
簡單說,SSH是一種網路協議,用於計算機之間的遠程加密登錄。
SSH 為 Secure Shell的縮寫,由 IETF 的網路小組(Network Working Group)所制定,SSH 為建立在應用層基礎上的安全協議。SSH 是目前較可靠,專為遠程登錄會話和其他網路服務提供安全性的協議。利用 SSH 協議可以有效防止遠程管理過程中的信息泄露問題。SSH最初是UNIX系統上的一個程序,後來又迅速擴展到其他操作平台。SSH安裝容易、使用簡單,而且比較常見,一般的Unix系統、linux系統、FreeBSD系統都附帶有支持SSH的應用程序包。Windows如果需要使用SSH,可以安裝PuTTY或者Cygwin。
SSH 服務基於非對稱加密(public-key cryptography,也稱公開密鑰加密)技術實現數據加密傳輸。該技術會生成一對數學相關的密鑰, 其中一個用於對數據進行加密,而且只能用於加密,而另一個只能用於解密 。使用加密密鑰加密後的數據,只能用對應的解密密鑰才能解密。而且,只知道其中一個密鑰,無法計算出另一個。因此,如果公開了一對密鑰中的一個,並不會危害到另一個的秘密性質。通常把公開的密鑰稱為公鑰(public key),而不公開的密鑰稱為私鑰(private key)。
一般來說,非對稱加密的應用場景有兩個:
與對稱密鑰加密相比,非對稱加密的優點在於不存在共享的通用密鑰。由於解密用的私鑰無需發送給任何用戶,所以可以避免密鑰被劫持或篡改。而加密用的公鑰即便被劫持或篡改,如果沒有與其匹配的私鑰,也無法解密數據。所以,截獲的公鑰是沒有任何用處的。
當前,SSH主要採用 RSA 演算法(協議 V2 默認演算法)和 DSA 演算法(協議 V1 僅支持該演算法)來實現非對稱加密技術。
SSH連接時,整個交互過程如上圖。,主要可以分為三個階段
服務端在每次啟動 SSH 服務時,都會自動檢查 /etc/ssh/ 目錄下相關密鑰文件的有效性。如果相關文件檢查發現異常,則會導致服務啟動失敗,並拋出相應錯誤信息。 如果文件相關不存在,則會自動重新創建。
默認創建的相關文件及用途說明如下:
當伺服器SSH服務啟動,客戶端也安裝了SSH後,就可以進行連接了。
後續登錄校驗及正常的數據傳輸,都會通過雙向加密方式進行。相關交互說明如下:
從這個連接過程中,可以看出,主要使用到兩個文件夾下的內容:
在連接中的兩個過程:
之所以有多組密鑰,是因為使用了不同的加密演算法。
客戶端接收到之後,會存儲在 ~/.ssh/known_hosts 文件里,查看這個文件,可以看到有一行與伺服器 ssh_host_ecdsa_key.pub 內容一致。
所以, ~/.ssh/authorized_keys 里表示本機可以被哪些機器訪問
~/.ssh/known_hosts 里表示本機訪問過哪些機器
SSH配置文件有兩個,一個是 ssh_config ,一個是 sshd_config 。前者是客戶端配置,後者是伺服器配置。也就是說,如果本機是作為客戶端,那麼就修改第一個配置,如果本機是作為伺服器,那麼就修改第二個配置,
一般來說,和密鑰登錄的配置有關的有以下幾個,如果密鑰配置好後無法登錄,嘗試配置以下三項。
其他
傳統的網路服務程序,如FTP、Pop和Telnet在傳輸機制和實現原理上是沒有考慮安全機制的,其本質上都是不安全的。因為它們在網路上用明文傳送數據、用戶帳號和用戶口令,別有用心的人通過竊聽等網路攻擊手段非常容易地就可以截獲這些數據、用戶帳號和用戶口令。而且,這些網路服務程序的簡單安全驗證方式也有其弱點,那就是很容易受到"中間人"(man-in-the-middle)這種攻擊方式的攻擊。
所謂"中間人"的攻擊方式,就是"中間人"冒充真正的伺服器接收你的傳給伺服器的數據,然後再冒充你把數據傳給真正的伺服器。伺服器和你之間的數據傳送被"中間人"一轉手做了手腳之後,就會出現很嚴重的問題。中間人能夠攻擊,主要原因在於他能認識截取的信息,也能發出讓接受者認識的信息。
使用SSH,你可以把所有傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了,而且也能夠防止DNS欺騙和IP欺騙。使用SSH,還有一個額外的好處就是傳輸的數據是經過壓縮的,所以可以加快傳輸的速度。SSH有很多功能,它既可以代替Telnet,又可以為FTP、Pop、甚至為PPP提供一個安全的"通道"。
最初的SSH是由芬蘭的一家公司開發的。但是因為受版權和加密演算法的限制,現在很多人都轉而使用OpenSSH。OpenSSH是SSH的替代軟體包,而且是免費的,可以預計將來會有越來越多的人使用它而不是SSH。
C. SSH 協議原理、組成、認證方式和過程
SSH 是(Secure SHell protocol) 的簡寫,安全外殼協議(SSH)是一種在不安全網路上提供安全遠程登錄及其它安全網路服務的協議。
OpenSSH 是SSH (Secure SHell)協議的免費開源實現。SSH協議族可以用來進行遠程式控制制,或在計算機之間傳送文件。而實現此功能的傳統方式,如telnet(終端模擬協議)、 rcp ftp、 rlogin、rsh都是極為不安全的,並且會使用明文傳送密碼。OpenSSH提供了服務端後台程序和客戶端工具,用來加密遠程式控制制項和文件傳輸過程的中的數據,並由此來代替原來的類似服務。
在過去我們使用的rsh和telnet,因為包括登錄時的ID和密碼數據沒有加密就傳到網路上,存在安全上的問題。即使在內部網上,也有在網際網路上的竊取和篡改等危險性。SSH將包括密碼在內的所有數據都已進行了加密處理,可以進行更安全的遠程操作。在SSH中,由於協議標準的不同而存在SSH1和SSH2兩個不同的版本。SSH2是為了迴避SSH1所使用的加密演算法的許可證問題而開發的(現在這一許可證問題已經不存在了)。TLES 8中作為安裝SSH協議的應用程序採用了開放源碼的OpenSSH。OpenSSH與SSH1和SSH2的任何一個協議都能對應,但默認使用SSH2。
SSH 主要有三部分組成:
同時SSH協議框架中還為許多高層的網路安全應用協議提供擴展的支持。它們之間的層次關系可以用如下圖來表示:
對於SSH這樣以提供安全通訊為目標的協議,其中必不可少的就是一套完備的密鑰機制。由於SSH協議是面向互聯網網路中主機之間的互訪與信息交換,所以主機密鑰成為基本的密鑰機制。也就是說,SSH協議要求每一個使用本協議的主機都必須至少有一個自己的主機密鑰對,服務方通過對客戶方主機密鑰的認證之後,才能允許其連接請求。一個主機可以使用多個密鑰,針對不同的密鑰演算法而擁有不同的密鑰,但是至少有一種是必備的,即通過 DSS演算法產生的密鑰。關於DSS演算法,請參考 FIPS-186 文檔.SSH協議關於主機密鑰認證的管理方案有兩種,如下圖所示:
每一個主機都必須有自己的主機密鑰,密鑰可以有多對,每一對主機密鑰對包括公開密鑰和私有密鑰。在實際應用過程中怎樣使用這些密鑰,並依賴它們來實現安全特性呢?如上圖所示,SSH協議框架中提出了兩種方案。
在第一種方案中,主機將自己的公用密鑰分發給相關的客戶機,客戶機在訪問主機時則使用該主機的公開密鑰來加密數據,主機則使用自己的私有密鑰來解密數據,從而實現主機密鑰認證,確定客戶機的可靠身份。在圖2(a)中可以看到,用戶從主機A上發起操作,去訪問,主機B和主機C,此時,A成為客戶機,它必須事先配置主機B和主機C的公開密鑰,在訪問的時候根據主機名來查找相應的公開密鑰。對於被訪問主機(也就是伺服器端)來說則只要保證安全地存儲自己的私有密鑰就可以了。
在第二種方案中,存在一個密鑰認證中心,所有系統中提供服務的主機都將自己的公開密鑰提交給認證中心,而任何作為客戶機的主機則只要保存一份認證中心的公開密鑰就可以了。在這種模式下,客戶機在訪問伺服器主機之前,還必須向密鑰認證中心請求認證,認證之後才能夠正確地連接到目的主機上。
很顯然,第一種方式比較容易實現,但是客戶機關於密鑰的維護卻是個麻煩事,因為每次變更都必須在客戶機上有所體現;第二種方式比較完美地解決管理維護問題,然而這樣的模式對認證中心的要求很高,在互聯網路上要實現這樣的集中認證,單單是權威機構的確定就是個大麻煩,有誰能夠什麼都能說了算呢?但是從長遠的發展來看,在企業應用和商業應用領域,採用中心認證的方案是必要的。
另外,SSH協議框架中還允許對主機密鑰的一個折中處理,那就是首次訪問免認證。首次訪問免認證是指,在某客戶機第一次訪問主機時,主機不檢查主機密鑰,而向該客戶都發放一個公開密鑰的拷貝,這樣在以後的訪問中則必須使用該密鑰,否則會被認為非法而拒絕其訪問。
在整個通訊過程中,為實現 SSH的安全連接,伺服器端與客戶端要經歷如下五個階段:
* 版本號協商階段,SSH目前包括 SSH1和SSH2兩個版本, 雙方通過版本協商確定使用的版本
* 密鑰和演算法協商階段,SSH支持多種加密演算法, 雙方根據本端和對端支持的演算法,協商出最終使用的演算法
* 認證階段,SSH客戶端向伺服器端發起認證請求, 伺服器端對客戶端進行認證
* 會話請求階段, 認證通過後,客戶端向伺服器端發送會話請求
* 交互會話階段 ,會話請求通過後,伺服器端和客戶端進行信息的交互
Q1: SSH的版本和區別。
SSH2避免了RSA的專利問題,並修補了CRC的缺陷。SSH2用數字簽名演算法(DSA)和Diffie-Hellman(DH)演算法代替RSA來完成對稱密鑰的交換,用HMAC來代替CRC。同時SSH2增加了AES和Twofish等對稱加密演算法。
A1: SSH(Secure SHell)到目前為止有兩個不兼容的版本——SSH1和SSH2。SSH1又分為1.3和1.5兩個版本。SSH1採用DES、3DES、 Blowfish和RC4等對稱加密演算法保護數據安全傳輸,而對稱加密演算法的密鑰是通過非對稱加密演算法(RSA)來完成交換的。SSH1使用循環冗餘校驗碼(CRC)來保證數據的完整性,但是後來發現這種方法有缺陷。
更多內容請參考The SSHv1 Protocol & The SSHv2 Protocol
Q2: 什麼是HMAC?
A2: HMAC(Hash Message Authentication Code) ,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
Q3: 什麼是X11 forwarding?
A3: sh的X11 forwarding特性可以使X client和X server安全地通訊。使用X11 forwarding後,從X client到X Server方向的數據先被送至ssh server,ssh server利用和ssh client的安全通道轉發給ssh client,再由ssh client轉發給X server,從X server到X client的數據流同理。這里ssh server和ssh client充當了X client和X server間數據的轉發器,由於ssh server和X client、ssh client和X server一般在同一台機器上,它們之間是一種安全的進程間通訊,而ssh server和ssh client間的通訊也是安全的,所以X client和X server間的通訊就是安全的。
Q4: 什麼是TTY?
A4: 終端是一種字元型設備,它有多種類型,通常使用tty來簡稱各種類型的終端設備。tty是 Teletype的縮寫。Teletype是最早出現的一種終端設備,很象電傳打字機,是由Teletype公司生產的。設備名放在特殊文件目錄/dev/下。
Q5: 簡單描述下SSH運行的過程?
D. 如何把OpenSSH公鑰轉換成OpenSSL格式
首先看看OpenSSL工具的簡單使用方法,我們以rsa加密演算法為例
生成一個私鑰:
openssl genrsa -out private.key 1024
-out指定生成私鑰文件名 1024是生成密鑰的長度
利用私鑰生成對應的公鑰:
openssl rsa -in private.key -pubout -out public.key
-in 指定的私鑰,-out 指定公鑰文件名
加密文件:
openssl rsautl -encrypt -in test -inkey public.key -pubin -out test_encrypt
-in 指定加密的文件,-inkey 指定公鑰,-pubin表明是用純公鑰文件加密,-out為加密後的密文文件
解密文件:
openssl rsautl -decrypt -in test_encrypt -inkey private.key -out test_decrypt
-in指定加密後的密文文件,-inkey指定公鑰對應的私鑰,-out為解密後的文件。
然後你就可以直接diff一把原文件和test_decrypt,看看是不是一樣了
不過玩過OpenSSL的兄弟一定知道,OpenSSL生成的公鑰跟OpenSSH的公鑰雖然來自同一個私鑰,不過格式卻完全不一樣
這就是很多兄弟遭遇悲劇的所在,因為OpenSSH的公鑰藉助ssh的互信可以在authorized_key中非常容易就得到
不過這個openssh的公鑰格式不一樣,沒法用openssl加密
openssl的公鑰例子:
-----BEGIN PUBLIC KEY-----
O3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2
eHnHl5CB8ruRX9fBl/
QWPdspTBKcxeFbccDwIDAQAB
-----END PUBLIC KEY-----
openssh的公鑰例子:
ssh-rsa /TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2eHnHl5CB8ruRX9fBl/QWPdspTBKcxeFbccDw==
不過還好這個早就不是什麼新問題了,如果是OpenSSH v.5.6或者以上版本,可以用下面的命令生成(這個沒驗證過,確實找不到這么高版本的環境)
ssh-keygen -f key.pub -e -m pem
不過你的OpenSSH還沒這么高版本,也不想費勁去升級依賴的一堆庫文件,也有用代碼實現的方式
附上python實現代碼:
#!/usr/bin/env python
# with help and inspiration from
# * ASN1_generate_nconf(3) (specifically the SubjectPublicKeyInfo structure)
# * http://www.sysmic.org/dotclear/index.php?post/2010/03/24/Convert-keys-betweens-GnuPG%2C-OpenSsh-and-OpenSSL
# * http://blog.oddbit.com/2011/05/converting-openssh-public-keys.html
import sys
import base64
import struct
from pyasn1.type import univ
from pyasn1.codec.der import encoder as der_encoder, decoder as der_decoder
if len(sys.argv) != 2:
sys.stderr.write("Usage: %s \n" % sys.argv[0])
sys.exit(1)
keyfields = open(sys.argv[1]).read().split(None)
if len(keyfields) I', keydata[:4])[0]
# read in bytes
data, keydata = keydata[4:dlen+4], keydata[4+dlen:]
parts.append(data)
e_val = eval('0x' + ''.join(['%02X' % struct.unpack('B', x)[0] for x in parts[1]]))
n_val = eval('0x' + ''.join(['%02X' % struct.unpack('B', x)[0] for x in parts[2]]))
bitstring = univ.Sequence()
bitstring.setComponentByPosition(0, univ.Integer(n_val))
bitstring.setComponentByPosition(1, univ.Integer(e_val))
bitstring = der_encoder.encode(bitstring)
bitstring = ''.join([('00000000'+bin(ord(x))[2:])[-8:] for x in list(bitstring)])
bitstring = univ.BitString("'%s'B" % bitstring)
pubkeyid = univ.Sequence()
pubkeyid.setComponentByPosition(0, univ.ObjectIdentifier('1.2.840.113549.1.1.1')) # == OID for rsaEncryption
pubkeyid.setComponentByPosition(1, univ.Null(''))
pubkey_seq = univ.Sequence()
pubkey_seq.setComponentByPosition(0, pubkeyid)
pubkey_seq.setComponentByPosition(1, bitstring)
print "-----BEGIN PUBLIC KEY-----"
if keycomment:
print "X-Comment: " + keycomment
print
base64.MAXBINSIZE = (64//4)*3 # this actually doesn't matter, but it helped with comparing to openssl's output
print base64.encodestring(der_encoder.encode(pubkey_seq)),
print '-----END PUBLIC KEY-----'
http://stackoverflow.com/questions/1011572/convert-pem-key-to-ssh-rsa-format
E. Xshell顯示找不到匹配的outgoing encryption演算法怎麼辦
解決方法如下:
1、docker安裝完成以後,要使用xhell連接,在配置了ip、埠、用戶名和密碼後,點擊鏈接
後,彈出窗口提示「沒有找到匹配的outgoing encryption演算法」錯誤。
F. SSH原理 and SSH遠程登錄
Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在應用層基礎上的安全網路協議。它是專為遠程登錄會話(甚至可以用Windows遠程登錄Linux伺服器進行文件互傳)和其他網路服務提供安全性的協議,可有效彌補網路中的漏洞。通過SSH,可以把所有傳輸的數據進行加密,也能夠防止DNS欺騙和IP欺騙。還有一個額外的好處就是傳輸的數據是經過壓縮的,所以可以加快傳輸的速度。目前已經成為Linux系統的標准配置。
SSH只是一種協議,存在多種實現,既有商業實現,也有開源實現。本文主要介紹OpenSSH免費開源實現在Ubuntu中的應用,如果要在Windows中使用SSH,需要使用另一個軟體PuTTY。
SSH之所以能夠保證安全,原因在於它採用了非對稱加密技術(RSA)加密了所有傳輸的數據。
傳統的網路服務程序,如FTP、Pop和Telnet其本質上都是不安全的;因為它們在網路上用明文傳送數據、用戶帳號和用戶口令,很容易受到中間人(man-in-the-middle)攻擊方式的攻擊。就是存在另一個人或者一台機器冒充真正的伺服器接收用戶傳給伺服器的數據,然後再冒充用戶把數據傳給真正的伺服器。
但並不是說SSH就是絕對安全的,因為它本身提供兩種級別的驗證方法:
第一種級別(基於口令的安全驗證):只要你知道自己帳號和口令,就可以登錄到遠程主機。所有傳輸的數據都會被加密,但是不能保證你正在連接的伺服器就是你想連接的伺服器。可能會有別的伺服器在冒充真正的伺服器,也就是受到「中間人攻擊」這種方式的攻擊。
第二種級別(基於密鑰的安全驗證):你必須為自己創建一對密鑰,並把公鑰放在需要訪問的伺服器上。如果你要連接到SSH伺服器上,客戶端軟體就會向伺服器發出請求,請求用你的密鑰進行安全驗證。伺服器收到請求之後,先在該伺服器上你的主目錄下尋找你的公鑰,然後把它和你發送過來的公鑰進行比較。如果兩個密鑰一致,伺服器就用公鑰加密「質詢」(challenge)並把它發送給客戶端軟體。客戶端軟體收到「質詢」之後就可以用你的私鑰在本地解密再把它發送給伺服器完成登錄。與第一種級別相比,第二種級別不僅加密所有傳輸的數據,也不需要在網路上傳送口令,因此安全性更高,可以有效防止中間人攻擊。
SSH分為客戶端 openssh-client 和伺服器 openssh-server,可以利用以下命令確認電腦上是否安裝了客戶端和伺服器。
如果只是想遠程登陸別的機器只需要安裝客戶端(Ubuntu默認安裝了客戶端),如果要開放本機的SSH服務就需要安裝伺服器。
首先確認ssh-server是否已經啟動了
如圖,sshd 表示ssh-server已經啟動了。如果沒有啟動,可以使用如下命令啟動:
停止和重啟ssh服務的命令如下:
接下來就可以進行使用客戶機遠程登錄伺服器了~
口令登錄非常簡單,只需要一條命令,命令格式為: **ssh 客戶端用戶名@伺服器ip地址 **eg:
如果需要 調用圖形界面程序 可以使用 -X 選項
如果客戶機的用戶名和伺服器的 用戶名相同 ,登錄時 可以省略 用戶名。
還要說明的是,SSH服務的 默認埠是22 ,也就是說,如果你不設置埠的話登錄請求會自動送到遠程主機的22埠。我們可以使用** -p 選項來修改埠號**,比如連接到伺服器的1234埠:
客戶機必須要知道伺服器的 ip地址 。可以在伺服器端電腦上利用** ifconfig** 命令查看該機的ip地址:
如果是第一次登錄遠程主機,系統會給出下面提示:
意思是,該遠程主機的真實性無法確定,其公鑰指紋為 SHA256:s8pZiuKQr7k7f+57j22lk/IdWC8143VQKR+EabeP5,確定想要繼續連接嗎?
輸入yes 即可。這時系統會提示遠程主機被添加到已知主機列表。
然後會要求我們輸入 遠程主機的密碼 ,輸入的密碼正確就可以成功登錄了。命令提示符會修改為遠程主機的提示符,現在開始,終端中輸入的命令都將在伺服器中執行。
我們可以通過** Ctrl+D** 或者 exit 命令 退出遠程登錄 。
每次登錄遠程主機都需要輸入密碼是很不方便的,如果想要省去這一步驟,可以利用密鑰對進行連接,還可以提高安全性。
1、在本機生成密鑰對
使用ssh-keygen命令生成密鑰對:
ssh-keygen -t rsa #-t表示類型選項,這里採用rsa加密演算法
然後根據提示一步步的按enter鍵即可(其中有一個提示是要求設置私鑰口令passphrase,不設置則為空,這里看心情吧,如果不放心私鑰的安全可以設置一下),執行結束以後會在 /home/當前用戶 目錄下生成一個 .ssh 文件夾,其中包含私鑰文件 id_rsa 和公鑰文件 id_rsa.pub。
2、將公鑰復制到遠程主機中
使用ssh--id命令將公鑰復制到遠程主機。ssh--id會將公鑰寫到遠程主機的 ~/ .ssh/authorized_key 文件中
ssh--id [email protected]
經過以上兩個步驟,以後再登錄這個遠程主機就不用再輸入密碼了。
1)已獲取登錄實例的管理員帳號及密碼(或密鑰)。
2)雲伺服器實例已開通22號埠。
—使用密碼登錄
Host Name(or IP address) :伺服器的IP地址;
Port :伺服器的埠,必須設置為22;
Connect type :選擇 「SSH」;
Saved Sessions :填寫會話名稱,例如 test。 配置 「Host Name」 後,再配置 「Saved Sessions」 並保存,則後續使用時您可直接雙擊 「Saved Sessions」 下保存的會話名稱即可登錄伺服器;
登錄完成後,命令提示符左側將顯示當前登錄雲伺服器的信息。
—使用密鑰登錄
Ps: 當不存在私鑰文件時,可以選擇Conversions > Import key 導入公鑰(.pem)文件來生成私鑰文件(.ppk)
Host Name (IP address) :伺服器的IP;
Port :伺服器的埠,必須填 22;
Connect type :選擇 「SSH」;
Saved Sessions :填寫會話名稱,例如 test。 配置 「Host Name」 後,再配置 「Saved Sessions」 並保存,則後續使用時您可直接雙擊 「Saved Sessions」 下保存的會話名稱即可登錄伺服器;
登錄完成後,命令提示符左側將顯示當前登錄伺服器的信息。
G. SSH詳解-3.密鑰登陸
SSH詳解-1.ssh基礎知識
SSH詳解-2.ssh基本用法
SSH詳解-3.密鑰登陸
SSH詳解-4.多個ssh公鑰
在上一篇中我們了解到了ssh基本用法,ssh通過密碼進行登錄。密碼登錄存在很多問題。密碼太簡單,又不安全。密碼太復雜,不容易記,而且每次登錄都要輸入很麻煩。於是就有了密鑰登陸。
什麼是密鑰(key)?
ssh密鑰登錄採用的是 非對稱加密 。
非對稱密鑰加密系統,又稱公鑰密鑰加密。它需要使用不同的密鑰來分別完成加密和解密操作,一個公開發布,即公開密鑰(public key)和,另一個由用戶自己秘密保存,即私用密鑰(private key)。
如果數據使用公鑰加密,那麼只有使用對應的私鑰才能解密,其他密鑰都不行;反過來,如果使用私鑰加密(這個過程一般稱為「簽名」),也只有使用對應的公鑰解密。
了解完密鑰後,接下來看看密鑰登錄的過程,SSH 密鑰登錄分為以下的步驟。
第零步,准備步驟客戶端通過 ssh-keygen 生成自己的公鑰和私鑰,並將公鑰放入遠程伺服器的指定位置。
第一步,用戶客戶端向伺服器發起SSH登錄的請求。
第二步,伺服器收到用戶SSH登錄的請求,伺服器生成一些隨機數據發送給客戶端。
第三步,客戶端接收到伺服器發過來的數據,客戶端使用私鑰對數據進行簽名後再返回給伺服器。
第四步,伺服器收到客戶端加密後的數據,使用對應公鑰進行解密。然後判斷解密後的數據是否與原始數據一致,如果一致就允許用戶登錄。
ssh-keygen 是OpenSSH提供的一個命令行工具,用於生成密鑰登錄所需的公鑰和私鑰。
在上面的例子中,我使用了-t參數來指定加密演算法,一遍會選擇rsa或者dsa。
第一個問題,問我要保存在哪?(直接Enter默認會保存在~/.ssh/id_rsa中)因為我之前已經生成過密鑰了,我就保存在tenxun裡面。
第二個問題,詢問是否要為私鑰文件設定密碼保護(passphrase)。這樣的話,即使入侵者拿到私鑰,還是需要破解密碼。如果為了方便,不想設定密碼保護,可以直接按回車鍵,密碼就會為空。
最後,就會生成私鑰和公鑰,屏幕上還會給出公鑰的指紋,以及當前的用戶名和主機名作為注釋,用來識別密鑰的來源。
從上面的公鑰中我們可以看到末尾的公鑰注釋 23696@DESKTOP-GKRBCVI
公鑰注釋可以用來識別不同的公鑰,表示這是哪台主機(DESKTOP-GKRBCVI)的哪個用戶(username)的公鑰。
注意 ,公鑰只有一行。因為它太長了,顯示的時候可能自動換行了。
OpenSSH 規定,用戶公鑰保存在伺服器的 ~/.ssh/authorized_keys 文件。你要以哪個用戶的身份登錄到伺服器,密鑰就必須保存在該用戶主目錄的~/.ssh/authorized_keys文件。只要把公鑰添加到這個文件之中,就相當於公鑰上傳到伺服器了。每個公鑰占據一行。如果該文件不存在,可以手動創建。
-i 指定要上傳公鑰(公鑰文件可以不指定路徑和 .pub 後綴名),user是所要登錄的用戶名,hostname是主機名,這兩個參數與ssh 登錄命令是一致。
特別注意 ,不是把公鑰上傳上去就行了,還需要把 authorized_keys 文件的許可權要設為644,即只有文件所有者才能寫。如果許可權設置不對,SSH伺服器可能會拒絕讀取該文件,導緻密鑰登錄失效,登錄的時候還需要輸入密碼。
提到輸入密碼,如果再生成公鑰和私鑰的時候設置了密碼,使用密鑰登錄的時候也需要輸入私鑰的密碼,這樣可以防止他人非法竊取了私鑰。
私鑰設置了密碼以後,每次使用都必須輸入私鑰密碼,這個問題可以使用 ssh-agent 命令解決。
網路-密鑰
Git - 生成 SSH 公鑰 (git-scm.com)
ssh(1) - OpenBSD manual pages
H. linux如何配置openssh文件,支持TLS1.1 1.2
TLS全稱為:Transport Layer Security——安全傳輸層協議,用於在兩個通信應用程序之間提供保密性和數據完整性。TLS 1. 0 和TLS 1. 1 是分別於 1996 年和2006年發布的老版協議,使用的是弱加密演算法和系統。比如SHA-1和MD5,這些演算法和系統十分脆弱,存在重大安全漏洞,容易受到降級攻擊的嚴重影響,而在 2008 年和 2017 年分別發布了協議的新版本,分為TLS 1. 2 和TLS 1.3,無疑更優於舊版本,使用起來也更安全。網路搜索《Linux就該這么學》一起來學習。
1,Chrome、Firefox等瀏覽器最新版本升級後,不在支持 TLS 1. 0 和TLS 1. 1。 如果使用的網站上貼上標簽,在URL地址欄和鎖定圖標顯示「不安全」標識,暗示用戶HTTPS連接並不像他們想像的那樣安全。
2,目前北金所部分系統使用的是低版本協議,存在重大安全漏洞,容易受到降級攻擊的嚴重影響。
操作:
1,伺服器安裝部署SSL證書的,只要開啟支持TLS 1.2或以上版本的加密協議即可。nginx開啟如下圖:
ssl_ciphers 填自己的加密方式;
I. win10系統下,ssh連接虛擬機linux出現以下錯誤如何解決
ssh client 報 algorithm negotiation failed的解決方法之一
修改sshd的配置文件 /etc/ssh/sshd_config
在配置文件中添加:
Ciphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3des-cbc,arcfour128,arcfour256,arcfour,blowfish-cbc,cast128-cbc
MACs hmac-md5,hmac-sha1,[email protected],hmac-ripemd160,hmac-sha1-96,hmac-md5-96
KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,[email protected]
重啟sshd服務後,即可正常連接。
導致此問題的原因是ssh升級後,為了安全,默認不再採用原來一些加密演算法,我們手工添加進去即可。