1. 程式人生 > >ssh登陸遠端主機(密碼方式和key的方式)

ssh登陸遠端主機(密碼方式和key的方式)

連線遠端主機

要使用SSH連線,自然需要相應的客戶端和服務端軟體,這裡採用OpenSSH。記住兩臺主機都要裝。這裡為了偷懶,就直接給兩臺主機都裝了客戶端和服務端。

Shell程式碼  收藏程式碼
  1. sudo apt-get install openssl-server openssh-client  

安裝完成後,在本地主機的終端上執行以下命令:

Shell程式碼  收藏程式碼
  1. ssh bill@192.168.0.120  

如果是第一次想某遠端主機發起SSH連線,系統會提示你該主機地址不在known host裡,這時輸入yes就可以繼續了。然後系統會提示你輸入bill 的密碼,輸入正確後,終端的提示符會變成bill@remote-hostname,這就說明你已經以bill的身份成功登入了,之後就可以像使用本地主機一樣,操作遠端主機的檔案了(能做的操作取決於bill的許可權)。在提示符下輸入exit

 就會退出登入。很簡單吧。

ssh命令的基本用方法就是 ssh username@ipaddress 。username就是遠端主機的使用者,ipaddress是遠端主機的IP地址,你也可以把它換成域名。你可以只輸入ssh來獲得它的幫助資訊,檢視更多細節。

請記住username@ipaddress 這種格式,因為它在其他命令列工具(如 git 和 scp )中屢見不鮮,這時你就知道該工具是用SSH來訪問遠端主機的。

使用公鑰認證(public key),避免使用密碼

現在你已經熟悉了SSH的基本用法(一行命令而已),但每次發起連線都要輸入密碼很是煩人。而且實際環境中因為種種原因,基本不會告訴你遠端主機的密碼的。那沒有密碼,如何驗證某主機可以以bill的身份登入呢?我們可以使用公鑰(public key)和金鑰(private key)代替密碼。

首先簡單講講公鑰驗證機制:公鑰和金鑰是兩份檔案,服務端持有公鑰,用來加密;客戶端持有金鑰,用來解密。客戶端向服務端發起連線請求時,服務端會生成一串隨機數,經過公鑰加密後傳給客戶端。這時客戶端會用金鑰解密獲取隨機數,再返回服務端。最後服務端判斷一下,如果客戶端能夠返回正確的隨機數,就認為校驗通過了 ,可以進行連線。否則您就從哪兒來會哪兒去吧。

公鑰驗證機制的存在其實是為了提供一種比密碼驗證機制更安全的方式,使用公鑰認證,就只需要把自己生成的公鑰發給管理員,而不需要管理員把伺服器的使用者密碼告訴每一個人(而且以後更改密碼可能還要再通知一遍)。對你而言,則可以把公鑰發給多個服務端,也避免了去記住不同服務端的使用者密碼的麻煩。

現在說說怎麼做。首先,本地主機(客戶端)需要生成公鑰(public key)和金鑰(private key)。執行以下命令:

Shell程式碼  收藏程式碼
  1. ssh-keygen -t rsa  

ssh-keygen命令用來生成公鑰和金鑰(下面簡稱key),這個命令會在~/.ssh 目錄下生成兩個key檔案。.ssh目錄是SSH為主機上每個使用者分別建立的一個目錄,用來存放使用者層面的配置資訊的。

ssh-keygen可以生成兩種格式的key,RSA和DSA。可以用 -t 引數指定。其實不加任何引數,ssh-keygen就會預設生成RSA的key。這裡加上它只是說明一下 -t 這個比較重要的引數而已。使用 -h 引數可以檢視幫助資訊,注意 --help 是沒用的 ……

輸入命令後,系統會詢問你待生成的金鑰檔案的名字,預設id_rsa,然後會要你輸入一個密語(passphrase)來加密金鑰(可以為空)。之後就生成了金鑰和公鑰,預設公鑰檔案的名字是金鑰檔名加上 .pub 字尾。本文使用預設設定,會生成金鑰 id_rsa 和 公鑰 id_rsa.pub 。

上面說了,遠端主機(服務端)需要一份公鑰,所以你要把公鑰給它。方法有很多。這裡我們使用scp命令來遠端傳檔案。傳完之後,本地主機的id_rsa.pub檔案就沒用了,你可以刪除它,或者留著它,以後再發給其他的遠端主機。

Shell程式碼  收藏程式碼
  1. scp id_rsa.pub bill@192.168.0.120:~/alex_id_rsa.pub  

上面的命令用來把檔案複製到遠端主機的bill使用者根目錄下,並改名為alex_id_rsa.pub。這個命令和cp命令差不多,只是把目標地址換成了遠端主機的地址。一看這格式就知道,scp是使用SSH進行遠端通訊的。所以下面的內容你知道了——再輸一次密碼,這是最後一次了。

這裡的SSH地址稍微多了點東西,它的格式為 username@ipaddress:file_or_directory 。就是在原來的基礎上加了一個冒號,後面接檔案或目錄的路徑。使用這種表示法,理論上你可以定義到任何一臺主機的檔案。

現在複製完畢,但你還需要把id_rsa.pub中的內容新增到.ssh目錄下的authorized_keys檔案中去。如果沒有,你就要建立一個。說起來很多,實際也就是一行命令:

Shell程式碼  收藏程式碼
  1. cat alex_id_rsa.pub >> authorized_keys  

這是一個簡單的linux重定向,意思是把alex_id_rsa.pub中的內容 增量新增 到authorized_keys中。注意是增量新增,因為這個檔案裡不止存放一個公鑰,看檔名就知道,不是麼?

現在所有設定都完成了,再來試試:

Shell程式碼  收藏程式碼
  1. ssh bill@192.168.0.120  

如果你之前執行ssh-keygen時,輸入過為金鑰加密的密語,這時系統會提示你輸入密語。這是因為本地主機需要呼叫金鑰id_rsa進行解密。但金鑰本身被加密了,所以你要先解密金鑰。輸入正確的密語後,就會成功進入遠端主機。但exit之後,下次發起連線時,還會要你輸入密語……(也許你的機器有不同的表現,我們下面會講)。這完全沒達到我們偷懶的目的。但我沒說假話,至少你確實不需要輸入密碼了 。至於如何避免輸入密語,這就是我們下面要講的。

一些不同之處

如果使用ssh-keygen時,沒有填寫密語,那麼系統以後都不會要求你輸入密語。這樣確實挺方便,但缺點就是不加密的金鑰容易被有心人利用。當然,使用哪種方案,取決於你的實際使用環境。只是記住,還是有辦法可以避免頻繁地輸入密語。

如果你使用金鑰驗證方式用SSH發起遠端連線時,Ubuntu彈出一個圖形化提示框要求你“輸入密碼以解鎖私鑰”,恭喜你,你只用輸入一次金鑰密語。直到你登出alex使用者前,每次你發起SSH連線時都不會被要求輸入密語。如果你用ssh-keygen生成金鑰時,使用的預設檔名,發起SSH連線時一般都會出現這種情況。我想這是Ubuntu自動快取瞭解密後的金鑰檔案,這也是下面我們要將的“快取金鑰”。如果你就是這種情況,下面的快取部分就不用看了。

如果你生成金鑰時使用自定義的檔名(比如alex_rsa),那麼還有個麻煩,就是使用ssh命令時,它會需要你手動指定私鑰檔案,如下所示:

Shell程式碼  收藏程式碼
  1. ssh -i alex_rsa bill@192.168.0.120  

這是因為ssh需要金鑰時,預設只會去找~/.ssh目錄下的identity、id_rsa和id_dsa三個檔案,就像它只會從authorized_keys和authorized_keys2兩個檔案中去找金鑰一樣。這是預設約定。自己掰雖然自由,但代價就是還有一堆東西等著你去掰……還是Convention Over Configuration比較方便。

最後,如果你想用先進一點的DSA 而不是古老的RSA ……這沒那麼麻煩,只需在ssh-keygen時改動一下 -t 引數(注意生成的檔案是id_dsa和id_dsa.pub)。但你最好在服務端執行cat命令時,把authorized_keys改成authorized_keys2。這是為了分別存放RSA和DSA的公鑰。雖然你把DSA的公鑰放進authorized_keys中也不會有任何問題(反之亦然)。

快取金鑰(private key),避免輸入密語

快取金鑰可以使你只需輸入一次密語,以後它都不會來麻煩你了。方法很簡單,一個命令列工具ssh-add可以把你指定的金鑰檔案加入到快取中。

Shell程式碼  收藏程式碼
  1. ssh-add ~/.ssh/id_rsa  

加入時,會要你輸入一次密語。再發起SSH連線時,都不會要你輸入密語了,直到你本地主機的使用者登出。

注:有些其他的文章裡會使用ssh-agent,但經我測試其實不需要啟動ssh-agent就可以快取金鑰。有一篇文章講ssh-agent可以用來做金鑰轉發,但這點對我沒什麼用處,就沒試過。如果有童鞋知道ssh-agent和ssh-add的關係,請不吝賜教!

再偷懶一把,使用config配置檔案儲存使用者和主機名

現在我們使用了公鑰認證代替了密碼認證,又快取了金鑰密語。但在實驗過程中你應該敲了不少此命令:

Shell程式碼  收藏程式碼
  1. ssh bill@192.168.0.120  

也許你已經難以忍受每次都敲又臭又長的IP地址。如果我們能把它改成

Shell程式碼  收藏程式碼
  1. ssh server  

該多好。下面我們就來做這件事。你可以在當前使用者的.ssh目錄下建立一個config檔案,去儲存一些自定義的配置。我們可以把使用者名稱和主機名儲存進去。使用任何你熟悉的編輯器,在檔案中加入如下程式碼:

Config檔案程式碼  收藏程式碼
  1. Host server  
  2. User bill  
  3. HostName 192.168.0.120  

大概解釋一下:我們定義了一個叫server的host,它下面的所有配置項(直到下一個host定義之前)都隸屬於這個host,我們為server設定了使用者名稱和密碼。以後在任何需要敲 [email protected] 的地方,你都可以使用server來替代。這並不限於ssh命令,比如:

Shell程式碼  收藏程式碼
  1. scp id_rsa server:~/  

是不是很爽呢?