第1章 ssh和SSH服務(包含隧道內容)

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/07/06/7129122.html
-Advertisement-
Play Games

本文對SSH連接驗證機制進行了非常詳細的分析,還詳細介紹了ssh客戶端工具的各種功能,相信能讓各位對ssh有個全方位較透徹的瞭解,而不是僅僅只會用它來連接遠程主機。 另外,本人翻譯了ssh客戶端命令的man文檔,如本文有不理解的地方,可以參考man文檔手冊:ssh中文手冊。 本文目錄: 1.1 非對 ...


本文對SSH連接驗證機制進行了非常詳細的分析,還詳細介紹了ssh客戶端工具的各種功能,相信能讓各位對ssh有個全方位較透徹的瞭解,而不是僅僅只會用它來連接遠程主機。

另外,本人翻譯了ssh客戶端命令的man文檔,如本文有不理解的地方,可以參考man文檔手冊:ssh中文手冊


本文目錄:

1.1 非對稱加密基礎知識

1.2 SSH概要

1.3 SSH認證過程分析

1.3.1 主機驗證過程

1.3.2 身份驗證過程

1.3.3 驗證通過

1.4 各種文件分佈

1.5 配置文件簡單介紹

1.5.1 sshd_config

1.5.2 ssh_config

1.6 ssh命令簡單功能

1.7 scp命令及過程分析

1.7.1 scp拷貝機制分析

1.8 基於公鑰認證實現雙機互信

1.8.1 實現步驟

1.8.2 一鍵shell腳本

1.8.3 公鑰認證之——服務端分發私鑰

1.9 expect實現ssh/scp完全非交互(批量)

1.9.1 scp自動應答腳本

1.9.2 ssh-copy-id自動應答腳本

1.10 ssh連接速度慢的幾個原因和解決方法

1.11 ssh安全隧道(ssh躍牆之術)

1.11.1 ssh安全隧道(一):本地埠轉發

1.11.2 ssh安全隧道(二):遠程埠轉發

1.11.3 ssh安全隧道(三):動態埠轉發(SOCKS代理)


1.1 非對稱加密基礎知識

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

非對稱加密:通過公鑰(public key)和私鑰(private key)來加密、解密。公鑰加密的內容可以使用私鑰解密,私鑰加密的內容可以使用公鑰解密。一般使用公鑰加密,私鑰解密,但並非絕對如此,例如CA簽署證書時就是使用自己的私鑰加密。在接下來介紹的SSH服務中,雖然一直建議分發公鑰,但也可以分發私鑰。

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

(1).A將自己的公鑰A分發給B,B拿著公鑰A將數據進行加密,並將加密的數據發送給A,A將使用自己的私鑰A解密數據。

(2).A將自己的公鑰A分發給B,並使用自己的私鑰A加密數據,然後B使用公鑰A解密數據。

(3).B將自己的公鑰B分發給A,A拿著公鑰B將數據進行加密,並將加密的數據發送給B,B將使用自己的私鑰B解密數據。

(4).B將自己的公鑰B分發給A,並使用自己的私鑰B加密數據,然後A使用公鑰B解密數據。

雖然理論上支持4種情形,但在SSH的身份驗證階段,SSH只支持服務端保留公鑰,客戶端保留私鑰的方式所以方式只有兩種:客戶端生成密鑰對,將公鑰分發給服務端;服務端生成密鑰對,將私鑰分發給客戶端。只不過出於安全性和便利性,一般都是客戶端生成密鑰對並分發公鑰。後文將給出這兩種分發方式的示例。

1.2 SSH概要

(1).SSH是傳輸層和應用層上的安全協議,它只能通過加密連接雙方會話的方式來保證連接的安全性。當使用ssh連接成功後,將建立客戶端和服務端之間的會話,該會話是被加密的,之後客戶端和服務端的通信都將通過會話傳輸。

(2).SSH服務的守護進程為sshd,預設監聽在22埠上。

(3).所有ssh客戶端工具,包括ssh命令,scp,sftp,ssh-copy-id等命令都是藉助於ssh連接來完成任務的。也就是說它們都連接服務端的22埠,只不過連接上之後將待執行的相關命令轉換傳送到遠程主機上,由遠程主機執行。

(4).ssh客戶端命令(ssh、scp、sftp等)讀取兩個配置文件:全局配置文件/etc/ssh/ssh_config和用戶配置文件~/.ssh/config。實際上命令行上也可以傳遞配置選項。它們生效的優先順序是:命令行配置選項 > ~/.ssh/config > /etc/ssh/ssh_config。

(5).ssh涉及到兩個驗證:主機驗證和用戶身份驗證。通過主機驗證,再通過該主機上的用戶驗證,就能唯一確定該用戶的身份。一個主機上可以有很多用戶,所以每台主機的驗證只需一次,但主機上每個用戶都需要單獨進行用戶驗證。

(6).ssh支持多種身份驗證,最常用的是密碼驗證機制和公鑰認證機制,其中公鑰認證機制在某些場景實現雙機互信時幾乎是必須的。雖然常用上述兩種認證機制,但認證時的順序預設是gssapi-with-mic,hostbased,publickey,keyboard-interactive,password。註意其中的主機認證機制hostbased不是主機驗證,由於主機認證用的非常少(它所讀取的認證文件為/etc/hosts.equiv或/etc/shosts.equiv),所以網路上比較少見到它的相關介紹。總的來說,通過在ssh配置文件(註意不是sshd配置文件)中使用指令PreferredAuthentications改變認證順序不失為一種驗證的效率提升方式。

(7).ssh客戶端其實有不少很強大的功能,如埠轉發(隧道模式)、代理認證、連接共用(連接復用)等。

(8).ssh服務端配置文件為/etc/ssh/sshd_config,註意和客戶端的全局配置文件/etc/ssh/ssh_config區分開來。

(9).最重要的一點,ssh登錄時會請求分配一個偽終端。但有些身份認證程式如sudo可以禁止這種類型的終端分配,導致ssh連接失敗。例如使用ssh執行sudo命令時sudo就會驗證是否要分配終端給ssh。

1.3 SSH認證過程分析

假如從客戶端A(172.16.10.5)連接到服務端B(172.16.10.6)上,將包括主機驗證和用戶身份驗證兩個過程,以RSA非對稱加密演算法為例。

[root@xuexi ~]# ssh 172.16.10.6

服務端B上首先啟動了sshd服務程式,即開啟了ssh服務,打開了22埠(預設)。

1.3.1 主機驗證過程

當客戶端A要連接B時,首先將進行主機驗證過程,即判斷主機B是否是否曾經連接過。

判斷的方法是讀取~/.ssh/known_hosts文件和/etc/ssh/known_hosts文件,搜索是否有172.16.10.6的主機信息(主機信息稱為host key,表示主機身份標識)。如果沒有搜索到對應該地址的host key,則詢問是否保存主機B發送過來的host key,如果搜索到了該地址的host key,則將此host key和主機B發送過來的host key做比對,如果完全相同,則表示主機A曾經保存過主機B的host key,無需再保存,直接進入下一個過程——身份驗證,如果不完全相同,則提示是否保存主機B當前使用的host key。

詢問是否保存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

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

在說明身份驗證過程前,先看下known_hosts文件的格式。以~/.ssh/known_hosts為例。

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

該文件中,每行一個host key,行首是主機名,它是搜索host key時的索引,主機名後的內容即是host key部分。以此文件為例,它表示客戶端A曾經試圖連接過172.16.10.6這個主機B,並保存了主機B的host key,下次連接主機B時,將搜索主機B的host key,並與172.16.10.6傳送過來的host key做比較,如果能匹配上,則表示該host key確實是172.16.10.6當前使用的host key,如果不能匹配上,則表示172.16.10.6修改過host key,或者此文件中的host key被修改過。

那麼主機B當前使用的host key保存在哪呢?在/etc/ssh/ssh_host*文件中,這些文件是服務端(此處即主機B)的sshd服務程式啟動時重建的。以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   # 在主機B上查看
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC675dv1w+GDYViXxqlTspUHsQjargFPSnR9nEqCyUgm5/32jXAA3XTJ4LUGcDHBuQ3p3spW/eO5hAP9eeTv5HQzTSlykwsu9He9w3ee+TV0JjBFulfBR0weLE4ut0PurPMbthE7jIn7FVDoLqc6o64WvN8LXssPDr8WcwvARmwE7pYudmhnBIMPV/q8iLMKfquREbhdtGLzJRL9DrnO9NNKB/EeEC56GY2t76p9ThOB6ES6e/87co2HjswLGTWmPpiqY8K/LA0LbVvqRrQ05+vNoNIdEfk4MXRn/IhwAh6j46oGelMxeTaXYC+r2kVELV0EvYV/wMa8QHbFPSM6nLz

發現/etc/ssh/ssh_host_rsa_key.pub文件內容和~/.ssh/known_hosts中該主機的host key部分完全一致,只不過~/.ssh/known_hosts中除了host key部分還多了一個主機名,這正是搜索主機時的索引。

綜上所述,在主機驗證階段,服務端持有的是私鑰,客戶端保存的是來自於服務端的公鑰。註意,這和身份驗證階段密鑰的持有方是相反的。

實際上,ssh並非直接比對host key,因為host key太長了,比對效率較低。所以ssh將host key轉換成host key指紋,然後比對兩邊的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計算得出。例如,下麵分別是主機A(172.16.10.5)保存的host key指紋,和主機B(172.16.10.6)當前使用的host key的指紋。可見它們是完全一樣的。

[root@xuexi ~]# ssh-keygen -l -f ~/.ssh/known_hosts
2048 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_key
2048 f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf   (RSA)

其實ssh還支持host key模糊比較,即將host key轉換為圖形化的指紋。這樣,圖形結果相差大的很容易就比較出來。之所以說是模糊比較,是因為對於非常近似的圖形化指紋,ssh可能會誤判。圖形化指紋的生成方式如下:只需在上述命令上加一個"-v"選項進入詳細模式即可。

[root@xuexi ~]# ssh-keygen -lv -f ~/.ssh/known_hosts
2048 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 身份驗證過程

主機驗證通過後,將進入身份驗證階段。SSH支持多種身份驗證機制,它們的驗證順序如下:gssapi-with-mic,hostbased,publickey,keyboard-interactive,password,但常見的是密碼認證機制(password)和公鑰認證機制(public key)。當公鑰認證機制未通過時,再進行密碼認證機制的驗證。這些認證順序可以通過ssh配置文件(註意,不是sshd的配置文件)中的指令PreferredAuthentications改變。

如果使用公鑰認證機制,客戶端A需要將自己生成的公鑰(~/.ssh/id_rsa.pub)發送到服務端B的~/.ssh/authorized_keys文件中。當進行公鑰認證時,客戶端將告訴服務端要使用哪個密鑰對,並告訴服務端它已經訪問過密鑰對的私鑰部分~/.ssh/id_rsa(不能直接提供給服務端匹配檢測,因為私鑰不能泄露),然後服務端將檢測密鑰對的公鑰部分,判斷該客戶端是否允許通過認證。如果認證不通過,則進入下一個認證機制,以密碼認證機製為例。

當使用密碼認證時,將提示輸入要連接的遠程用戶的密碼,輸入正確則驗證通過。

1.3.3 驗證通過

當主機驗證和身份驗證都通過後,分兩種情況:直接登錄或執行ssh命令行中給定某個命令。如:

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

(1).前者ssh命令行不帶任何命令參數,表示使用遠程主機上的某個用戶(此處為root用戶)登錄到遠程主機172.16.10.6上,所以遠程主機會為ssh分配一個偽終端,併進入bash環境。

(2).後者ssh命令行帶有命令參數,表示在遠程主機上執行給定的命令【echo "haha"】。ssh命令行上的遠程命令是通過fork ssh-agent得到的子進程來執行的,當命令執行完畢,子進程消逝,ssh也將退出,建立的會話和連接也都將關閉。(之所以要在這裡明確說明遠程命令的執行過程,是為了說明後文將介紹的ssh實現埠轉發時的註意事項)

實際上,在ssh連接成功,登錄或執行命令行中命令之前,可以指定要在遠程執行的命令,這些命令放在~/.ssh/rc或/etc/ssh/rc文件中,也就是說,ssh連接建立之後做的第一件事是在遠程主機上執行這兩個文件中的命令。

1.4 各種文件分佈

以主機A連接主機B為例,主機A為SSH客戶端,主機B為SSH服務端。

在服務端即主機B上:

  • /etc/ssh/sshd_config  :ssh服務程式sshd的配置文件。
  • /etc/ssh/ssh_host_*   :服務程式sshd啟動時生成的服務端公鑰和私鑰文件。如ssh_host_rsa_key和ssh_host_rsa_key.pub。
  •                                   :其中.pub文件是主機驗證時的host key,將寫入到客戶端的~/.ssh/known_hosts文件中。
  •                                   :其中私鑰文件嚴格要求許可權為600,若不是則sshd服務可能會拒絕啟動。
  • ~/.ssh/authorized_keys:保存的是基於公鑰認證機制時來自於客戶端的公鑰。在基於公鑰認證機制認證時,服務端將讀取該文件。

在客戶端即主機A上:

  • /etc/ssh/ssh_config    :客戶端的全局配置文件。
  • ~/.ssh/config              :客戶端的用戶配置文件,生效優先順序高於全局配置文件。一般該文件預設不存在。該文件對許可權有嚴
  •                                   :格要求只對所有者有讀/寫許可權,對其他人完全拒絕寫許可權。
  • ~/.ssh/known_hosts   :保存主機驗證時服務端主機host key的文件。文件內容來源於服務端的ssh_host_rsa_key.pub文件。
  • /etc/ssh/known_hosts:全局host key保存文件。作用等同於~/.ssh/known_hosts。
  • ~/.ssh/id_rsa              :客戶端生成的私鑰。由ssh-keygen生成。該文件嚴格要求許可權,當其他用戶對此文件有可讀許可權時,
  •                                   :ssh將直接忽略該文件。
  • ~/.ssh/id_rsa.pub       :私鑰id_rsa的配對公鑰。對許可權不敏感。當採用公鑰認證機制時,該文件內容需要複製到服務端的
  •                                   :~/.ssh/authorized_keys文件中。
  • ~/.ssh/rc                     :保存的是命令列表,這些命令在ssh連接到遠程主機成功時將第一時間執行,執行完這些命令之後才
  •                                   :開始登陸或執行ssh命令行中的命令。
  • /etc/ssh/rc                  :作用等同於~/.ssh/rc。

1.5 配置文件簡單介紹

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

雖然服務端和客戶端配置文件預設已配置項雖然非常少非常簡單,但它們可配置項非常多。sshd_config完整配置項參見金步國翻譯的sshd_config中文手冊,ssh_config也可以參考sshd_config的配置,它們大部分配置項所描述的內容是相同的。

1.5.1 sshd_config

簡單介紹下該文件中比較常見的指令。

[root@xuexi ~]# cat /etc/ssh/sshd_config
#Port
22 # 服務端SSH埠,可以指定多條表示監聽在多個埠上 #ListenAddress 0.0.0.0 # 監聽的IP地址。0.0.0.0表示監聽所有IP Protocol 2 # 使用SSH 2版本 ##################################### # 私鑰保存位置 # ##################################### # HostKey for protocol version 1 #HostKey /etc/ssh/ssh_host_key # SSH 1保存位置/etc/ssh/ssh_host_key # HostKeys for protocol version 2 #HostKey /etc/ssh/ssh_host_rsa_key # SSH 2保存RSA位置/etc/ssh/ssh_host_rsa _key #HostKey /etc/ssh/ssh_host_dsa_key # SSH 2保存DSA位置/etc/ssh/ssh_host_dsa _key ################################### # 雜項配置 # ################################### #PidFile /var/run/sshd.pid # 服務程式sshd的PID的文件路徑 #ServerKeyBits 1024 # 伺服器生成的密鑰長度 #SyslogFacility AUTH # 使用哪個syslog設施記錄ssh日誌。日誌路徑預設為/var/log/secure #LogLevel INFO # 記錄SSH的日誌級別為INFO #LoginGraceTime 2m # 身份驗證階段的超時時間,若在此超時期間內未完成身份驗證將自動斷開 ################################### # 以下項影響認證速度 # ################################### #UseDNS yes # 指定是否將客戶端主機名解析為IP,以檢查此主機名是否與其IP地址真實對應。預設yes。 # 由此可知該項影響的是主機驗證階段。建議在未配置DNS解析時,將其設置為no,否則主機驗證階段會很慢 ################################### # 以下是和安全有關的配置 # ################################### #PermitRootLogin yes # 是否允許root用戶登錄 #MaxSessions 10 # 最大客戶端連接數量 #GSSAPIAuthentication no # 是否開啟GSSAPI身份認證機制,預設為yes #PubkeyAuthentication yes # 是否開啟基於公鑰認證機制 #AuthorizedKeysFile .ssh/authorized_keys # 基於公鑰認證機制時,來自客戶端的公鑰的存放位置 PasswordAuthentication yes # 是否使用密碼驗證,如果使用密鑰對驗證可以關了它 #PermitEmptyPasswords no # 是否允許空密碼,如果上面的那項是yes,這裡最好設置no ################################### # 以下可以自行添加到配置文件 # ################################### DenyGroups hellogroup testgroup # 表示hellogroup和testgroup組中的成員不允許使用sshd服務,即拒絕這些用戶連接 DenyUsers hello test # 表示用戶hello和test不能使用sshd服務,即拒絕這些用戶連接 ################################### # 以下一項和遠程埠轉發有關 # ################################### #GatewayPorts no # 設置為yes表示sshd允許被遠程主機所設置的本地轉髮端口綁定在非環回地址上 # 預設值為no,表示遠程主機設置的本地轉髮端口只能綁定在環回地址上,見後文"遠程埠轉發"

一般來說,如非有特殊需求,只需修改下監聽埠和UseDNS為no以加快主機驗證階段的速度即可。

配置好後直接重啟啟動sshd服務即可。

[root@xuexi ~]# service sshd restart

1.5.2 ssh_config

需要說明的是,客戶端配置文件有很多配置項和服務端配置項名稱相同,但它們一個是在連接時採取的配置(客戶端配置文件),一個是sshd啟動時開關性的設置(服務端配置文件)。例如,兩配置文件都有GSSAPIAuthentication項,在客戶端將其設置為no,表示連接時將直接跳過該身份驗證機制,而在服務端設置為no則表示sshd啟動時不開啟GSSAPI身份驗證的機制。即使客戶端使用了GSSAPI認證機制,只要服務端沒有開啟,就絕對不可能認證通過。

下麵也簡單介紹該文件。

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

 

如非有特殊需求,ssh客戶端配置文件一般只需修改下GSSAPIAuthentication的值為no來改善下用戶驗證的速度即可,另外在有非交互需求時,將StrictHostKeyChecking設置為no以讓主機自動添加host key。

1.6 ssh命令簡單功能

此處先介紹ssh命令的部分功能,其他包括埠轉發的在後文相關內容中解釋,關於連接復用的選項本文不做解釋。

語法:

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

例如,以172.16.10.6主機上的longshuai用戶登錄172.16.10.6。

[root@xuexi ~]# ssh longshuai@172.16.10.6
The 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       # 主機驗證
Warning: Permanently added '172.16.10.6' (ECDSA) to the list of known hosts.
longshuai@172.16.10.6's password:                      # 用戶驗證
Last login: Wed Jul  5 12:27:29 2017 from 172.16.10.6

此時已經登錄到了172.16.10.6主機上。

[longshuai@xuexi ~]$ hostname -I
172.16.10.6

要退出ssh登錄,使用logout命令或exit命令即可返回到原主機環境。

使用ssh還可以實現主機跳轉,即跳板功能。例如主機B能和A、C通信,但A、C之間不同通信,即A<-->B<-->C<-x->A的情形。如果要從A登陸到C,則可以藉助B這個跳板登錄到C。此處一個簡單示例為:從172.16.10.5登錄到172.16.10.6,再以此為基礎登錄到172.16.100.3上。

[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
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.3
The 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 -I
172.16.10.3 172.16.10.4

同樣,在退出時,也是一層一層退出的。

[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當跳板連接到172.16.10.3,所以172.16.10.3的host key是添加到172.16.10.3上而非172.16.10.5上的。

如果在命令行給出了要執行的命令,預設ssh將工作在前臺,如果同時給定了"-f"選項,則ssh工作在後臺。但儘管是工作在後臺,當遠程執行的命令如果有消息返回時,將隨時可能顯示在本地。當遠程命令執行完畢後,ssh連接也將立即關閉。

[root@xuexi ~]# ssh 172.16.10.6 'sleep 5'     # 在前臺睡眠5秒鐘

[root@xuexi ~]# ssh 172.16.10.6 -f 'sleep 5;echo over'   # 在後臺睡眠5秒,睡眠完成後echo一段信息

由於第二條命令是放在後臺執行的,所以該ssh一建立完成ssh會話就立即返回本地bash環境,但當5秒之後,將在本地突然顯示"over"。

ssh執行遠程命令預設允許從標準輸入中讀取數據然後傳輸到遠程。可以使用"-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下文件歸檔壓縮,然後傳送到遠程主機上並被解包;第二條命令將遠程主機上的/tmp目錄歸檔壓縮,並傳輸到本地解包。所以它們實現了拷貝的功能。

不妨再分析下麵的命令,該命令改編自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連接,併在遠程執行"umask 077"臨時修改遠程的umask值,使得遠程創建的目錄許可權為700,然後判斷遠程主機上是否有~/.ssh目錄,如果沒有則創建,最後從標準輸入中讀取本地公鑰文件~/.ssh/id_rsa.pub的內容並將其追加到~/.ssh/authorized_keys文件中。

如果將此命令改為如下命令,使用ssh的"-n"選項,並將追加重定向改為覆蓋重定向符號。

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

該命令的結果是清空遠程主機172.16.10.6上的~/.ssh/authorized_keys文件,因為ssh的"-n"選項強行改變了ssh讀取的標準輸入為/dev/null。

1.7 scp命令及過程分析

scp是基於ssh的遠程拷貝命令,也支持本地拷貝,甚至支持遠程到遠程的拷貝。

scp由於基於ssh,所以其埠也是使用ssh的埠。其實,scp拷貝的實質是使用ssh連接到遠程,並使用該連接來傳輸數據。下文有scp執行過程的分析。

另外,scp還非常不占資源,不會提高多少系統負荷,在這一點上,rsync遠不及它。雖然 rsync比scp會快一點,但rsync是增量拷貝,要判斷每個文件是否修改過,在小文件眾多的情況下,判斷次數非常多,導致rsync效率較差,而scp基本不影響系統正常使用。

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

scp [-12BCpqrv] [-l limit] [-o ssh_option] [-P port] [[user@]host1:]src_file ... [[user@]host2:]dest_file

選項說明:
-1:使用ssh v1版本,這是預設使用協議版本
-2:使用ssh v2版本
-C:拷貝時先壓縮,節省帶寬
-l limit:限制拷貝速度,Kbit/s,1Byte=8bit,所以"-l 800"表示的速率是100K/S
-o ssh_option:指定ssh連接時的特殊選項,一般用不上。
-P port:指定目標主機上ssh埠,大寫的字母P,預設是22埠
-p:拷貝時保持源文件的mtime,atime,owner,group,privileges
-r:遞歸拷貝,用於拷貝目錄。註意,scp拷貝遇到鏈接文件時,會拷貝鏈接的源文件內容填充到目標文件中(scp的本質就是填充而非拷貝)
-v:輸出詳細信息,可以用來調試或查看scp的詳細過程,分析scp的機制

src_file是源位置,dest_file是目標位置,即將src_file複製到dest_file,其中src_file可以指定多個。由於源位置和目標位置都可以使用本地路徑和遠程路徑,所以scp能實現本地拷貝到遠程、本地拷貝到本地、遠程拷貝到本地、遠程拷貝到另一個遠程。其中遠程路徑的指定格式為"user@hostname:/path",可以省略user,也可以省略":/path",省略":/path"時表示拷貝到目的用戶的家目錄下。

註意:scp拷貝是強制覆蓋型拷貝,當有重名文件時,不會進行任何詢問。

例如:

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

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

(2).本地到遠程:/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).遠程到本地: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).遠程路徑1到遠程路徑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拷貝機制分析

scp的拷貝實質是建立ssh連接,然後通過此連接來傳輸數據。如果是遠程1拷貝到遠程2,則是將scp命令轉換後發送到遠程1上執行,在遠程1上建立和遠程2的ssh連接,並通過此連接來傳輸數據。

在遠程複製到遠程的過程中,例如在本地(172.16.10.5)執行scp命令將A主機(172.16.10.6)上的/tmp/copy.txt複製到B主機(172.16.10.3)上的/tmp目錄下,如果使用-v選項查看調試信息的話,會發現它的步驟類似是這樣的。

# 以下是從結果中提取的過程
# 首先輸出本地要執行的命令
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主機
debug1: Connecting to 172.16.10.6 [172.16.10.6] port 22.
debug1: Connection established.
 
# 要求驗證本地和A主機之間的連接
debug1: Next authentication method: password
root@172.16.10.6's password:
 
# 將scp命令行修改後發送到A主機上
debug1: Sending command: scp -v /tmp/copy.txt root@172.16.10.3:/tmp
 
# 在A主機上執行scp命令
Executing: program /usr/bin/ssh host 172.16.10.3, user root, command scp -v -t /tmp
 
# 驗證A主機和B主機之間的連接
debug1: Next authentication method: password
root@172.16.10.3's password:
 
# 從A主機上拷貝源文件到最終的B主機上
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  
 
# 關閉本地主機和A主機的連接
Connection to 172.16.10.6 closed.

也就是說,遠程主機A到遠程主機B的複製,實際上是將scp命令行從本地傳輸到主機A上,由A自己去執行scp命令。也就是說,本地主機不會和主機B有任何交互行為,本地主機就像是一個代理執行者一樣,只是幫助傳送scp命令行以及幫助顯示信息。

其實從本地主機和主機A上的~/.ssh/know_hosts文件中可以看出,本地主機只是添加了主機A的host key,並沒有添加主機B的host key,而在主機A上則添加了主機B的host key。

 

1.8 基於公鑰認證機制實現雙機互信

在身份驗證階段,由於預設情況下基於公鑰認證的機制順序優先於基於密碼認證的機制,所以基於公鑰認證身份,就可以免輸入密碼,即實現雙機互信(實際上只是單方向的信任)。

基於公鑰認證機制的認證過程在前文已經詳細說明過了,如還不清楚,請跳回上文。

1.8.1 實現步驟

以下是實現基於公鑰認證的實現步驟:

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

[root@xuexi ~]# ssh-keygen -t rsa    # -t參數指定演算法,可以是rsa或dsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):  # 詢問私鑰保存路徑
Enter passphrase (empty for no passphrase):               # 詢問是否加密私鑰文件
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. 

如果不想被詢問,則可以使用下麵一條命令完成:"-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/目錄下私鑰的許可權。私鑰文件有嚴格的許可權要求,當私鑰文件的非所有者有可讀許可權時,將直接忽略該私鑰文件導致公鑰認證失敗。

[root@xuexi ~]# ls -l ~/.ssh
total 12
-rw------- 1 root root 1671 Jun 29 00:18 id_rsa      # 私鑰許可權必須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分發(即複製)到遠程待信任主機上。

ssh-copy-id用法很簡單,只需指定待信任主機及目標用戶即可。如果生成的公鑰文件,路徑不是~/.ssh/id_rsa.pub,則使用"-i"選項指定要分發的公鑰。

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

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

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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、確認mysql是否已安裝,有下麵的代碼可知 2、卸載已安裝的mysql,建議使用yum命令,因為yum命令可以自動刪除與mysql相關的依賴;如果使用rpm命令,則還需要手動去刪除和mysql相關的文件,比較麻煩 3、用whereis命令查找mysql相關的文件,因為步驟2用yum來卸載,所以m ...
  • 1. SVM基本知識 SVM(Support Vector Machine)是一個類分類器,能夠將不同類的樣本在樣本空間中進行分隔,分隔使用的面叫做分隔超平面。 比如對於二維樣本,分佈在二維平面上,此時超平面實際上是一條直線,直線上面是一類,下麵是另一類。定義超平面為: f(x)=w0+wTx 可以 ...
  • 先看一下實驗的兩張表: 表comments,總行數28856 表comments_for,總行數57,comments_id是有索引的,ID列為主鍵。 以上兩張表是我們測試的基礎,然後看一下索引,comments_for這個表comments_id是有索引的,ID為主鍵。 最近被公司某一開發問道JO ...
  • 在上篇《MySQL--當mysqldump --single-transaction遇到alter table》中測試發現,在MySQL 5.6版本中,如果在mysqldump期間修改表,可能會導致mysqldump報錯,而該結論與同事的執行現象不符,因此在MySQL 5.5版本中進行下測試。 測試 ...
  • 一 概述 1.物理分頁 物理分頁依賴的是某一物理實體,這個物理實體就是資料庫,比如MySQL資料庫提供了limit關鍵字,程式員只需要編寫帶有limit關鍵字的SQL語句,資料庫返回的就是分頁結果。 2.邏輯分頁 邏輯分頁依賴的是程式員編寫的代碼。資料庫返回的不是分頁結果,而是全部數據,然後再由程式 ...
  • 1. 問題表現 消息 102,級別 15,狀態 1,過程 wx_kaliushui,第 8 行'GO' 附近有語法錯誤。 為了說明問題,我把代碼精簡到極致,如下: 2. 排查過程 2.1. 去掉註釋部分,問題解決 2.2. 去掉GO,問題解決 2.3. 註釋掉GO,問題解決 2.4. 將代碼全選複製 ...
  • 部分生產環境採用mysqldump --single-transaction的方式在夜間進行資料庫備份,而同事恰好在備份期間執行了alter table操作,操作部分成功部分失敗,為啥呢? ## ## 以下測試在MySQL 5.6.36上執行,該問題存在版本差異! MySQL 5.5 版本測試結果: ...
  • 1、創建用戶create user KD identified by 123456;2、授予連接資料庫的許可權grant connect to KD;3、將Scott用戶的emp表授權給KD可以查詢grant select on scott.emp to KD;grant create table t ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...