引子:linux
第一次接觸到SSH,也是第一次接觸到Linux(Unix Like)系統,時間上說不上來了,SSH算得上是Linux系統的的一個標準配置,對SSH的印象,它就是一種遠程鏈接的工具,有了它就能安全的與遠程主機進行鏈接。算法
(一)、什麼是SSH shell
SSH的全稱是Secure Shell,簡單說來ssh是一種安全的外殼協議,用於兩個計算機間安全的遠程登錄,說它安全,是由於ssh採用公鑰加密的機制。最開始時用做遠程管理的工具是telnet,這個協議工做時在網絡上傳輸的數據全是明文,出於安全性的考慮,此協議的使用率愈來愈少。而ssh的安全性使用它成爲一種互聯網上遠程登錄主機的解決方案。在windows系統上經常使用到的有Putty、SecureCRT、XManager中的Xshell工具,而XManager工具是我見到的IT工做者中使用頻率極高的一個工具,在windows上好像沒有ssh協議的服務器端的實現,ssh協議的實現也分爲商業的實現和開源的實現,在這裏將是對ssh協議的一個開源實現的學習與記錄。Openssh便是Linux系統下開源的實現,它開放且免費。數據庫
(二)、ssh工做原理windows
說ssh是種安全的協議,是由於它採用公鑰加密。用主機A鏈接主機B來講明這個過程: 安全
一、主機A向主機B發起登錄請求; bash
二、主機B向主機A發送公鑰文件; 服務器
三、主機A把登錄密碼用接收到的公鑰加密後發送給主機B; 網絡
四、主機B用本身的私鑰解密加密信息,獲得登錄密碼; dom
五、主機B驗證密碼的正確性,正確則讓其登錄,不然則斷開。
(三)、中間人***(Man-in-the-middleattack)
基於公鑰加密這種驗證方式看起比較完美,登錄密碼的傳輸都是通過公鑰加密處理,即便被惡意劫持,只要私鑰文件沒有被泄露,那也不能解密加密信息,密碼的保密性獲得保障。但這種看似完美的工做方式也有其致命的弱點,若是主機B是***假裝的,他接收到主機A的登錄主機B的登錄請求,用本身的公鑰發送給主機A,而主機A很難辨別主機B的真僞,***就能夠採起這種方式得到主機B正確的登錄密碼,這就是有名的中間人***(Man-in-the-middleattack)。
要想應對中間人的***,則需避免登錄時輸入用戶口令的操做,ssh中的認證方式有兩種,一種是基於口令的方式,另外一種是基於公鑰的認證方式,後者就能在用戶不輸入口令的狀況下登錄主機。
(四)、配置文件
系統環境:
[root@bogon~]# cat /etc/redhat-release CentOSrelease 6.4 (Final) [root@bogon~]# uname -m x86_64
先看一下系統中安裝openssh所用的安裝包:
[root@bogon~]# rpm -qa *ssh* openssh-5.3p1-84.1.el6.x86_64 openssh-clients-5.3p1-84.1.el6.x86_64 libssh2-1.4.2-1.el6.x86_64 openssh-server-5.3p1-84.1.el6.x86_64
能夠用「rpm -ql 安裝包名稱」命令來查看各個安裝名生成的目錄結構,以下:
[root@bogon~]# rpm -ql openssh-clients
對於openssh,咱們須要關注的配置文件分爲兩類,一類是公共配置文件,另外一類是私有配置文件。公共配置文件又分爲服務端的配件文件和客戶端的配置文件。
/etc/ssh/sshd_config #服務端配置文件
/etc/ssh/ssd_config #客戶端配置文件
~/.ssh/* #私有配置文件
咱們主要關注的是服務端的配置文件和私有配置文件。
(五)、認證方式
ssh支持兩種認證方式,一種是基於用戶名與口令的認證,另外一種是基於密鑰的認證。
5.1基於用戶名與口令認證:
客戶端經過輸入用戶名與用戶登錄密碼的方式完成遠程登錄,雖然說是要求輸入用戶名及密碼來驗證,但ssh也會涉及到公鑰的發送,即遠程主機收到用戶遠程登錄請求時會把本身的公鑰發送給用戶端。 在windows下以ssh的方式登錄linux主機時,以xmanager爲例,當用xmanager中的xshell第一次登錄linux主機時會有如下的提示:
大體意思就是用戶包要鏈接的主機在用戶本地的存儲key的數據庫中沒有存儲,主機是不可信任的,而且給出了遠程主機公鑰的摘要信息,是否要斷續的鏈接此主機?那怎樣來驗證我所要鏈接的主機(192.168.0.201)是真實的,不是一個假裝的主機,避免中間人***。當點擊「Accept&Save」,那xshell會把遠程主機的公鑰信息保存下來,在這裏能夠查看到:
應對中間人***,SSH有2種方法應對,一是遠程主機把本身的公鑰拿到CA處作認證,申請一個數字證書;二是遠程主機把本身公鑰的指紋信息公佈出來,好比公佈在網站上,你們均可查看到公鑰的指紋信息。這樣用戶在登錄時就能夠鑑別主機的真僞了。提取主機的指紋信息的方法以下:
[root@Server-A ~]# ssh-keygen -lf/etc/ssh/ssh_host_dsa_key.pub 102439:61:e5:80:e8:09:b3:83:10:39:c8:b4:5e:ca:45:7e /etc/ssh/ssh_host_dsa_key.pub(DSA)
遠程主機能夠把這個採用dsa算法的指紋信息發佈在一個網站上,那我用xshell去遠程鏈接時就可對比一下指紋信息是否是同樣,若是是同樣的那就能證實我鏈接的是真實的主機。
在linux下用ssh方式登錄另外一linux主機時,若是第一次登錄會有以下的提示:
[root@Server-A~]# ssh 192.168.0.201 Theauthenticity of host '192.168.0.201 (192.168.0.201)' can't be established. RSAkey fingerprint is 4c:a3:2f:29:69:86:f6:0f:38:25:8c:7c:7c:3b:d5:91. Areyou sure you want to continue connecting (yes/no)?
表示的意義與用xshell登錄時的提示相同,輸入「yes」,再輸入遠程主機的口令便可登錄,登錄成功後本地主機會生成「~/.ssh/known_hosts」文件,這文件裏保存着遠程主機的公鑰信息,這樣下次再遠程登錄時就不須要發送公鑰信息了,直接輸入口令便可。
5.2 基於公鑰的認證:
基於用戶口令的認證方式每次都要求用戶提供正確的口令,比較麻煩,且增長了口令泄露的機率。而基於公鑰的認證則不須要用戶輸入口令便可完成遠程登錄。這種認證方式是這樣工做的:用戶把本身的公鑰存儲在遠程主機上,在登錄時,遠程主機向用戶發送一段隨機字符串,用戶用本身的私鑰加密這段隨機數字,並把加密後的信息發送給遠程主機,遠程主機用事先存儲的公鑰來解密這個數據,若是解密成功,則說明請求登錄的用戶是可信任的,這樣就直接容許用戶登錄,而不要求輸入密碼了。這種認證方式須要把用戶本身的公鑰保存到遠程主機上。若沒有現成的公鑰,那就生成:
[root@Server-A~]# ssh-keygen -t rsa Generatingpublic/private rsa key pair. Enterfile in which to save the key (/root/.ssh/id_rsa): Enterpassphrase (empty for no passphrase): Entersame passphrase again: Youridentification has been saved in /root/.ssh/id_rsa. Yourpublic key has been saved in /root/.ssh/id_rsa.pub. Thekey fingerprint is: 9b:ef:2c:6a:92:05:c7:f4:4b:b8:4e:b4:ce:05:2f:0croot@Server-A Thekey's randomart p_w_picpath is: +--[RSA 2048]----+ | | | . | | o o | | E * o | | * *S. | | B +o | | B oo | | o = .o | | o.. o+ | +-----------------+ [root@Server-A~]# ls .ssh/ id_rsa id_rsa.pub known_hosts
此時在家目錄下的「./ssh」目錄下生成了兩個文件,一個id_rsa(私鑰文件),id_rsa.pub(公鑰文件)。接着把公鑰文件拷貝到遠程主機:
[root@Server-A ~]# scp .ssh/id_rsa.pub 192.168.0.201:/root/.ssh/authorized_keys
這裏的「authorized_keys」這個文件名不能更改,這是由「/etc/ssh/sshd_config」文件定義的。
測試一下可否不輸入密碼就能遠程登錄Server_B主機:
[root@Server-A ~]# ssh 192.168.0.201 Address 192.168.0.201 maps to bogon, butthis does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! [root@Server-B ~]#
沒錯,成功了,但有報告信息,這是由於在/etc/hosts文件裏沒有增長兩主機的映射關係,增長就能夠了,在兩主機中的「/etc/hosts」文件中都增長如下兩行:
[root@Server-A ~]# echo"192.168.0.200 Server-A">> /etc/hosts [root@Server-A ~]# echo "192.168.0.201 Server-B" >> /etc/hosts
上邊用「scp」命令直接把主機的公鑰文件拷貝到遠程主機用戶家目錄下的「root/.ssh/authorized_keys」,其實還有一個更好的方法,ssh爲咱們提供了一個客戶端工具,即「ssh-copy-id」,這個工具能將本地主機的公鑰自動拷貝到遠程主機上生成「authorized_keys」文件,且會讓這個文件的權限爲「600」這樣更爲安全,此命令的用法以下:
[root@Server-A ~]# ssh-copy-id root@192.168.0.201
建議用這個命令來實現無密碼公鑰登錄,由於用「scp」命令把公鑰拷貝到遠程主機後,不會把authorized_keys文件的權限修改爲「600」,在某些linux版本下是沒法實現基於公鑰登錄的。
用xshell這個神器也可實現基於公鑰的認證,方法與在linux上相似,只是鏈接主機成了windows下的了,方法以下:
一、打開密鑰生成嚮導工具
二、選擇密鑰的類型與加密長度
三、直接下一步
四、下一步
五、導出公鑰信息
六、完成
這樣就生成了一個「id_rsa_1024.pub」公鑰文件,把這個公鑰文件上傳到遠程主機,並把公鑰信息追加到「~/.ssh/authorized_keys」。
最後配置xshell使用密鑰方式登錄服務器:
一、打開Xshell,點擊「New」按鈕,彈出「NewSession Properties」對話框,在「Connection」欄目中,填寫好相關信息,以下圖:
二、在「Authentication」中填寫認證方式和私鑰,以下圖:
這樣設置好後,也能夠基於密鑰登錄遠程主機了。