ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

1.1 非對(duì)稱加密基礎(chǔ)知識(shí)

對(duì)稱加密:加密和解密使用一樣的算法,只要解密時(shí)提供與加密時(shí)一致的密碼就可以完成解密。例如QQ登錄密碼,銀行卡密碼,只要保證密碼正確就可以。

非對(duì)稱加密:通過(guò)公鑰(public key)和私鑰(private key)來(lái)加密、解密。公鑰加密的內(nèi)容可以使用私鑰解密,私鑰加密的內(nèi)容可以使用公鑰解密。一般使用公鑰加密,私鑰解密,但并非絕對(duì)如此,例如CA簽署證書(shū)時(shí)就是使用自己的私鑰加密。在接下來(lái)介紹的SSH服務(wù)中,雖然一直建議分發(fā)公鑰,但也可以分發(fā)私鑰。

所以,如果A生成了(私鑰A,公鑰A),B生成了(私鑰B,公鑰B),那么A和B之間的非對(duì)稱加密會(huì)話情形包括:

(1).A將自己的公鑰A分發(fā)給B,B拿著公鑰A將數(shù)據(jù)進(jìn)行加密,并將加密的數(shù)據(jù)發(fā)送給A,A將使用自己的私鑰A解密數(shù)據(jù)。

(2).A將自己的公鑰A分發(fā)給B,并使用自己的私鑰A加密數(shù)據(jù),然后B使用公鑰A解密數(shù)據(jù)。

(3).B將自己的公鑰B分發(fā)給A,A拿著公鑰B將數(shù)據(jù)進(jìn)行加密,并將加密的數(shù)據(jù)發(fā)送給B,B將使用自己的私鑰B解密數(shù)據(jù)。

(4).B將自己的公鑰B分發(fā)給A,并使用自己的私鑰B加密數(shù)據(jù),然后A使用公鑰B解密數(shù)據(jù)。

雖然理論上支持4種情形,但在SSH的身份驗(yàn)證階段,SSH只支持服務(wù)端保留公鑰,客戶端保留私鑰的方式所以方式只有兩種:客戶端生成密鑰對(duì),將公鑰分發(fā)給服務(wù)端;服務(wù)端生成密鑰對(duì),將私鑰分發(fā)給客戶端。只不過(guò)出于安全性和便利性,一般都是客戶端生成密鑰對(duì)并分發(fā)公鑰。后文將給出這兩種分發(fā)方式的示例。

1.2 SSH概要

(1).SSH是傳輸層和應(yīng)用層上的安全協(xié)議,它只能通過(guò)加密連接雙方會(huì)話的方式來(lái)保證連接的安全性。當(dāng)使用ssh連接成功后,將建立客戶端和服務(wù)端之間的會(huì)話,該會(huì)話是被加密的,之后客戶端和服務(wù)端的通信都將通過(guò)會(huì)話傳輸。

(2).SSH服務(wù)的守護(hù)進(jìn)程為sshd,默認(rèn)監(jiān)聽(tīng)在22端口上。

(3).所有ssh客戶端工具,包括ssh命令,scp,sftp,ssh-copy-id等命令都是借助于ssh連接來(lái)完成任務(wù)的。也就是說(shuō)它們都連接服務(wù)端的22端口,只不過(guò)連接上之后將待執(zhí)行的相關(guān)命令轉(zhuǎn)換傳送到遠(yuǎn)程主機(jī)上,由遠(yuǎn)程主機(jī)執(zhí)行。

(4).ssh客戶端命令(ssh、scp、sftp等)讀取兩個(gè)配置文件:全局配置文件/etc/ssh/ssh_config和用戶配置文件~/.ssh/config。實(shí)際上命令行上也可以傳遞配置選項(xiàng)。它們生效的優(yōu)先級(jí)是:命令行配置選項(xiàng) > ~/.ssh/config > /etc/ssh/ssh_config。

(5).ssh涉及到兩個(gè)驗(yàn)證:主機(jī)驗(yàn)證和用戶身份驗(yàn)證。通過(guò)主機(jī)驗(yàn)證,再通過(guò)該主機(jī)上的用戶驗(yàn)證,就能唯一確定該用戶的身份。一個(gè)主機(jī)上可以有很多用戶,所以每臺(tái)主機(jī)的驗(yàn)證只需一次,但主機(jī)上每個(gè)用戶都需要單獨(dú)進(jìn)行用戶驗(yàn)證。

(6).ssh支持多種身份驗(yàn)證,最常用的是密碼驗(yàn)證機(jī)制和公鑰認(rèn)證機(jī)制,其中公鑰認(rèn)證機(jī)制在某些場(chǎng)景實(shí)現(xiàn)雙機(jī)互信時(shí)幾乎是必須的。雖然常用上述兩種認(rèn)證機(jī)制,但認(rèn)證時(shí)的順序默認(rèn)是gssapi-with-mic,hostbased,publickey,keyboard-interactive,password。注意其中的主機(jī)認(rèn)證機(jī)制hostbased不是主機(jī)驗(yàn)證,由于主機(jī)認(rèn)證用的非常少(它所讀取的認(rèn)證文件為/etc/hosts.equiv或/etc/shosts.equiv),所以網(wǎng)絡(luò)上比較少見(jiàn)到它的相關(guān)介紹。總的來(lái)說(shuō),通過(guò)在ssh配置文件(注意不是sshd配置文件)中使用指令PreferredAuthentications改變認(rèn)證順序不失為一種驗(yàn)證的效率提升方式。

(7).ssh客戶端其實(shí)有不少很強(qiáng)大的功能,如端口轉(zhuǎn)發(fā)(隧道模式)、代理認(rèn)證、連接共享(連接復(fù)用)等。

(8).ssh服務(wù)端配置文件為/etc/ssh/sshd_config,注意和客戶端的全局配置文件/etc/ssh/ssh_config區(qū)分開(kāi)來(lái)。

(9).最重要的一點(diǎn),ssh登錄時(shí)會(huì)請(qǐng)求分配一個(gè)偽終端。但有些身份認(rèn)證程序如sudo可以禁止這種類型的終端分配,導(dǎo)致ssh連接失敗。例如使用ssh執(zhí)行sudo命令時(shí)sudo就會(huì)驗(yàn)證是否要分配終端給ssh。

1.3 SSH認(rèn)證過(guò)程分析

假如從客戶端A(172.16.10.5)連接到服務(wù)端B(172.16.10.6)上,將包括主機(jī)驗(yàn)證和用戶身份驗(yàn)證兩個(gè)過(guò)程,以RSA非對(duì)稱加密算法為例。

[root@xuexi ~]# ssh 172.16.10.6

服務(wù)端B上首先啟動(dòng)了sshd服務(wù)程序,即開(kāi)啟了ssh服務(wù),打開(kāi)了22端口(默認(rèn))。

1.3.1 主機(jī)驗(yàn)證過(guò)程

當(dāng)客戶端A要連接B時(shí),首先將進(jìn)行主機(jī)驗(yàn)證過(guò)程,即判斷主機(jī)B是否是否曾經(jīng)連接過(guò)。

判斷的方法是讀取~/.ssh/known_hosts文件和/etc/ssh/known_hosts文件,搜索是否有172.16.10.6的主機(jī)信息(主機(jī)信息稱為host key,表示主機(jī)身份標(biāo)識(shí))。如果沒(méi)有搜索到對(duì)應(yīng)該地址的host key,則詢問(wèn)是否保存主機(jī)B發(fā)送過(guò)來(lái)的host key,如果搜索到了該地址的host key,則將此host key和主機(jī)B發(fā)送過(guò)來(lái)的host key做比對(duì),如果完全相同,則表示主機(jī)A曾經(jīng)保存過(guò)主機(jī)B的host key,無(wú)需再保存,直接進(jìn)入下一個(gè)過(guò)程——身份驗(yàn)證,如果不完全相同,則提示是否保存主機(jī)B當(dāng)前使用的host key。

詢問(wèn)是否保存host key的過(guò)程如下所示:

[root@xuexi ~]# ssh 172.16.10.6 The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf.  Are you sure you want to continue connecting (yes/no)? yes

或者windows端使用圖形界面ssh客戶端工具時(shí):

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

在說(shuō)明身份驗(yàn)證過(guò)程前,先看下known_hosts文件的格式。以~/.ssh/known_hosts為例。

[root@xuexi ~]# cat ~/.ssh/known_hosts172.16.10.6 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC675dv1w+GDYViXxqlTspUHsQjargFPSnR9nEqCyUgm5/32jXAA3XTJ4LUGcDHBuQ3p3spW/eO5hAP9eeTv5HQzTSlykwsu9He9w3ee+TV0JjBFulfBR0weLE4ut0PurPMbthE7jIn7FVDoLqc6o64WvN8LXssPDr8WcwvARmwE7pYudmhnBIMPV/q8iLMKfquREbhdtGLzJRL9DrnO9NNKB/EeEC56GY2t76p9ThOB6ES6e/87co2HjswLGTWmPpiqY8K/LA0LbVvqRrQ05+vNoNIdEfk4MXRn/IhwAh6j46oGelMxeTaXYC+r2kVELV0EvYV/wMa8QHbFPSM6nLz

該文件中,每行一個(gè)host key,行首是主機(jī)名,它是搜索host key時(shí)的索引,主機(jī)名后的內(nèi)容即是host key部分。以此文件為例,它表示客戶端A曾經(jīng)試圖連接過(guò)172.16.10.6這個(gè)主機(jī)B,并保存了主機(jī)B的host key,下次連接主機(jī)B時(shí),將搜索主機(jī)B的host key,并與172.16.10.6傳送過(guò)來(lái)的host key做比較,如果能匹配上,則表示該host key確實(shí)是172.16.10.6當(dāng)前使用的host key,如果不能匹配上,則表示172.16.10.6修改過(guò)host key,或者此文件中的host key被修改過(guò)。

那么主機(jī)B當(dāng)前使用的host key保存在哪呢?在/etc/ssh/ssh_host*文件中,這些文件是服務(wù)端(此處即主機(jī)B)的sshd服務(wù)程序啟動(dòng)時(shí)重建的。以rsa算法為例,則保存在/etc/ssh/ssh_host_rsa_key和/etc/ssh/ssh_host_rsa_key.pub中,其中公鑰文件/etc/ssh/ssh_host_rsa_key.pub中保存的就是host key。

[root@xuexi ~]# cat /etc/ssh/ssh_host_rsa_key.pub   # 在主機(jī)B上查看ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC675dv1w+GDYViXxqlTspUHsQjargFPSnR9nEqCyUgm5/32jXAA3XTJ4LUGcDHBuQ3p3spW/eO5hAP9eeTv5HQzTSlykwsu9He9w3ee+TV0JjBFulfBR0weLE4ut0PurPMbthE7jIn7FVDoLqc6o64WvN8LXssPDr8WcwvARmwE7pYudmhnBIMPV/q8iLMKfquREbhdtGLzJRL9DrnO9NNKB/EeEC56GY2t76p9ThOB6ES6e/87co2HjswLGTWmPpiqY8K/LA0LbVvqRrQ05+vNoNIdEfk4MXRn/IhwAh6j46oGelMxeTaXYC+r2kVELV0EvYV/wMa8QHbFPSM6nLz

發(fā)現(xiàn)/etc/ssh/ssh_host_rsa_key.pub文件內(nèi)容和~/.ssh/known_hosts中該主機(jī)的host key部分完全一致,只不過(guò)~/.ssh/known_hosts中除了host key部分還多了一個(gè)主機(jī)名,這正是搜索主機(jī)時(shí)的索引。

綜上所述,在主機(jī)驗(yàn)證階段,服務(wù)端持有的是私鑰,客戶端保存的是來(lái)自于服務(wù)端的公鑰。注意,這和身份驗(yàn)證階段密鑰的持有方是相反的。

實(shí)際上,ssh并非直接比對(duì)host key,因?yàn)閔ost key太長(zhǎng)了,比對(duì)效率較低。所以ssh將host key轉(zhuǎn)換成host key指紋,然后比對(duì)兩邊的host key指紋即可。指紋格式如下:

[root@xuexi ~]# ssh 172.16.10.6 The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf.  Are you sure you want to continue connecting (yes/no)? yes

host key的指紋可由ssh-kegen計(jì)算得出。例如,下面分別是主機(jī)A(172.16.10.5)保存的host key指紋,和主機(jī)B(172.16.10.6)當(dāng)前使用的host key的指紋。可見(jiàn)它們是完全一樣的。

[root@xuexi ~]# ssh-keygen -l -f ~/.ssh/known_hosts2048 f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf 172.16.10.6 (RSA)    [root@xuexi ~]# ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key2048 f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf   (RSA)

其實(shí)ssh還支持host key模糊比較,即將host key轉(zhuǎn)換為圖形化的指紋。這樣,圖形結(jié)果相差大的很容易就比較出來(lái)。之所以說(shuō)是模糊比較,是因?yàn)閷?duì)于非常近似的圖形化指紋,ssh可能會(huì)誤判。圖形化指紋的生成方式如下:只需在上述命令上加一個(gè)”-v”選項(xiàng)進(jìn)入詳細(xì)模式即可。

[root@xuexi ~]# ssh-keygen -lv -f ~/.ssh/known_hosts2048 f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf 172.16.10.6 (RSA)+--[ RSA 2048]----+  |                 |  |                 |  |           .     |  |          o      |  |        S. . +   |  |      . +++ + .  |  |       B.+.= .   |  |      + B.  +.   |  |       o.+.  oE  |  +-----------------+

1.3.2 身份驗(yàn)證過(guò)程

主機(jī)驗(yàn)證通過(guò)后,將進(jìn)入身份驗(yàn)證階段。SSH支持多種身份驗(yàn)證機(jī)制,它們的驗(yàn)證順序如下:gssapi-with-mic,hostbased,publickey,keyboard-interactive,password,但常見(jiàn)的是密碼認(rèn)證機(jī)制(password)和公鑰認(rèn)證機(jī)制(public key)。當(dāng)公鑰認(rèn)證機(jī)制未通過(guò)時(shí),再進(jìn)行密碼認(rèn)證機(jī)制的驗(yàn)證。這些認(rèn)證順序可以通過(guò)ssh配置文件(注意,不是sshd的配置文件)中的指令PreferredAuthentications改變。

如果使用公鑰認(rèn)證機(jī)制,客戶端A需要將自己生成的公鑰(~/.ssh/id_rsa.pub)發(fā)送到服務(wù)端B的~/.ssh/authorized_keys文件中。當(dāng)進(jìn)行公鑰認(rèn)證時(shí),客戶端將告訴服務(wù)端要使用哪個(gè)密鑰對(duì),并告訴服務(wù)端它已經(jīng)訪問(wèn)過(guò)密鑰對(duì)的私鑰部分~/.ssh/id_rsa(不能直接提供給服務(wù)端匹配檢測(cè),因?yàn)樗借€不能泄露),然后服務(wù)端將檢測(cè)密鑰對(duì)的公鑰部分,判斷該客戶端是否允許通過(guò)認(rèn)證。如果認(rèn)證不通過(guò),則進(jìn)入下一個(gè)認(rèn)證機(jī)制,以密碼認(rèn)證機(jī)制為例。

當(dāng)使用密碼認(rèn)證時(shí),將提示輸入要連接的遠(yuǎn)程用戶的密碼,輸入正確則驗(yàn)證通過(guò)。

1.3.3 驗(yàn)證通過(guò)

當(dāng)主機(jī)驗(yàn)證和身份驗(yàn)證都通過(guò)后,分兩種情況:直接登錄或執(zhí)行ssh命令行中給定某個(gè)命令。如:

[root@xuexi ~]# ssh 172.16.10.6 [root@xuexi ~]# ssh 172.16.10.6  'echo "haha"'

(1).前者ssh命令行不帶任何命令參數(shù),表示使用遠(yuǎn)程主機(jī)上的某個(gè)用戶(此處為root用戶)登錄到遠(yuǎn)程主機(jī)172.16.10.6上,所以遠(yuǎn)程主機(jī)會(huì)為ssh分配一個(gè)偽終端,并進(jìn)入bash環(huán)境。

(2).后者ssh命令行帶有命令參數(shù),表示在遠(yuǎn)程主機(jī)上執(zhí)行給定的命令【echo “haha”】。ssh命令行上的遠(yuǎn)程命令是通過(guò)fork ssh-agent得到的子進(jìn)程來(lái)執(zhí)行的,當(dāng)命令執(zhí)行完畢,子進(jìn)程消逝,ssh也將退出,建立的會(huì)話和連接也都將關(guān)閉。(之所以要在這里明確說(shuō)明遠(yuǎn)程命令的執(zhí)行過(guò)程,是為了說(shuō)明后文將介紹的ssh實(shí)現(xiàn)端口轉(zhuǎn)發(fā)時(shí)的注意事項(xiàng))

實(shí)際上,在ssh連接成功,登錄或執(zhí)行命令行中命令之前,可以指定要在遠(yuǎn)程執(zhí)行的命令,這些命令放在~/.ssh/rc或/etc/ssh/rc文件中,也就是說(shuō),ssh連接建立之后做的第一件事是在遠(yuǎn)程主機(jī)上執(zhí)行這兩個(gè)文件中的命令。

1.4 各種文件分布

以主機(jī)A連接主機(jī)B為例,主機(jī)A為SSH客戶端,主機(jī)B為SSH服務(wù)端。

在服務(wù)端即主機(jī)B上:

  • /etc/ssh/sshd_config? :ssh服務(wù)程序sshd的配置文件。

  • /etc/ssh/ssh_host_* ??:服務(wù)程序sshd啟動(dòng)時(shí)生成的服務(wù)端公鑰和私鑰文件。如ssh_host_rsa_key和ssh_host_rsa_key.pub。

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :其中.pub文件是主機(jī)驗(yàn)證時(shí)的host key,將寫(xiě)入到客戶端的~/.ssh/known_hosts文件中。

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :其中私鑰文件嚴(yán)格要求權(quán)限為600,若不是則sshd服務(wù)可能會(huì)拒絕啟動(dòng)。

  • ~/.ssh/authorized_keys:保存的是基于公鑰認(rèn)證機(jī)制時(shí)來(lái)自于客戶端的公鑰。在基于公鑰認(rèn)證機(jī)制認(rèn)證時(shí),服務(wù)端將讀取該文件。

在客戶端即主機(jī)A上:

  • /etc/ssh/ssh_config ? ?:客戶端的全局配置文件。

  • ~/.ssh/config ? ? ? ? ? ? ?:客戶端的用戶配置文件,生效優(yōu)先級(jí)高于全局配置文件。一般該文件默認(rèn)不存在。該文件對(duì)權(quán)限有嚴(yán)

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :格要求只對(duì)所有者有讀/寫(xiě)權(quán)限,對(duì)其他人完全拒絕寫(xiě)權(quán)限。

  • ~/.ssh/known_hosts ? :保存主機(jī)驗(yàn)證時(shí)服務(wù)端主機(jī)host key的文件。文件內(nèi)容來(lái)源于服務(wù)端的ssh_host_rsa_key.pub文件。

  • /etc/ssh/known_hosts:全局host key保存文件。作用等同于~/.ssh/known_hosts。

  • ~/.ssh/id_rsa ? ? ? ? ? ? ?:客戶端生成的私鑰。由ssh-keygen生成。該文件嚴(yán)格要求權(quán)限,當(dāng)其他用戶對(duì)此文件有可讀權(quán)限時(shí),

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :ssh將直接忽略該文件。

  • ~/.ssh/id_rsa.pub ? ? ? :私鑰id_rsa的配對(duì)公鑰。對(duì)權(quán)限不敏感。當(dāng)采用公鑰認(rèn)證機(jī)制時(shí),該文件內(nèi)容需要復(fù)制到服務(wù)端的

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :~/.ssh/authorized_keys文件中。

  • ~/.ssh/rc ? ? ? ? ? ? ? ? ? ? :保存的是命令列表,這些命令在ssh連接到遠(yuǎn)程主機(jī)成功時(shí)將第一時(shí)間執(zhí)行,執(zhí)行完這些命令之后才

  • ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :開(kāi)始登陸或執(zhí)行ssh命令行中的命令。

  • /etc/ssh/rc ? ? ? ? ? ? ? ? ?:作用等同于~/.ssh/rc。

1.5 配置文件簡(jiǎn)單介紹

分為服務(wù)端配置文件/etc/ssh/sshd_config和客戶端配置文件/etc/ssh/ssh_config(全局)或~/.ssh/config(用戶)。

雖然服務(wù)端和客戶端配置文件默認(rèn)已配置項(xiàng)雖然非常少非常簡(jiǎn)單,但它們可配置項(xiàng)非常多。sshd_config完整配置項(xiàng)參見(jiàn)金步國(guó)翻譯的sshd_config中文手冊(cè),ssh_config也可以參考sshd_config的配置,它們大部分配置項(xiàng)所描述的內(nèi)容是相同的。

1.5.1 sshd_config

簡(jiǎn)單介紹下該文件中比較常見(jiàn)的指令。

[root@xuexi ~]#  /etc//.  # 監(jiān)聽(tīng)的IP地址。. protocol version /etc//ssh_host_key      # SSH 1保存位置/etc// protocol version /etc//ssh_host_rsa_key  # SSH 2保存RSA位置/etc///etc//ssh_host_dsa_key  # SSH 2保存DSA位置/etc///var/run//var/log//

一般來(lái)說(shuō),如非有特殊需求,只需修改下監(jiān)聽(tīng)端口和UseDNS為no以加快主機(jī)驗(yàn)證階段的速度即可。

配置好后直接重啟啟動(dòng)sshd服務(wù)即可。

[root@xuexi ~]# service sshd restart

1.5.2 ssh_config

需要說(shuō)明的是,客戶端配置文件有很多配置項(xiàng)和服務(wù)端配置項(xiàng)名稱相同,但它們一個(gè)是在連接時(shí)采取的配置(客戶端配置文件),一個(gè)是sshd啟動(dòng)時(shí)開(kāi)關(guān)性的設(shè)置(服務(wù)端配置文件)。例如,兩配置文件都有GSSAPIAuthentication項(xiàng),在客戶端將其設(shè)置為no,表示連接時(shí)將直接跳過(guò)該身份驗(yàn)證機(jī)制,而在服務(wù)端設(shè)置為no則表示sshd啟動(dòng)時(shí)不開(kāi)啟GSSAPI身份驗(yàn)證的機(jī)制。即使客戶端使用了GSSAPI認(rèn)證機(jī)制,只要服務(wù)端沒(méi)有開(kāi)啟,就絕對(duì)不可能認(rèn)證通過(guò)。

下面也簡(jiǎn)單介紹該文件。

# Host *                              # Host指令是ssh_config中最重要的指令,只有ssh連接的目標(biāo)主機(jī)名能匹配此處給定模式時(shí),                                        # 下面一系列配置項(xiàng)直到出現(xiàn)下一個(gè)Host指令才對(duì)此次連接生效  #   ForwardAgent no  #   ForwardX11 no  #   RhostsRSAAuthentication no  #   RSAAuthentication yes  #   PasswordAuthentication yes     # 是否啟用基于密碼的身份認(rèn)證機(jī)制  #   HostbasedAuthentication no     # 是否啟用基于主機(jī)的身份認(rèn)證機(jī)制  #   GSSAPIAuthentication no        # 是否啟用基于GSSAPI的身份認(rèn)證機(jī)制  #   GSSAPIDelegateCredentials no  #   GSSAPIKeyExchange no  #   GSSAPITrustDNS no  #   BatchMode no                   # 如果設(shè)置為"yes",將禁止passphrase/password詢問(wèn)。比較適用于在那些不需要詢問(wèn)提供密                                     # 碼的腳本或批處理任務(wù)任務(wù)中。默認(rèn)為"no"。  #   CheckHostIP yes  #   AddressFamily any  #   ConnectTimeout 0#   StrictHostKeyChecking ask        # 設(shè)置為"yes",ssh將從不自動(dòng)添加host key到~/.ssh/known_hosts文件,                                       # 且拒絕連接那些未知的主機(jī)(即未保存host key的主機(jī)或host key已改變的主機(jī))。                                       # 它將強(qiáng)制用戶手動(dòng)添加host key到~/.ssh/known_hosts中。                                       # 設(shè)置為ask將詢問(wèn)是否保存到~/.ssh/known_hosts文件。                                       # 設(shè)置為no將自動(dòng)添加到~/.ssh/known_hosts文件。  #   IdentityFile ~/.ssh/identity     # ssh v1版使用的私鑰文件  #   IdentityFile ~/.ssh/id_rsa       # ssh v2使用的rsa算法的私鑰文件  #   IdentityFile ~/.ssh/id_dsa       # ssh v2使用的dsa算法的私鑰文件  #   Port 22                          # 當(dāng)命令行中不指定端口時(shí),默認(rèn)連接的遠(yuǎn)程主機(jī)上的端口  #   Protocol 2,1#   Cipher 3des                      # 指定ssh v1版本中加密會(huì)話時(shí)使用的加密協(xié)議  #   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc  # 指定ssh v1版本中加密會(huì)話時(shí)使用的加密協(xié)議  #   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160  #   EscapeChar ~#   Tunnel no  #   TunnelDevice any:any  #   PermitLocalCommand no    # 功能等價(jià)于~/.ssh/rc,表示是否允許ssh連接成功后在本地執(zhí)行LocalCommand指令指定的命令。  #   LocalCommand             # 指定連接成功后要在本地執(zhí)行的命令列表,當(dāng)PermitLocalCommand設(shè)置為no時(shí)將自動(dòng)忽略該配置                               # %d表本地用戶家目錄,%h表示遠(yuǎn)程主機(jī)名,%l表示本地主機(jī)名,%n表示命令行上提供的主機(jī)名,                               # p%表示遠(yuǎn)程ssh端口,r%表示遠(yuǎn)程用戶名,u%表示本地用戶名。  #   VisualHostKey no         # 是否開(kāi)啟主機(jī)驗(yàn)證階段時(shí)host key的圖形化指紋  Host *GSSAPIAuthentication yes

?

如非有特殊需求,ssh客戶端配置文件一般只需修改下GSSAPIAuthentication的值為no來(lái)改善下用戶驗(yàn)證的速度即可,另外在有非交互需求時(shí),將StrictHostKeyChecking設(shè)置為no以讓主機(jī)自動(dòng)添加host key。

1.6 ssh命令簡(jiǎn)單功能

此處先介紹ssh命令的部分功能,其他包括端口轉(zhuǎn)發(fā)的在后文相關(guān)內(nèi)容中解釋,關(guān)于連接復(fù)用的選項(xiàng)本文不做解釋。

語(yǔ)法:

ssh [options] [user@]hostname [command]     參數(shù)說(shuō)明:-b bind_address :在本地主機(jī)上綁定用于ssh連接的地址,當(dāng)系統(tǒng)有多個(gè)ip時(shí)才生效。-E log_file     :將debug日志寫(xiě)入到log_file中,而不是默認(rèn)的標(biāo)準(zhǔn)錯(cuò)誤輸出stderr。-F configfile   :指定用戶配置文件,默認(rèn)為~/.ssh/config。-f              :請(qǐng)求ssh在工作在后臺(tái)模式。該選項(xiàng)隱含了"-n"選項(xiàng),所以標(biāo)準(zhǔn)輸入將變?yōu)?dev/null。-i identity_file:指定公鑰認(rèn)證時(shí)要讀取的私鑰文件。默認(rèn)為~/.ssh/id_rsa。-l login_name   :指定登錄在遠(yuǎn)程機(jī)器上的用戶名。也可以在全局配置文件中設(shè)置。-N              :顯式指明ssh不執(zhí)行遠(yuǎn)程命令。一般用于端口轉(zhuǎn)發(fā),見(jiàn)后文端口轉(zhuǎn)發(fā)的示例分析。-n              :將/dev/null作為標(biāo)準(zhǔn)輸入stdin,可以防止從標(biāo)準(zhǔn)輸入中讀取內(nèi)容。ssh在后臺(tái)運(yùn)行時(shí)默認(rèn)該項(xiàng)。-p port         :指定要連接遠(yuǎn)程主機(jī)上哪個(gè)端口,也可在全局配置文件中指定默認(rèn)的連接端口。-q              :靜默模式。大多數(shù)警告信息將不輸出。-T              :禁止為ssh分配偽終端。-t              :強(qiáng)制分配偽終端,重復(fù)使用該選項(xiàng)"-tt"將進(jìn)一步強(qiáng)制。-v              :詳細(xì)模式,將輸出debug消息,可用于調(diào)試。"-vvv"可更詳細(xì)。-V              :顯示版本號(hào)并退出。-o              :指定額外選項(xiàng),選項(xiàng)非常多。  user@hostname   :指定ssh以遠(yuǎn)程主機(jī)hostname上的用戶user連接到的遠(yuǎn)程主機(jī)上,若省略u(píng)ser部分,則表示使用本地當(dāng)前用戶。                  :如果在hostname上不存在user用戶,則連接將失敗(將不斷進(jìn)行身份驗(yàn)證)。  command         :要在遠(yuǎn)程主機(jī)上執(zhí)行的命令。指定該參數(shù)時(shí),ssh的行為將不再是登錄,而是執(zhí)行命令,命令執(zhí)行完畢時(shí)ssh連接就關(guān)閉。

例如,以172.16.10.6主機(jī)上的longshuai用戶登錄172.16.10.6。

[root@xuexi ~]# ssh longshuai@172.16.10.6The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.ECDSA key fingerprint is 18:d1:28:1b:99:3b:db:20:c7:68:0a:f8:9e:43:e8:b4.Are you sure you want to continue connecting (yes/no)? yes       # 主機(jī)驗(yàn)證Warning: Permanently added '172.16.10.6' (ECDSA) to the list of known hosts.longshuai@172.16.10.6's password:                      # 用戶驗(yàn)證Last login: Wed Jul  5 12:27:29 2017 from 172.16.10.6

此時(shí)已經(jīng)登錄到了172.16.10.6主機(jī)上。

[longshuai@xuexi ~]$ hostname -I172.16.10.6

要退出ssh登錄,使用logout命令或exit命令即可返回到原主機(jī)環(huán)境。

使用ssh還可以實(shí)現(xiàn)主機(jī)跳轉(zhuǎn),即跳板功能。例如主機(jī)B能和A、C通信,但A、C之間不同通信,即ABCA的情形。如果要從A登陸到C,則可以借助B這個(gè)跳板登錄到C。此處一個(gè)簡(jiǎn)單示例為:從172.16.10.5登錄到172.16.10.6,再以此為基礎(chǔ)登錄到172.16.100.3上。

[root@xuexi ~]# ssh 172.16.10.6The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf.  Are you sure you want to continue connecting (yes/no)? yes  Warning: Permanently added '172.16.10.6' (RSA) to the list of known hosts.  Last login: Wed Jul  5 12:36:51 2017 from 172.16.10.6
[root@xuexi ~]# ssh 172.16.10.3The authenticity of host '172.16.10.3 (172.16.10.3)' can't be established.ECDSA key fingerprint is 18:d1:28:1b:99:3b:db:20:c7:68:0a:f8:9e:43:e8:b4.  Are you sure you want to continue connecting (yes/no)? yes  Warning: Permanently added '172.16.10.3' (ECDSA) to the list of known hosts.  root@172.16.10.3's password:Last login: Thu Jun 29 12:38:56 2017 from 172.16.10.6
[root@xuexi ~]# hostname -I172.16.10.3 172.16.10.4

同樣,在退出時(shí),也是一層一層退出的。

[root@xuexi ~]# exit  logout  Connection to 172.16.10.3 closed.    [root@xuexi ~]# hostname -I     172.16.10.6[root@xuexi ~]# exit  logout  Connection to 172.16.10.6 closed.

注意,由于在借助172.16.10.6當(dāng)跳板連接到172.16.10.3,所以172.16.10.3的host key是添加到172.16.10.3上而非172.16.10.5上的。

如果在命令行給出了要執(zhí)行的命令,默認(rèn)ssh將工作在前臺(tái),如果同時(shí)給定了”-f”選項(xiàng),則ssh工作在后臺(tái)。但盡管是工作在后臺(tái),當(dāng)遠(yuǎn)程執(zhí)行的命令如果有消息返回時(shí),將隨時(shí)可能顯示在本地。當(dāng)遠(yuǎn)程命令執(zhí)行完畢后,ssh連接也將立即關(guān)閉。

[root@xuexi ~]# ssh 172.16.10.6 'sleep 5'     # 在前臺(tái)睡眠5秒鐘    [root@xuexi ~]# ssh 172.16.10.6 -f 'sleep 5;echo over'   # 在后臺(tái)睡眠5秒,睡眠完成后echo一段信息

由于第二條命令是放在后臺(tái)執(zhí)行的,所以該ssh一建立完成ssh會(huì)話就立即返回本地bash環(huán)境,但當(dāng)5秒之后,將在本地突然顯示”over”。

ssh執(zhí)行遠(yuǎn)程命令默認(rèn)允許從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)然后傳輸?shù)竭h(yuǎn)程。可以使用”-n”選項(xiàng),使得標(biāo)準(zhǔn)輸入重定向?yàn)?dev/null。例如:

[root@xuexi ~]# echo haha | ssh 172.16.10.6 'cat'haha    [root@xuexi ~]# ssh 172.16.10.6 'cat' </etc/fstab

再看如下兩條命令:

[root@xuexi ~]# tar zc /tmp/* | ssh 172.16.10.6 'cd /tmp;tar xz'    [root@xuexi ~]# ssh 172.16.10.6 'tar cz /tmp' | tar xz

第一條命令將/tmp下文件歸檔壓縮,然后傳送到遠(yuǎn)程主機(jī)上并被解包;第二條命令將遠(yuǎn)程主機(jī)上的/tmp目錄歸檔壓縮,并傳輸?shù)奖镜亟獍K运鼈儗?shí)現(xiàn)了拷貝的功能。

不妨再分析下面的命令,該命令改編自ssh-copy-id腳本中的主要命令。如果不知道ssh-copy-id命令是干什么的,后文有介紹。

[root@xuexi ~]# cat ~/.ssh/id_rsa.pub | ssh 172.16.10.6 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys"

該命令首先建立ssh連接,并在遠(yuǎn)程執(zhí)行”umask 077″臨時(shí)修改遠(yuǎn)程的umask值,使得遠(yuǎn)程創(chuàng)建的目錄權(quán)限為700,然后判斷遠(yuǎn)程主機(jī)上是否有~/.ssh目錄,如果沒(méi)有則創(chuàng)建,最后從標(biāo)準(zhǔn)輸入中讀取本地公鑰文件~/.ssh/id_rsa.pub的內(nèi)容并將其追加到~/.ssh/authorized_keys文件中。

如果將此命令改為如下命令,使用ssh的”-n”選項(xiàng),并將追加重定向改為覆蓋重定向符號(hào)。

[root@xuexi ~]# cat ~/.ssh/id_rsa.pub | ssh -n 172.16.10.6 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat > ~/.ssh/authorized_keys"

該命令的結(jié)果是清空遠(yuǎn)程主機(jī)172.16.10.6上的~/.ssh/authorized_keys文件,因?yàn)閟sh的”-n”選項(xiàng)強(qiáng)行改變了ssh讀取的標(biāo)準(zhǔn)輸入為/dev/null。

1.7 scp命令及過(guò)程分析

scp是基于ssh的遠(yuǎn)程拷貝命令,也支持本地拷貝,甚至支持遠(yuǎn)程到遠(yuǎn)程的拷貝。

scp由于基于ssh,所以其端口也是使用ssh的端口。其實(shí),scp拷貝的實(shí)質(zhì)是使用ssh連接到遠(yuǎn)程,并使用該連接來(lái)傳輸數(shù)據(jù)。下文有scp執(zhí)行過(guò)程的分析。

另外,scp還非常不占資源,不會(huì)提高多少系統(tǒng)負(fù)荷,在這一點(diǎn)上,rsync遠(yuǎn)不及它。雖然 rsync比scp會(huì)快一點(diǎn),但rsync是增量拷貝,要判斷每個(gè)文件是否修改過(guò),在小文件眾多的情況下,判斷次數(shù)非常多,導(dǎo)致rsync效率較差,而scp基本不影響系統(tǒng)正常使用。

scp每次都是全量拷貝,在某些情況下,肯定是不及rsync的。

scp [-12BCpqrv] [-l limit] [-o ssh_option] [-P port] [[user@]host1:]src_file ... [[user@]host2:]dest_file    選項(xiàng)說(shuō)明:-1:使用ssh v1版本,這是默認(rèn)使用協(xié)議版本-2:使用ssh v2版本-C:拷貝時(shí)先壓縮,節(jié)省帶寬-l limit:限制拷貝速度,Kbit/s,1Byte=8bit,所以"-l 800"表示的速率是100K/S-o ssh_option:指定ssh連接時(shí)的特殊選項(xiàng),一般用不上。-P port:指定目標(biāo)主機(jī)上ssh端口,大寫(xiě)的字母P,默認(rèn)是22端口-p:拷貝時(shí)保持源文件的mtime,atime,owner,group,privileges-r:遞歸拷貝,用于拷貝目錄。注意,scp拷貝遇到鏈接文件時(shí),會(huì)拷貝鏈接的源文件內(nèi)容填充到目標(biāo)文件中(scp的本質(zhì)就是填充而非拷貝)-v:輸出詳細(xì)信息,可以用來(lái)調(diào)試或查看scp的詳細(xì)過(guò)程,分析scp的機(jī)制

src_file是源位置,dest_file是目標(biāo)位置,即將src_file復(fù)制到dest_file,其中src_file可以指定多個(gè)。由于源位置和目標(biāo)位置都可以使用本地路徑和遠(yuǎn)程路徑,所以scp能實(shí)現(xiàn)本地拷貝到遠(yuǎn)程、本地拷貝到本地、遠(yuǎn)程拷貝到本地、遠(yuǎn)程拷貝到另一個(gè)遠(yuǎn)程。其中遠(yuǎn)程路徑的指定格式為”user@hostname:/path”,可以省略u(píng)ser,也可以省略”:/path”,省略”:/path”時(shí)表示拷貝到目的用戶的家目錄下。

注意:scp拷貝是強(qiáng)制覆蓋型拷貝,當(dāng)有重名文件時(shí),不會(huì)進(jìn)行任何詢問(wèn)。

例如:

(1).本地拷貝到本地:/etc/fstab–>/tmp/a.txt。

[root@xuexi ~]# scp /etc/fstab /tmp/a.txt

(2).本地到遠(yuǎn)程:/etc/fstab–>172.16.10.6:/tmp/a.txt。

[root@xuexi ~]# scp /etc/fstab 172.16.10.6:/tmp  fstab                                          100%  805     0.8KB/s   00:00

(3).遠(yuǎn)程到本地:172.16.10.6:/etc/fstab–>/tmp/a.txt。

[root@xuexi ~]# scp 172.16.10.6:/etc/fstab /tmp/a.txt  fstab                                          100%  501     0.5KB/s   00:00

(4).遠(yuǎn)程路徑1到遠(yuǎn)程路徑2:172.16.10.6:/etc/fstab–>/172.16.10.3:/tmp/a.txt。

[root@xuexi ~]# scp 172.16.10.6:/etc/fstab 172.16.10.3:/tmp/a.txt  fstab                                          100%  501     0.5KB/s   00:00   Connection to 172.16.10.6 closed.

1.7.1 scp拷貝機(jī)制分析

scp的拷貝實(shí)質(zhì)是建立ssh連接,然后通過(guò)此連接來(lái)傳輸數(shù)據(jù)。如果是遠(yuǎn)程1拷貝到遠(yuǎn)程2,則是將scp命令轉(zhuǎn)換后發(fā)送到遠(yuǎn)程1上執(zhí)行,在遠(yuǎn)程1上建立和遠(yuǎn)程2的ssh連接,并通過(guò)此連接來(lái)傳輸數(shù)據(jù)。

在遠(yuǎn)程復(fù)制到遠(yuǎn)程的過(guò)程中,例如在本地(172.16.10.5)執(zhí)行scp命令將A主機(jī)(172.16.10.6)上的/tmp/copy.txt復(fù)制到B主機(jī)(172.16.10.3)上的/tmp目錄下,如果使用-v選項(xiàng)查看調(diào)試信息的話,會(huì)發(fā)現(xiàn)它的步驟類似是這樣的。

# 以下是從結(jié)果中提取的過(guò)程  # 首先輸出本地要執(zhí)行的命令  Executing: /usr/bin/ssh -v -x -oClearAllForwardings yes -t -l root 172.16.10.6 scp -v /tmp/copy.txt root@172.16.10.3:/tmp     # 從本地連接到A主機(jī)  debug1: Connecting to 172.16.10.6 [172.16.10.6] port 22.  debug1: Connection established.     # 要求驗(yàn)證本地和A主機(jī)之間的連接  debug1: Next authentication method: password  root@172.16.10.6's password: # 將scp命令行修改后發(fā)送到A主機(jī)上  debug1: Sending command: scp -v /tmp/copy.txt root@172.16.10.3:/tmp     # 在A主機(jī)上執(zhí)行scp命令  Executing: program /usr/bin/ssh host 172.16.10.3, user root, command scp -v -t /tmp     # 驗(yàn)證A主機(jī)和B主機(jī)之間的連接  debug1: Next authentication method: password  root@172.16.10.3's password: # 從A主機(jī)上拷貝源文件到最終的B主機(jī)上  debug1: Sending command: scp -v -t /tmp  Sending file modes: C0770 24 copy.txt  Sink: C0770 24 copy.txt  copy.txt                                                           100%   24     0.0KB/s       # 關(guān)閉本地主機(jī)和A主機(jī)的連接  Connection to 172.16.10.6 closed.

也就是說(shuō),遠(yuǎn)程主機(jī)A到遠(yuǎn)程主機(jī)B的復(fù)制,實(shí)際上是將scp命令行從本地傳輸?shù)街鳈C(jī)A上,由A自己去執(zhí)行scp命令。也就是說(shuō),本地主機(jī)不會(huì)和主機(jī)B有任何交互行為,本地主機(jī)就像是一個(gè)代理執(zhí)行者一樣,只是幫助傳送scp命令行以及幫助顯示信息。

其實(shí)從本地主機(jī)和主機(jī)A上的~/.ssh/know_hosts文件中可以看出,本地主機(jī)只是添加了主機(jī)A的host key,并沒(méi)有添加主機(jī)B的host key,而在主機(jī)A上則添加了主機(jī)B的host key。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

?

1.8 基于公鑰認(rèn)證機(jī)制實(shí)現(xiàn)雙機(jī)互信

在身份驗(yàn)證階段,由于默認(rèn)情況下基于公鑰認(rèn)證的機(jī)制順序優(yōu)先于基于密碼認(rèn)證的機(jī)制,所以基于公鑰認(rèn)證身份,就可以免輸入密碼,即實(shí)現(xiàn)雙機(jī)互信(實(shí)際上只是單方向的信任)。

基于公鑰認(rèn)證機(jī)制的認(rèn)證過(guò)程在前文已經(jīng)詳細(xì)說(shuō)明過(guò)了,如還不清楚,請(qǐng)?zhí)厣衔摹?/p>

1.8.1 實(shí)現(xiàn)步驟

以下是實(shí)現(xiàn)基于公鑰認(rèn)證的實(shí)現(xiàn)步驟:

(1).在客戶端使用ssh-keygen生成密鑰對(duì),存放路徑按照配置文件的指示,默認(rèn)是在~/.ssh/目錄下。

[root@xuexi ~]# ssh-keygen -t rsa    # -t參數(shù)指定算法,可以是rsa或dsa  Generating public/private rsa key pair.  Enter file in which to save the key (/root/.ssh/id_rsa):  # 詢問(wèn)私鑰保存路徑  Enter passphrase (empty for no passphrase):               # 詢問(wèn)是否加密私鑰文件  Enter same passphrase again:              Your identification has been saved in /root/.ssh/id_rsa.   Your public key has been saved in /root/.ssh/id_rsa.pub.

如果不想被詢問(wèn),則可以使用下面一條命令完成:”-f”指定私鑰文件,”-P”指定passphrase,或者”-N”也一樣。

[root@xuexi ~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''   # 指定加密私鑰文件的密碼為空密碼,即不加密    [root@xuexi ~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ''   # 同上

查看~/.ssh/目錄下私鑰的權(quán)限。私鑰文件有嚴(yán)格的權(quán)限要求,當(dāng)私鑰文件的非所有者有可讀權(quán)限時(shí),將直接忽略該私鑰文件導(dǎo)致公鑰認(rèn)證失敗。

[root@xuexi ~]# ls -l ~/.sshtotal 12-rw------- 1 root root 1671 Jun 29 00:18 id_rsa      # 私鑰權(quán)限必須600,屬主為自己-rw-r--r-- 1 root root  406 Jun 29 00:18 id_rsa.pub-rw-r--r-- 1 root root  393 Jun 29 05:56 known_hosts

(2).將上面生成的公鑰使用ssh-copy-id分發(fā)(即復(fù)制)到遠(yuǎn)程待信任主機(jī)上。

ssh-copy-id用法很簡(jiǎn)單,只需指定待信任主機(jī)及目標(biāo)用戶即可。如果生成的公鑰文件,路徑不是~/.ssh/id_rsa.pub,則使用”-i”選項(xiàng)指定要分發(fā)的公鑰。

ssh-copy-id [-i [identity_file]] [user@]machine

例如,將公鑰分發(fā)到172.16.10.6上的root用戶家目錄下:

[root@xuexi ~]# ssh-copy-id 172.16.10.6

ssh-copy-id唯一需要注意的是,如果ssh服務(wù)端的端口不是22,則需要給ssh-copy-id傳遞端口號(hào),傳遞方式為”-p port_num [user@]hostname”,例如”-p 22222 root@172.16.10.6″。之所以要如此傳遞,見(jiàn)下面摘自ssh-copy-id中公鑰分發(fā)的命令部分。

{ eval “$GET_ID” ; } | ssh $1 “umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)” || exit 1

其中”{ eval “$GET_ID” ; }”可理解為待分發(fā)的本地公鑰內(nèi)容,”(test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)”和selinux有關(guān),不用管,所以上述命令簡(jiǎn)化為:

cat ~/.ssh/id_rsa.pub | ssh $1 “umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys || exit 1

可見(jiàn),ssh-copy-id的所有參數(shù)都是存儲(chǔ)在位置變量$1中傳遞給ssh,所以應(yīng)該將ssh的端口選項(xiàng)”-p port_num”和user@hostname放在一起傳遞。

通過(guò)分析上面的命令,也即知道了ssh-copy-id的作用:在目標(biāo)主機(jī)的指定用戶的家目錄下,檢測(cè)是否有~/.ssh目錄,如果沒(méi)有,則以700權(quán)限創(chuàng)建該目錄,然后將本地的公鑰追加到目標(biāo)主機(jī)指定用戶家目錄下的~/.ssh/authorized_keys文件中。

1.8.2 一鍵shell腳本

就這樣簡(jiǎn)單的兩步就實(shí)現(xiàn)了基于公鑰的身份認(rèn)證。當(dāng)然,不使用ssh-copy-id,也一樣能實(shí)現(xiàn)上述過(guò)程。更便捷地,可以寫(xiě)一個(gè)簡(jiǎn)單的腳本,簡(jiǎn)化上述兩個(gè)步驟為1個(gè)步驟。

#!/bin/bash     ###########################################################  #  description: public key authentication in one step     #  #  author     : 駿馬金龍                                   #  #  blog       : http://www.cnblogs.com/f-ck-need-u/       ############################################################     privkey="$HOME/.ssh/id_rsa"publickey="$HOME/.ssh/id_rsa.pub"   # Usage helpif [ $# -ne 1 ];then     echo "Usage:$0 [user@]hostname"     exit 1fi   # test private/publick key exist or not, and the privilege 600 or notif [ -f "$privkey" -a -f "$publickey" ];then     privkey_priv=`stat -c %a $privkey`   if [ "$privkey_priv" -ne 600 ];then   echo "The privilege of private key ~/.ssh/id_rsa is not 600, exit now."   exit 1     fielse     echo "private/public key is not exist, it will create it"     ssh-keygen -t rsa -f $privkey -N ''     echo "keys created over, it located on $HOME/.ssh/"fi   ssh-copy-id "-o StrictHostKeyChecking=no $1"   if [ $? -eq 0 ];then     echo -e "e[31m publickey copy over e[0m"else     echo "ssh can't to the remote host"     exit 1fi

該腳本將檢查本地密鑰對(duì)~/.ssh/{id_rsa,id_rsa.pub}文件是否存在,還檢查私鑰文件的權(quán)限是否為600。如果缺少某個(gè)文件,將自動(dòng)新創(chuàng)建密鑰對(duì)文件,最后分發(fā)公鑰到目標(biāo)主機(jī)。

1.8.3 公鑰認(rèn)證之——服務(wù)端分發(fā)私鑰

對(duì)于基于公鑰認(rèn)證的身份驗(yàn)證機(jī)制,除了上面客戶端分發(fā)公鑰到服務(wù)端的方法,還可以通過(guò)分發(fā)服務(wù)端私鑰到客戶端來(lái)實(shí)現(xiàn)。

先理清下公鑰認(rèn)證的原理:客戶端要連接服務(wù)端,并告訴服務(wù)端要使用那對(duì)密鑰對(duì),然后客戶端訪問(wèn)自己的私鑰,服務(wù)端檢測(cè)對(duì)應(yīng)的公鑰來(lái)決定該公鑰所對(duì)應(yīng)的客戶端是否允許連接。所以對(duì)于基于公鑰認(rèn)證的身份驗(yàn)證,無(wú)論是客戶端分發(fā)公鑰,還是服務(wù)端分發(fā)私鑰,最終客戶端保存的一定是私鑰,服務(wù)端保存的一定是公鑰。

那么服務(wù)端分發(fā)私鑰實(shí)現(xiàn)公鑰認(rèn)證是如何實(shí)現(xiàn)的呢?步驟如下:假如客戶端為172.16.10.5,服務(wù)端為172.16.10.6。

(1).在服務(wù)端使用ssh-keygen生成密鑰對(duì)。

[root@xuexi ~]# ssh-keygen -f ~/.ssh/id_rsa -P ''

(2).將上面生成的公鑰追加到自己的authorized_keys文件中。

[root@xuexi ~]# ssh-copy-id 172.16.10.6

(3).將私鑰拷貝到客戶端,且路徑和文件名為~/.ssh/id_rsa。

[root@xuexi ~]# scp -p ~/.ssh/id_rsa* 172.16.10.5:/root/.ssh/

注意,第三步中也拷貝了公鑰,原因是客戶端連接服務(wù)端時(shí)會(huì)比較自己的公鑰和私鑰是否配對(duì),如果不配對(duì)將直接忽略公鑰認(rèn)證機(jī)制,所以會(huì)要求輸入密碼。可以將客戶端的公鑰刪除掉,或者將服務(wù)端生成的公鑰覆蓋到客戶端的公鑰上,都能完成公鑰認(rèn)證。

雖說(shuō),服務(wù)端分發(fā)私鑰的方式很少用,但通過(guò)上面的步驟,想必對(duì)ssh基于公鑰認(rèn)證的身份驗(yàn)證過(guò)程有了更深入的理解。

1.9 expect實(shí)現(xiàn)ssh/scp完全非交互(批量)

expect工具可以在程序發(fā)出交互式詢問(wèn)時(shí)按條件傳遞所需的字符串,例如詢問(wèn)yes/no自動(dòng)傳遞y或yes,詢問(wèn)密碼時(shí)自動(dòng)傳遞指定的密碼等,這樣就能讓腳本完全實(shí)現(xiàn)非交互。

顯然,ssh等客戶端命令基于密碼認(rèn)證時(shí)總是會(huì)詢問(wèn)密碼,即使是基于公鑰認(rèn)證,在建立公鑰認(rèn)證時(shí)也要詢問(wèn)一次密碼。另外,在ssh主機(jī)驗(yàn)證時(shí)還會(huì)詢問(wèn)是否保存host key。這一切都可以通過(guò)expect自動(dòng)回答。

關(guān)于expect工具,它使用的是tcl語(yǔ)言,雖說(shuō)應(yīng)用在expect上的tcl語(yǔ)言并非太復(fù)雜,但這并非本文內(nèi)容,如有興趣,可網(wǎng)上搜索或直接閱讀man文檔。

首先安裝expect工具。

[root@xuexi ~]# yum -y install expect

1.9.1 scp自動(dòng)應(yīng)答腳本

以下是scp自動(dòng)問(wèn)答的腳本。

[root@xuexi ~]# !/usr/bin/ { send

用法:autoscp.exp [user@]hostname src_file dest_file [password]

該自動(dòng)回答腳本可以自動(dòng)完成主機(jī)驗(yàn)證和密碼認(rèn)證,即使已經(jīng)是實(shí)現(xiàn)公鑰認(rèn)證的機(jī)器也沒(méi)問(wèn)題,因?yàn)楣€認(rèn)證機(jī)制默認(rèn)優(yōu)先于密碼認(rèn)證,且此腳本的password項(xiàng)是可選的,當(dāng)然,在沒(méi)有實(shí)現(xiàn)公鑰認(rèn)證的情況下,password是必須項(xiàng),否則expect實(shí)現(xiàn)非交互的目的就失去意義了。

以下是幾個(gè)示例:

[root@xuexi ~]# ./autoscp.exp 172.16.10.6 /etc/fstab /tmp 123456spawn scp /etc/fstab 172.16.10.6:/tmp  The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf.  Are you sure you want to continue connecting (yes/no)? yes          # 主機(jī)驗(yàn)證時(shí)詢問(wèn)是否保存host key,自動(dòng)回答yes  Warning: Permanently added '172.16.10.6' (RSA) to the list of known hosts.  root@172.16.10.6's password:                                        # 密碼認(rèn)證過(guò)程,自動(dòng)回答指定的密碼"123456"fstab                                                        100%  805     0.8KB/s   00:00

也可以指定完成的用戶名和主機(jī)名。

[root@xuexi ~]# ./autoscp.exp root@172.16.10.6 /etc/fstab /tmp 123456spawn scp /etc/fstab root@172.16.10.6:/tmp  root@172.16.10.6's password:         fstab                                 100%  805     0.8KB/s   00:00

1.9.2 ssh-copy-id自動(dòng)應(yīng)答腳本

以下是在建立公鑰認(rèn)證機(jī)制時(shí),ssh-copy-id拷貝公鑰到服務(wù)端的自動(dòng)應(yīng)答腳本。

[root@xuexi ~]# cat /tmp/autocopy.exp  #!/usr/bin/expect    ###########################################################  #  description: scp without interactive                   #  #  author     : 駿馬金龍                                   #  #  blog       : http://www.cnblogs.com/f-ck-need-u/       ############################################################    set timeout 10set user_hostname [lindex $argv 0]  set password [lindex $argv 1]  spawn ssh-copy-id $user_hostname      expect {"(yes/no)?"{              send "yesn"expect "*assword:" { send "$passwordn"}          }"*assword:"{              send "$passwordn"}      }  expect eof

用法:autocopy.exp [user@]hostname password

以下是一個(gè)示例,

[root@xuexi ~]# /tmp/autocopy.exp root@172.16.10.6 123456spawn ssh-copy-id root@172.16.10.6The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established.RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf.  Are you sure you want to continue connecting (yes/no)? yes      # 主機(jī)認(rèn)證時(shí),自動(dòng)應(yīng)答yes  Warning: Permanently added '172.16.10.6' (RSA) to the list of known hosts.  root@172.16.10.6's password:                                    # 密碼認(rèn)證時(shí)自動(dòng)輸入密碼"123456"Now try logging into the machine, with "ssh 'root@172.16.10.6'", and check in:       .ssh/authorized_keys     to make sure we haven't added extra keys that you weren't expecting.

如果要實(shí)現(xiàn)批量非交互,則可以寫(xiě)一個(gè)shell腳本調(diào)用該expect腳本。例如:

[root@xuexi ~]# cat /tmp/sci.sh#!/bin/bash    ###########################################################  #  description: scp without interactive                   #  #  author     : 駿馬金龍                                   #  #  blog       : http://www.cnblogs.com/f-ck-need-u/       ############################################################   passwd=123456               # 指定要傳遞的密碼為123456  user_host=`awk '{print $3}' ~/.ssh/id_rsa.pub`   # 此變量用于判斷遠(yuǎn)程主機(jī)中是否已添加本機(jī)信息成功   for i in $@    do/tmp/autocopy.exp $i $passwd >&/dev/nullssh $i "grep "$user_host" ~/.ssh/authorized_keys" >&/dev/null  # 判斷是否添加本機(jī)信息成功if [ $? -eq 0 ];thenecho "$i is ok"elseecho "$i is not ok"fidone

用法:/tmp/sci.sh [user@]hostname

其中hostname部分可以使用花括號(hào)展開(kāi)方式枚舉。但有個(gè)bug,最好ssh-copy-id的目標(biāo)不要是腳本所在的本機(jī),可能會(huì)強(qiáng)制輸入本機(jī)密碼,但批量腳本autocopy.exp則沒(méi)有此bug。

例如:

[root@xuexi tmp]# /tmp/sci.sh 172.16.10.3 172.16.10.6172.16.10.3 is ok172.16.10.6 is ok
[root@xuexi tmp]# /tmp/sci.sh 172.16.10.{3,6}172.16.10.3 is ok172.16.10.6 is ok
[root@xuexi tmp]# /tmp/sci.sh root@172.16.10.3 172.16.10.6root@172.16.10.3 is ok172.16.10.6 is ok

1.10 ssh連接速度慢的幾個(gè)原因和解決辦法

ssh連接包括兩個(gè)階段:主機(jī)驗(yàn)證階段和身份驗(yàn)證階段。這兩個(gè)階段都可能導(dǎo)致連接速度慢。

具體是哪個(gè)階段的速度慢,完全可以通過(guò)肉眼看出來(lái):

(1).卡著很久才提示保存host key肯定是主機(jī)驗(yàn)證過(guò)程慢。

(2).主機(jī)驗(yàn)證完成后卡著很久才提示輸入密碼,肯定是身份驗(yàn)證過(guò)程慢。

其中主機(jī)驗(yàn)證過(guò)程慢的原因,可能是網(wǎng)絡(luò)連接慢、DNS解析慢等原因。網(wǎng)絡(luò)連接慢,ssh對(duì)此毫無(wú)辦法,而DNS解析慢,ssh是可以解決的,解決方法是將ssh服務(wù)端的配置文件中UseDNS設(shè)置為no(默認(rèn)為yes)。

而身份驗(yàn)證慢的原因,則考慮ssh的身份驗(yàn)證順序:gssapi,host-based,publickey,keyboard-interactive,password。其中g(shù)ssapi認(rèn)證順序是比較慢的,所以解決方法一是在ssh客戶端配置文件中將GSSAPI認(rèn)證機(jī)制給關(guān)掉,解決方法二是在ssh客戶端配置文件中使用PreferredAuthentications指令修改身份驗(yàn)證順序。

方法一修改:GSSAPIAuthentication yes

方法二修改:PreferredAuthentications publickey,password,gssapi,host-based,keyboard-interactive

如果感受不到哪個(gè)階段導(dǎo)致速度變慢,可以使用ssh或scp等客戶端工具的”-vvv”選項(xiàng)進(jìn)行調(diào)試,看看是卡在哪個(gè)地方,不過(guò),想看懂”-vvv”的過(guò)程,還是比較考驗(yàn)?zāi)托牡摹?/p>

1.11 SSH安全隧道(ssh躍墻之術(shù))

1.11.1 ssh安全隧道(一):本地端口轉(zhuǎn)發(fā)

如下圖,假如host3和host1、host2都同互相通信,但是host1和host2之間不能通信,如何從host1連接上host2?

對(duì)于實(shí)現(xiàn)ssh連接來(lái)說(shuō),實(shí)現(xiàn)方式很簡(jiǎn)單,從host1 ssh到host3,再ssh到host2,也就是將host3作為跳板的方式。但是如果不是ssh,而是http的80端口呢?如何讓host1能訪問(wèn)host2的80端口?

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

ssh支持本地端口轉(zhuǎn)發(fā),語(yǔ)法格式為:

ssh -L [bind_addr:]local_port:remote:remote_port middle_host

以上圖為例,實(shí)現(xiàn)方式是在host1上執(zhí)行:

[root@xuexi ~]# ssh -g -L 2222:host2:80 host3

其中”-L”選項(xiàng)表示本地端口轉(zhuǎn)發(fā),其工作方式為:在本地指定一個(gè)由ssh監(jiān)聽(tīng)的轉(zhuǎn)發(fā)端口(2222),將遠(yuǎn)程主機(jī)的端口(host2:80)映射為本地端口(2222),當(dāng)有主機(jī)連接本地映射端口(2222)時(shí),本地ssh就將此端口的數(shù)據(jù)包轉(zhuǎn)發(fā)給中間主機(jī)(host3),然后host3再與遠(yuǎn)程主機(jī)的端口(host2:80)通信。

現(xiàn)在就可以通過(guò)訪問(wèn)host1的2222端口來(lái)達(dá)到訪問(wèn)host2:80的目的了。例如:

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

再來(lái)解釋下”-g”選項(xiàng),指定該選項(xiàng)表示允許外界主機(jī)連接本地轉(zhuǎn)發(fā)端口(2222),如果不指定”-g”,則host4將無(wú)法通過(guò)訪問(wèn)host1:2222達(dá)到訪問(wèn)host2:80的目的。甚至,host1自身也不能使用172.16.10.5:2222,而只能使用localhost:2222或127.0.0.1:2222這樣的方式達(dá)到訪問(wèn)host2:80的目的,之所以如此,是因?yàn)楸镜剞D(zhuǎn)發(fā)端口默認(rèn)綁定在回環(huán)地址上。可以使用bind_addr來(lái)改變轉(zhuǎn)發(fā)端口的綁定地址,例如:

[root@xuexi ~]# ssh -L 172.16.10.5:2222:host2:80 host3

這樣,host1自身就能通過(guò)訪問(wèn)172.16.10.5:2222的方式達(dá)到訪問(wèn)host2:80的目的。

一般來(lái)說(shuō),使用轉(zhuǎn)發(fā)端口,都建議同時(shí)使用”-g”選項(xiàng),否則將只有自身能訪問(wèn)轉(zhuǎn)發(fā)端口。

再來(lái)分析下轉(zhuǎn)發(fā)端口通信的過(guò)程。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

當(dāng)host4發(fā)起172.16.10.5:2222的連接時(shí)(即步驟①),數(shù)據(jù)包的目標(biāo)地址和端口為”172.16.10.5:2222″。由于host1上ssh已經(jīng)監(jiān)聽(tīng)了2222端口,并且知道該端口映射自哪臺(tái)主機(jī)哪個(gè)端口,所以將會(huì)把該數(shù)據(jù)包目標(biāo)地址和端口替換為”172.16.10.3:80″,并將此數(shù)據(jù)包通過(guò)轉(zhuǎn)發(fā)給host3。當(dāng)host3收到該數(shù)據(jù)包時(shí),發(fā)現(xiàn)是host1轉(zhuǎn)發(fā)過(guò)來(lái)請(qǐng)求訪問(wèn)host2:80的數(shù)據(jù)包,所以host3將代為訪問(wèn)host2的80端口。

所以,host1和host3之間的通信方式是SSH協(xié)議,這段連接是安全加密的,因此稱為”安全隧道”,而host3和host2之間通信協(xié)議則是HTTP而不是ssh。

現(xiàn)在再來(lái)考慮下,通過(guò)本地端口轉(zhuǎn)發(fā)的方式如何實(shí)現(xiàn)ssh跳板的功能呢?仍以上圖為例:

[root@xuexi ~]# ssh -g -L 22333:host2:22 host3

這樣只需使用ssh連上host1的22333端口就等于連接了host2的22端口。

甚至還可以在host3上執(zhí)行:

[root@xuexi?~]#?ssh?-L?172.16.10.5:22333:host2:80?host2    或:    [root@xuexi?~]#?ssh?-L?172.16.10.5:22333:host2:80?host3

這樣在host3就開(kāi)啟了一個(gè)轉(zhuǎn)發(fā)端口22333供host1連接。當(dāng)host1連接到host3:22333時(shí),host3將轉(zhuǎn)發(fā)給host2或host3自身,再由host2或host3自身與host2通信。

最后,關(guān)于端口轉(zhuǎn)發(fā)有一個(gè)需要注意的問(wèn)題:ssh命令中帶有要執(zhí)行的命令。考慮了下面的三條在host1上執(zhí)行的命令的區(qū)別。

[root@xuexi ~]# ssh -g -L 22333:host2:22 host3    [root@xuexi ~]# ssh -g -L 22333:host2:22 host3 "ifconfig"[root@xuexi ~]# ssh -g -L 22333:host2:22 host3 "sleep 10"

第一條命令開(kāi)啟了本地端口轉(zhuǎn)發(fā),且是以登錄到host3的方式開(kāi)啟的,所以執(zhí)行完該命令后,將跳到host3主機(jī)上,當(dāng)退出host3時(shí),端口轉(zhuǎn)發(fā)功能將被關(guān)閉。另外,host1上之所以要開(kāi)啟端口轉(zhuǎn)發(fā),目的是為了與host2進(jìn)行通信,而不是跳到host3上,所以應(yīng)該在ssh命令行上加上”-f”選項(xiàng)讓ssh在本機(jī)host1上以后臺(tái)方式提供端口轉(zhuǎn)發(fā)功能,而不是跳到host3上來(lái)提供端口轉(zhuǎn)發(fā)功能。

第二條命令在開(kāi)啟本地轉(zhuǎn)發(fā)的時(shí)候還指定了要在host3上執(zhí)行”ifconfig”命令,但是ssh的工作機(jī)制是遠(yuǎn)程命令執(zhí)行完畢的那一刻,ssh關(guān)閉連接,所以此命令開(kāi)啟的本地端口轉(zhuǎn)發(fā)功能有效期只有執(zhí)行ifconfig命令的一瞬間。

第三條命令和第二條命令類似,只不過(guò)指定的是睡眠10秒命令,所以此命令開(kāi)啟的本地轉(zhuǎn)發(fā)功能有效期只有10秒。

結(jié)合上面的分析,開(kāi)啟端口轉(zhuǎn)發(fā)功能時(shí),建議讓ssh以后臺(tái)方式提供端口轉(zhuǎn)發(fā)功能,且明確指示不要執(zhí)行任何ssh命令行上的遠(yuǎn)程命令。即最佳開(kāi)啟方式為:

[root@xuexi ~]# ssh -f -N -g -L 22333:host2:22 host3

1.11.2 ssh安全隧道(二):遠(yuǎn)程端口轉(zhuǎn)發(fā)

ssh除了支持本地端口轉(zhuǎn)發(fā),還支持遠(yuǎn)程端口轉(zhuǎn)發(fā)。顧名思義,遠(yuǎn)程端口轉(zhuǎn)發(fā)表示的是將遠(yuǎn)程端口的數(shù)據(jù)轉(zhuǎn)發(fā)到本地。

如下圖:假如host3是內(nèi)網(wǎng)主機(jī),它能和host2互相通信,也能和host1通信,但反過(guò)來(lái),host1不能和host3通信。這時(shí)要讓host1訪問(wèn)host3或host2就沒(méi)辦法通過(guò)本地端口轉(zhuǎn)發(fā)了,因?yàn)橐趆ost1上開(kāi)啟本地端口轉(zhuǎn)發(fā),必須要和host3通信請(qǐng)求建立隧道。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

可以通過(guò)在host3上發(fā)起遠(yuǎn)程端口轉(zhuǎn)發(fā)來(lái)實(shí)現(xiàn),因?yàn)閔ost3能和host1通信,host3可以請(qǐng)求在host1和host3之間建立隧道。

語(yǔ)法如下:

ssh -R [bind_addr:]remote1_port:host:port remote1

以上圖為例,實(shí)現(xiàn)方式是在host3上執(zhí)行:

[root@xuexi ~]# ssh -R 22333:host2:80 host1

這表示host3請(qǐng)求host1上的sshd服務(wù),在host1上建立一個(gè)套接字監(jiān)聽(tīng)22333端口,它是host2端口的映射,當(dāng)有主機(jī)連接host1:22333時(shí),此連接中的數(shù)據(jù)全部都通過(guò)host1和host3之間的安全隧道轉(zhuǎn)發(fā)給host3,再由host3向host2的80端口發(fā)起訪問(wèn)。由于host3請(qǐng)求開(kāi)啟的轉(zhuǎn)發(fā)端口是在遠(yuǎn)程主機(jī)host1上的,所以稱為”遠(yuǎn)程端口轉(zhuǎn)發(fā)”。

再考慮下面這條命令所開(kāi)啟的遠(yuǎn)程轉(zhuǎn)發(fā)端口,它是在host3上執(zhí)行的。

[root@xuexi ~]# ssh -R 22333:host3:80 host1

該命令將自身的host3:80映射到host1:22333上,這也能讓host1和host2、host3通信,因?yàn)樗淼朗墙⒃趆ost1:22333host3:80上的。

但是,遠(yuǎn)程端口轉(zhuǎn)發(fā)和本地端口轉(zhuǎn)發(fā)最大的一個(gè)區(qū)別是,遠(yuǎn)程轉(zhuǎn)發(fā)端口是由host1上的sshd服務(wù)控制的,默認(rèn)配置情況下,sshd服務(wù)只允許本地開(kāi)啟的遠(yuǎn)程轉(zhuǎn)發(fā)端口(22333)綁定在環(huán)回地址(127.0.0.1),即使顯式指定了bind_addr也無(wú)法覆蓋。例如:

[root@xuexi ~]# ssh -R *:22333:host2:80 host1    [root@xuexi ~]# netstat -tnlp  Active Internet connections (only servers)  Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name    tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      8405/sshd            tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      1422/master          tcp        0      0 127.0.0.1:22333             0.0.0.0:*                   LISTEN      8407/sshd            tcp        0      0 :::22                       :::*                        LISTEN      8405/sshd            tcp        0      0 ::1:25                      :::*                        LISTEN      1422/master           tcp        0      0 ::1:22333                   :::*                        LISTEN      8407/sshd

要允許本地的遠(yuǎn)程轉(zhuǎn)發(fā)端口綁定在非環(huán)回地址上,需要在host1的sshd配置文件中啟用”GatewayPorts”項(xiàng)它的默認(rèn)值為no。啟動(dòng)該選項(xiàng)后,不給定bind_addr或bind_addr設(shè)置為”*”都表示綁定在所有地址上。如下:

[root@xuexi ~]# ssh -g -R *:22333:host2:80 host1    [root@xuexi ~]# netstat -tnlp  Active Internet connections (only servers)  Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name    tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      8466/sshd            tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      1422/master          tcp        0      0 0.0.0.0:22333               0.0.0.0:*                   LISTEN      8468/sshd             tcp        0      0 :::22                       :::*                        LISTEN      8466/sshd            tcp        0      0 ::1:25                      :::*                        LISTEN      1422/master          tcp        0      0 :::22333                    :::*                        LISTEN      8468/sshd

和前面的本地轉(zhuǎn)發(fā)端口一樣,建議的幾個(gè)選項(xiàng)是:”-g”、”-f”、”-N”。即推薦的命令寫(xiě)法是:

[root@xuexi ~]# ssh -fgN -R 22333:host2:80 host1

現(xiàn)在,就可以通過(guò)訪問(wèn)host1:22333達(dá)到訪問(wèn)host2:80的目的了。如下圖所示。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

?

1.11.3 ssh安全隧道(三):動(dòng)態(tài)端口轉(zhuǎn)發(fā)(SOCKS代理)

無(wú)論是本地端口轉(zhuǎn)發(fā)還是遠(yuǎn)程端口轉(zhuǎn)發(fā),都是將某固定主機(jī)及其端口映射到本地或遠(yuǎn)程轉(zhuǎn)發(fā)端口上,例如將host2:80映射到host1:2222。也就是說(shuō),本地或遠(yuǎn)程轉(zhuǎn)發(fā)端口和目標(biāo)端口所代表的應(yīng)用層協(xié)議是一對(duì)一的關(guān)系,2222端口必須對(duì)應(yīng)的是http的80端口,使用瀏覽器向host1:2222端口發(fā)起http請(qǐng)求當(dāng)然沒(méi)問(wèn)題,但是使用ssh工具向host1:2222發(fā)起連接將會(huì)被拒絕,因?yàn)閔ost2上http服務(wù)只能解析http請(qǐng)求,不能解析ssh連接請(qǐng)求。

ssh支持動(dòng)態(tài)端口轉(zhuǎn)發(fā),由ssh來(lái)判斷發(fā)起請(qǐng)求的工具使用的是什么應(yīng)用層協(xié)議,然后根據(jù)判斷出的協(xié)議結(jié)果決定目標(biāo)端口。

以下圖為例進(jìn)行說(shuō)明,host1處在辦公內(nèi)網(wǎng),能和host3互相通信,但它無(wú)法直接和互聯(lián)網(wǎng)和host2通信,而host3則可以和host2以及互聯(lián)網(wǎng)通信。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

要讓host1訪問(wèn)互聯(lián)網(wǎng),又能和host2的22端口即ssh服務(wù)通信,顯然在host1上僅設(shè)置一個(gè)本地端口轉(zhuǎn)發(fā)是不夠的,雖然可以設(shè)置多個(gè)本地轉(zhuǎn)發(fā)端口分別映射不同的端口,但這顯然比較笨重和麻煩。使用動(dòng)態(tài)端口轉(zhuǎn)發(fā)即可。

語(yǔ)法格式為:

ssh -D [bind_addr:]port remote

以上圖為例,在host1上執(zhí)行:

[root@xuexi ~]# ssh -Nfg -D 2222 host3

執(zhí)行完上面的命令,host1將在本地開(kāi)啟SOCKS4或SOCKS5服務(wù)來(lái)監(jiān)聽(tīng)2222端口。只要客戶端程序工具(隱含了使用的應(yīng)用層協(xié)議類型)將其自身的代理設(shè)置為host1:2222,則該程序所有產(chǎn)生的數(shù)據(jù)都將轉(zhuǎn)發(fā)到host1:2222,再由host1:2222將數(shù)據(jù)通過(guò)隧道轉(zhuǎn)發(fā)給host3,最后由host3和互聯(lián)網(wǎng)或host2上對(duì)應(yīng)客戶端工具的應(yīng)用層協(xié)議的端口進(jìn)行通信。

其實(shí)很簡(jiǎn)單,假如host4使用IE瀏覽器作為客戶端工具,并將IE瀏覽器的代理設(shè)置為host1:2222,由于IE瀏覽器發(fā)起的請(qǐng)求使用的是http協(xié)議(此處不考慮其他可能的協(xié)議),那么IE瀏覽器產(chǎn)生的數(shù)據(jù)都轉(zhuǎn)發(fā)到host1:2222,再由host1:2222通過(guò)隧道轉(zhuǎn)發(fā)給host3,host3能聯(lián)網(wǎng),所以host4就實(shí)現(xiàn)了聯(lián)網(wǎng)功能。如下圖設(shè)置:

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

再比如host4上的QQ客戶端也可以設(shè)置代理。這樣QQ產(chǎn)生的數(shù)據(jù)都將通過(guò)host1:2222轉(zhuǎn)發(fā)出去,host1:2222再將QQ的數(shù)據(jù)轉(zhuǎn)發(fā)到host3上,host3知道這些數(shù)據(jù)使用的協(xié)議是oicq,所以host3會(huì)去連接騰訊的QQ服務(wù)器(oicq服務(wù)對(duì)應(yīng)的端口)。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

ssh只支持socks4和socks5兩種代理,有些客戶端工具中需要明確指明代理類型。

和本地、遠(yuǎn)程端口轉(zhuǎn)發(fā)一樣,建議的選項(xiàng)是:”-f”、”-N”和”-g”。

由于ssh動(dòng)態(tài)端口轉(zhuǎn)發(fā)是ssh客戶端的功能,所以不使用ssh命令,使用SecurtCRT、putty等ssh客戶端工具都可以實(shí)現(xiàn)代理上網(wǎng)。例如,本地主機(jī)不能上網(wǎng),但能和172.16.10.6的SSH服務(wù)通信,而172.16.10.6能上網(wǎng),則可以在本地主機(jī)先使用SecurtCRT連接172.16.10.6,再在對(duì)應(yīng)的會(huì)話選項(xiàng)上做如下設(shè)置,使得本地主機(jī)也能上網(wǎng)。(注意:我沒(méi)說(shuō)可以FQ啊,好公民不FQ!!!)

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

然后,在本地主機(jī)查看下是否監(jiān)聽(tīng)了SecurtCRT中指定的8888動(dòng)態(tài)轉(zhuǎn)發(fā)端口。

ssh的基本介紹和SSH服務(wù)(包含隧道內(nèi)容)

現(xiàn)在,本機(jī)所有數(shù)據(jù)包都通過(guò)SecurtCRT所連接的172.16.10.6流向外界。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊9 分享