介紹
SSH 是創(chuàng)建在應(yīng)用層和傳輸層基礎(chǔ)上的安全協(xié)議,為計(jì)算機(jī)上的 Shell(殼層)提供安全的傳輸和使用環(huán)境。
SSH 只是協(xié)議,有多種實(shí)現(xiàn)方式,本文基于其開源實(shí)現(xiàn) OpenSSH
遠(yuǎn)程登錄
SSH主要用于遠(yuǎn)程登錄:
1
|
$ ssh user@host |
當(dāng)本地用戶名和遠(yuǎn)程用戶名一致時(shí),可省略用戶名:
1
|
$ ssh host |
SSH 協(xié)議默認(rèn)端口是22,指定端口可使用 -p 參數(shù)
1
|
$ ssh -p 2222 user@host |
MITM
SSH 采用公鑰加密的方式來保證傳輸安全。過程如下:
- 客戶端發(fā)起登錄請(qǐng)求,遠(yuǎn)程主機(jī)將自己的公鑰發(fā)個(gè)用戶;
- 客戶端使用該公鑰將登錄密碼加密后發(fā)送給遠(yuǎn)程主機(jī);
- 遠(yuǎn)程主機(jī)使用私鑰解密登錄密碼,如密碼正確則允許客戶端登錄。
However!
- 由于 SSH 協(xié)議的公鑰是自己簽發(fā)的,并不像HTTPS 的SSL證書是有CA機(jī)構(gòu)頒發(fā)的。如果有人插在用戶與遠(yuǎn)程主機(jī)之間,截獲登錄請(qǐng)求,然后冒充遠(yuǎn)程主機(jī),將偽造的公鑰發(fā)給客戶端,那么用戶則很難辨別真?zhèn)巍?/li>
- 這樣就可以獲取用戶登錄密碼,用來登錄遠(yuǎn)程主機(jī)。這就是MITM,(Man-in-the-middle attack,中間人攻擊)
密碼登錄
第一次登錄遠(yuǎn)程主機(jī),會(huì)有如下提示:
1
2
3
4
|
$ ssh 10.0.0.12 The authenticity of host '10.0.0.12 (10.0.0.12)' can't be established. RSA key fingerprint is 3a:45:30:52:b5:ea:2a:55:e7:23:41:ef:16:76:0b:8d. Are you sure you want to continue connecting ( yes /no )? |
意思是:無法確認(rèn)遠(yuǎn)程主機(jī)真實(shí)性,指知道它的公鑰指紋,是否繼續(xù)連接?
公鑰指紋(fingerprint):公鑰采用RSA算法,長(zhǎng)度較長(zhǎng)難以比對(duì),所以對(duì)其進(jìn)行MD5計(jì)算,得到128位的指紋,即上例中的3a:45:30:52:b5:ea:2a:55:e7:23:41:ef:16:76:0b:8d
其實(shí)并沒有什么有效便捷的方式確認(rèn)公鑰指紋的真實(shí)性,確認(rèn)接受遠(yuǎn)程主機(jī)公鑰:
1
|
Are you sure you want to continue connecting ( yes /no )? yes |
系統(tǒng)提示遠(yuǎn)程主機(jī)已加入到受信主機(jī)列表:
1
|
Warning: Permanently added '10.0.0.12' (RSA) to the list of known hosts. |
然后提示輸入密碼:
1
|
[email protected]'s password: |
輸入密碼正確,就可以正常登陸了。
當(dāng)遠(yuǎn)程主機(jī)的公鑰被接受以后,它就會(huì)被保存在文件$HOME/.ssh/known_hosts之中。下次再連接這臺(tái)主機(jī),系統(tǒng)會(huì)發(fā)現(xiàn)它的公鑰已經(jīng)保存在本地了,從而跳過警告部分,直接提示輸入密碼。
公鑰登陸
除了密碼登錄,SSH 還支持公鑰登錄。
“公鑰登錄”原理是:用戶將自己的公鑰儲(chǔ)存在遠(yuǎn)程主機(jī)上。登錄的時(shí)候,遠(yuǎn)程主機(jī)會(huì)向用戶發(fā)送一段隨機(jī)字符串,用戶用自己的私鑰加密后,再發(fā)回來。遠(yuǎn)程主機(jī)用事先儲(chǔ)存的公鑰進(jìn)行解密,如果成功,就證明用戶是可信的,直接允許登錄shell,不再要求輸入密碼。
公鑰登錄需要用戶提供自己的公鑰,一般保存在 $HOME/.ssh/ 目錄下,id_rsa是私鑰,id_rsa.pub是公鑰。如果沒有可以通過ssh-keygen生成。
1
2
3
4
|
$ ls -1 ~/. ssh id_rsa id_rsa.pub known_hosts |
需要把公鑰發(fā)送到遠(yuǎn)程主機(jī):
1
2
|
# ssh-copy-id [-i [identity_file]] [user@]machine |
此后再登錄就不需要輸入密碼了。
如果還是無法使用公鑰登錄,可以檢查一下遠(yuǎn)程主機(jī)SSH配置/etc/ssh/sshd_config,打開如下注釋并重啟SSH服務(wù)[我發(fā)現(xiàn)CentOS release 6.8 (Final)默認(rèn)SSH配置中注釋掉以下內(nèi)容也是可以使用公鑰登錄的]:
1
2
3
4
|
> #RSAAuthentication yes > #PubkeyAuthentication yes > #AuthorizedKeysFile .ssh/authorized_keys > |
authorized_keys文件
遠(yuǎn)程主機(jī)將用戶的公鑰,保存在 $HOME/.ssh/authorized_keys 中。公鑰是一段字符串,也可以手動(dòng)追加到遠(yuǎn)程主機(jī)authorized_keys文件中,每行一個(gè)。
也可以通過如下命令代替ssh-copy-id,解釋公鑰的保存過程:
1
|
$ ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/. ssh /id_rsa .pub |
遠(yuǎn)程操作
SSH可以用于直接在遠(yuǎn)程主機(jī)上操作
1
2
|
# 查看遠(yuǎn)程主機(jī)Nginx進(jìn)程 ssh 10.0.0.12 'ps -ef | grep nginx' |
端口轉(zhuǎn)發(fā)
本地轉(zhuǎn)發(fā)
本地轉(zhuǎn)發(fā)是指:把本地主機(jī)端口通過待登錄主機(jī)端口轉(zhuǎn)發(fā)到遠(yuǎn)程主機(jī)端口上去。
本地轉(zhuǎn)發(fā)通過參數(shù) -L 指定,格式: -L [本地主機(jī):]本地主機(jī)端口:遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)端口
1
|
ssh -L 5000:www.google.com:80 user@host |
通過上面的命令,訪問本地5000端口,相當(dāng)于訪問遠(yuǎn)程主機(jī)www.google.com的80端口,并且這是通過通過登錄主機(jī)來安全地轉(zhuǎn)發(fā)數(shù)據(jù)的。當(dāng)不能直接訪問遠(yuǎn)程主機(jī)某端口,而登錄主機(jī)可以訪問時(shí),可以使用這種方式將遠(yuǎn)程主機(jī)端口綁定到本地。
遠(yuǎn)程轉(zhuǎn)發(fā)
遠(yuǎn)程轉(zhuǎn)發(fā)是指:把登錄主機(jī)端口通過本地主機(jī)端口轉(zhuǎn)發(fā)到遠(yuǎn)程主機(jī).
遠(yuǎn)程轉(zhuǎn)發(fā)通過參數(shù) -R 指定,格式: -R 登錄主機(jī)端口:遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)端口。
1
|
ssh -R 8080:localhost:80 user@host |
通過上面的命令,訪問登錄主機(jī)的 8080 端口就相當(dāng)于訪問 localhost:80!
例如下面這種場(chǎng)景:我在本機(jī)起了一個(gè)web服務(wù),希望別人從外網(wǎng)訪問或測(cè)試,但是外網(wǎng)是不能直接訪問我的內(nèi)網(wǎng)機(jī)器。所以我可以在本機(jī)上執(zhí)行上面的命令,這樣就就可以通過訪問登錄主機(jī)的80端口,來訪問本機(jī)的80端口了,從而實(shí)現(xiàn)外網(wǎng)訪問內(nèi)網(wǎng)的應(yīng)用了。簡(jiǎn)直太方便~
動(dòng)態(tài)轉(zhuǎn)發(fā)
動(dòng)態(tài)轉(zhuǎn)發(fā)不需要指定特定的目標(biāo)主機(jī)和端口號(hào),可以實(shí)現(xiàn)不加密的網(wǎng)絡(luò)連接,全部走SSH連接,從而提高安全性。
例如把本地5000端口的數(shù)據(jù),都通過SSH傳向登錄主機(jī):
1
|
ssh -D 5000 user@host |
例如可以用于科學(xué)上網(wǎng)的場(chǎng)景,在瀏覽器中設(shè)置代理類型為 SOCKS(5),主機(jī)及端口為127.0.0.1:5000 就可以通過登錄主機(jī)科學(xué)上網(wǎng)了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。