SSH的原理與應(yīng)用
一 SSH簡(jiǎn)介
SSH是Secure Shell的所寫(xiě),也叫做安全外殼協(xié)議。SSH的主要目的是實(shí)現(xiàn)安全遠(yuǎn)程登錄。
二 SSH工作原理
SSH的安全性比較好,其對(duì)數(shù)據(jù)進(jìn)行加密的方式主要有兩種:對(duì)稱(chēng)加密(密鑰加密)和非對(duì)稱(chēng)加密(公鑰加密)。
對(duì)稱(chēng)加密指加密解密使用的是同一套秘鑰。Client端把密鑰加密后發(fā)送給Server端,Server用同一套密鑰解密。對(duì)稱(chēng)加密的加密強(qiáng)度比較高,很難破解。但是,Client數(shù)量龐大,很難保證密鑰不泄漏。如果有一個(gè)Client端的密鑰泄漏,那么整個(gè)系統(tǒng)的安全性就存在嚴(yán)重的漏洞。為了解決對(duì)稱(chēng)加密的漏洞,于是就產(chǎn)生了非對(duì)稱(chēng)加密。非對(duì)稱(chēng)加密有兩個(gè)密鑰:“公鑰”和“私鑰”。公鑰加密后的密文,只能通過(guò)對(duì)應(yīng)的私鑰進(jìn)行解密。想從公鑰推理出私鑰幾乎不可能,所以非對(duì)稱(chēng)加密的安全性比較高。
SSH的加密原理中,使用了RSA非對(duì)稱(chēng)加密算法。整個(gè)過(guò)程是這樣的:(1)遠(yuǎn)程主機(jī)收到用戶(hù)的登錄請(qǐng)求,把自己的公鑰發(fā)給用戶(hù)。(2)用戶(hù)使用這個(gè)公鑰,將登錄密碼加密后,發(fā)送回來(lái)。(3)遠(yuǎn)程主機(jī)用自己的私鑰,解密登錄密碼,如果密碼正確,就同意用戶(hù)登錄。
三 中間人攻擊
SSH之所以能夠保證安全,原因在于它采用了公鑰加密,這個(gè)過(guò)程本身是安全的,但是實(shí)際用的時(shí)候存在一個(gè)風(fēng)險(xiǎn):如果有人截獲了登錄請(qǐng)求,然后冒充遠(yuǎn)程主機(jī),將偽造的公鑰發(fā)給用戶(hù),那么用戶(hù)很難辨別真?zhèn)?。因?yàn)椴幌駂ttps協(xié)議,SSH協(xié)議的公鑰是沒(méi)有證書(shū)中心(CA)公證的,是自己簽發(fā)的。
如果攻擊者插在用戶(hù)與遠(yuǎn)程主機(jī)之間(比如在公共的wifi區(qū)域),用偽造的公鑰,獲取用戶(hù)的登錄密碼。再用這個(gè)密碼登錄遠(yuǎn)程主機(jī),那么SSH的安全機(jī)性就不存在了。這種風(fēng)險(xiǎn)就是著名的"中間人攻擊"(Man-in-the-middle attack)。那么SSH協(xié)議是怎樣應(yīng)對(duì)的呢?
四 口令登錄
如果是第一次登錄遠(yuǎn)程機(jī),會(huì)出現(xiàn)以下提示:
$ ssh user@host
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
因?yàn)楣€長(zhǎng)度較長(zhǎng)(采用RSA算法,長(zhǎng)達(dá)1024位),很難比對(duì),所以對(duì)其進(jìn)行MD5計(jì)算,將它變成一個(gè)128位的指紋。如98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,這樣比對(duì)就容易多了。
經(jīng)過(guò)比對(duì)后,如果用戶(hù)接受這個(gè)遠(yuǎn)程主機(jī)的公鑰,系統(tǒng)會(huì)出現(xiàn)一句提示語(yǔ):
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
表示host主機(jī)已得到認(rèn)可,然后再輸入登錄密碼就可以登錄了。
當(dāng)遠(yuǎn)程主機(jī)的公鑰被接受以后,它就會(huì)被保存在文件~/.ssh/known_hosts之中。下次再連接這臺(tái)主機(jī),系統(tǒng)就會(huì)認(rèn)出它的公鑰已經(jīng)保存在本地了,從而跳過(guò)警告部分,直接提示輸入密碼。每個(gè)SSH用戶(hù)都有自己的known_hosts文件,此外系統(tǒng)也有一個(gè)這樣的文件,一般是/etc/ssh/ssh_known_hosts,保存一些對(duì)所有用戶(hù)都可信賴(lài)的遠(yuǎn)程主機(jī)的公鑰。
五 公鑰登錄
使用密碼登錄,每次都必須輸入密碼,非常麻煩。好在SSH還提供了公鑰登錄,可以省去輸入密碼的步驟。
所謂"公鑰登錄",原理很簡(jiǎn)單,就是用戶(hù)將自己的公鑰儲(chǔ)存在遠(yuǎn)程主機(jī)上。登錄的時(shí)候,遠(yuǎn)程主機(jī)會(huì)向用戶(hù)發(fā)送一段隨機(jī)字符串,用戶(hù)用自己的私鑰加密后,再發(fā)回來(lái)。遠(yuǎn)程主機(jī)用事先儲(chǔ)存的公鑰進(jìn)行解密,如果成功,就證明用戶(hù)是可信的,直接允許登錄shell,不再要求密碼。
這種方法要求用戶(hù)必須提供自己的公鑰。如果沒(méi)有現(xiàn)成的,可以直接用ssh-keygen生成一個(gè):
$ ssh-keygen
運(yùn)行上面的命令以后,系統(tǒng)會(huì)出現(xiàn)一系列提示,可以一路回車(chē)。其中有一個(gè)問(wèn)題是,要不要對(duì)私鑰設(shè)置口令(passphrase),如果擔(dān)心私鑰的安全,這里可以設(shè)置一個(gè)。
運(yùn)行結(jié)束以后,在~/.ssh/目錄下,會(huì)新生成兩個(gè)文件:id_rsa.pub和id_rsa。前者是公鑰,后者是私鑰。
這時(shí)再輸入下面的命令,將公鑰傳送到遠(yuǎn)程主機(jī)host上面:
$ ssh-copy-id user@host
遠(yuǎn)程主機(jī)將用戶(hù)的公鑰,保存在登錄后的用戶(hù)主目錄的~/.ssh/authorized_keys文件中。
這樣,以后就登錄遠(yuǎn)程主機(jī)不需要輸入密碼了。
如果還是不行,就用vim打開(kāi)遠(yuǎn)程主機(jī)的/etc/ssh/sshd_config這個(gè)文件,將以下幾行的注釋去掉。
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
然后,重啟遠(yuǎn)程主機(jī)的ssh服務(wù)。
Redhat6系統(tǒng)
service ssh restart
Redhat7系統(tǒng)
systemctl restart ssh
ubuntu系統(tǒng)
service ssh restart
debian系統(tǒng)
/etc/init.d/ssh restart
六 SSH端口轉(zhuǎn)發(fā)
SSH端口轉(zhuǎn)發(fā)有三種:動(dòng)態(tài)端口轉(zhuǎn)發(fā)、本地端口轉(zhuǎn)發(fā)、遠(yuǎn)程端口轉(zhuǎn)發(fā)。
這三種方式說(shuō)起來(lái)有點(diǎn)難理解,通過(guò)例子會(huì)好理解一點(diǎn)。假設(shè)有三臺(tái)主機(jī),host1、host2、host3。
動(dòng)態(tài)端口轉(zhuǎn)發(fā)是找一個(gè)代理端口,然后通過(guò)代理端口去連相應(yīng)的端口。動(dòng)態(tài)端口轉(zhuǎn)發(fā)的好處在于通過(guò)代理端口可以去找很多需要連接的端口,提高了工作效率。比如host1本來(lái)是連不上host2的,而host3卻可以連上host2。host1可以找到host3作代理,然后通過(guò)host3去連接host2的相應(yīng)端口
本地端口轉(zhuǎn)發(fā)也是找到第三方,通過(guò)第三方再連接想要連接的端口,但這種方式的端口轉(zhuǎn)發(fā)是固定的,是點(diǎn)對(duì)點(diǎn)的。比如假定host1是本地主機(jī),host2是遠(yuǎn)程主機(jī)。由于種種原因,這兩臺(tái)主機(jī)之間無(wú)法連通。但是,另外還有一臺(tái)host3,可以同時(shí)連上host1和host2這兩臺(tái)主機(jī)。通過(guò)host3,將host1連上host2。host1找到host3,host1和host3之間就像有一條數(shù)據(jù)傳輸?shù)牡缆?,通常被稱(chēng)為“SSH隧道”,通過(guò)這條隧道host1就可以連上host2。
遠(yuǎn)程端口轉(zhuǎn)發(fā)和本地端口轉(zhuǎn)發(fā)就是反過(guò)來(lái)了。假如host1在外網(wǎng),host2在內(nèi)網(wǎng),正常情況下,host1不能訪問(wèn)host2。通過(guò)遠(yuǎn)程端口轉(zhuǎn)發(fā),host2可以反過(guò)來(lái)訪問(wèn)host1。host2和host1之間形成了一條道路,host1就可以通過(guò)這條道路去訪問(wèn)host2。
七 SSH基本用法
SSH主要用于遠(yuǎn)程登錄:
假定你要以用戶(hù)名user,登錄遠(yuǎn)程主機(jī)host,只要一條簡(jiǎn)單命令就可以了。
$ ssh user@host
如果本地用戶(hù)名與遠(yuǎn)程用戶(hù)名一致,登錄時(shí)可以省略用戶(hù)名。
$ ssh host
SSH的默認(rèn)端口是22,也就是說(shuō),你的登錄請(qǐng)求會(huì)送進(jìn)遠(yuǎn)程主機(jī)的22端口。使用p參數(shù),可以修改這個(gè)端口。
$ ssh -p 2018 user@host
上面這條命令表示,ssh直接連接遠(yuǎn)程主機(jī)的2018端口。