天天看點

診斷并解決 SSH 連接配接慢的方法診斷并解決 SSH 連接配接慢的方法

每次putty使用ssh登入到遠端的linux進行管理的時候,遠端登入的過程都非常慢——輸入完使用者名之後,非要等到30秒左右才會出來輸入密碼的提示。在實際處理問題的時候,特别需要快速響應的時候,這種狀況着實讓人難以忍受。

但後來具體測試了一下,發現這又并非是每種系統的通病,出現問題的機器主要集中的centos上,同樣的debian系統,在遠端連接配接的過程就是健步如飛,絲毫沒有卡頓猶豫的感覺。這難道是centos的問題?

診斷并解決 SSH 連接配接慢的方法診斷并解決 SSH 連接配接慢的方法

<a target="_blank"></a>

centos:

<code>ssh -v [email protected]</code>

ssh遠端登入的時候顯示的資訊如下:

<code>openssh_6.0p1 debian-4, openssl 1.0.1e 11 feb 2013</code>

<code>...some sensitive information...</code>

<code>debug1: remote protocol version 2.0, remote software version openssh_5.3</code>

<code>debug1: match: openssh_5.3 pat openssh_5*</code>

<code>debug1: enabling compatibility mode for protocol 2.0</code>

<code>debug1: local version string ssh-2.0-openssh_6.0p1 debian-4</code>

<code>debug1: ssh2_msg_kexinit sent</code>

<code>debug1: ssh2_msg_kexinit received</code>

<code>debug1: kex: server-&gt;client aes128-ctr hmac-md5 none</code>

<code>debug1: kex: client-&gt;server aes128-ctr hmac-md5 none</code>

<code>debug1: ssh2_msg_kex_dh_gex_request(1024&lt;1024&lt;8192) sent</code>

<code>debug1: expecting ssh2_msg_kex_dh_gex_group</code>

<code>debug1: ssh2_msg_kex_dh_gex_init sent</code>

<code>debug1: expecting ssh2_msg_kex_dh_gex_reply</code>

<code>debug1: ssh_rsa_verify: signature correct</code>

<code>debug1: ssh2_msg_newkeys sent</code>

<code>debug1: expecting ssh2_msg_newkeys</code>

<code>debug1: ssh2_msg_newkeys received</code>

<code>debug1: roaming not allowed by server</code>

<code>debug1: ssh2_msg_service_request sent</code>

<code>debug1: ssh2_msg_service_accept received</code>

<code>debug1: authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password</code>

<code>debug1: next authentication method: gssapi-keyex</code>

<code>debug1: no valid key exchange context</code>

<code>debug1: next authentication method: gssapi-with-mic</code>

<code>debug1: unspecified gss failure. minor code may provide more information</code>

<code>cannot determine realm for numeric host address</code>

<code></code>

<code>debug1: next authentication method: publickey</code>

<code>debug1: trying private key: /home/mitchellchu/.ssh/id_rsa</code>

<code>debug1: trying private key: /home/mitchellchu/.ssh/id_dsa</code>

<code>debug1: trying private key: /home/mitchellchu/.ssh/id_ecdsa</code>

<code>debug1: next authentication method: password</code>

而debian使用同樣的指令測試的結果為:

<code>debug1: remote protocol version 2.0, remote software version openssh_6.0p1 debian-4</code>

<code>debug1: match: openssh_6.0p1 debian-4 pat openssh*</code>

<code>debug1: sending ssh2_msg_kex_ecdh_init</code>

<code>debug1: expecting ssh2_msg_kex_ecdh_reply</code>

<code>debug1: ssh_ecdsa_verify: signature correct</code>

<code>debug1: authentications that can continue: publickey,password</code>

從上面可以看到,在centos中,系統使用了publickey,gssapi-keyex,gssapi-with-mic,和password來進行認證(上面顔色标記行,23行),而debian此時則使用了publickey和password兩種。在連接配接centos的時候,在23行處花費了相當多的時間。我們在那裡開始往下看,就能非常清楚的看到下面的資訊:

<code>#下面使用的是gssapi-keyex來進行驗證</code>

<code>#但是報錯:沒有可用的key來交換資訊</code>

<code>#系統接着又使用下一個驗證方法:gssapi-with-mic</code>

<code>#但遺憾的是,gssapi-with-mic方法也失敗。</code>

<code>#原因:不能确定數字主機位址的域</code>

<code># 在嘗試幾次後,ssh認證終于放棄了這種驗證。進入下一個驗證:publickey</code>

除了這個方法還有其他方法麼?這個自然是有的,centos其實就已經提供給我們一個解決方案了——使用ssh遠端登入的時候禁用gssapi驗證。當然,還有一個問題不得不注意,如果你的機器上啟用了usedns的話,需要一并關閉,具體可參見最後的說明。

從錯誤可以看出應該是和主機域相關的問題——應該是無法确認ip對應的域,是以會出現這個問題。gssapi主要是基于kerberos的,是以要解決這個問題也就變得要系統配置有kerberos,這對于沒有kerberos的筒子們來說,配置個kerberos就為了解決個登入延時問題,似乎不是個明智的決定——特别是在生産環境中!最小化滿足需求才是王道。

禁用gssapi認證有兩個方式:用戶端和服務端

比較簡單,影響的隻有單個用戶端使用者,可以用下面的方法實作:

<code>ssh -o gssapiauthentication=no your-server-username@serverip</code>

用上面的方法登入遠端,即可實作禁用gssapiauthentication。

如果你嫌麻煩,直接配置你ssh用戶端的檔案<code>/etc/ssh/ssh_config</code>來達到永久解決這個問題:

<code>vi /etc/ssh/ssh_config</code>

<code>### 找到ssh_config檔案裡面的gssapiauthentication yes這行</code>

<code>### 修改為gssapiauthentication no</code>

<code>### 儲存ssh_config檔案并退出</code>

這個修改方法是将所有這個機器上的使用者都影響到了,如果你影響面不要那麼的廣泛,隻要在指定的使用者上實施禁用gssapiauthentication的話,那麼你可以在該使用者的目錄下,找到.ssh目錄,在其下面添加<code>config</code>檔案,并在檔案内添加上面這句,如果沒有這個檔案,你也可以直接這麼做:

<code>cat &gt;&gt;~/.ssh/config&lt;&lt;eof</code>

<code>gssapiauthentication no</code>

<code>eof</code>

使用cat,直接将輸入導出到檔案中,這時候,你在使用ssh連接配接遠端的目标主機時,就不會再使用gssapi認證了。

上面這些檔案是在用戶端,不是服務端的。也就是說,要修改這個檔案,你的用戶端也要是linux才行。

如果你是在windows下使用putty這樣的用戶端工具,就不使用上面這個方法了,putty下可以嘗試在連接配接之前進行設定:

putty configuration -&gt; connection -&gt; ssh -&gt; auth -&gt; gssapi -&gt; (取消勾選)attempt gssapi authentication(ssh-2 only)

如果沒有關閉putty的gssapiauthentication,你可以在連接配接的視窗右鍵(或:ctrl + 右鍵)檢視日志,可以發現putty會自動嘗試gssapi連接配接的日志:

<code>2014-05-18 23:46:54 using sspi from secur32.dll</code>

<code>2014-05-18 23:46:54 attempting gssapi authentication</code>

<code>2014-05-18 23:46:54 gssapi authentication request refused</code>

恩,上面基本上将用戶端禁止gssapiauthentication的方法羅列了一下。

注意:上面這些方法是比較通用的。

那麼你也可以嘗試下如下的用戶端解決這個問題的方法:

添加遠端主機的主機名到你本機的host檔案中(linux是<code>/etc/hosts</code>,windows是<code>系統盤:\windows\system32\drivers\etc\hosts</code>)。linux和windows下都可以添加下面這行。

<code>### 注意:下面這樣的ip-addr要替換成你的遠端機器的ip位址,hostname,自然是主機名 ip-addr hostname</code>

添加完畢之後,儲存退出。

如果你沒有配置kerberos的話,僅配置這個hosts檔案一樣是不能解決問題的,在使用ssh登入的時候,你可以看到報錯日志會類似下面這樣:

<code>debug1: authentications that can continue: publickey,gssapi-keyex,gssapi-with-mi</code>

<code>credentials cache file '/tmp/krb5cc_0' not found</code>

這個錯誤我在剛開始的時候也犯了的,需要注意。

直接到/etc/ssh/sshd_config裡面,将gssapiauthentication yes改為no即可了,同時也請注意,你可能也需要将usedns這個也修改成usedns no(這個要注意,每個系統的預設值不同,此處以centos 6為例):

<code>sudo vi /etc/ssh/sshd_config</code>

<code>### 普通使用者權限不夠,需要root權限</code>

<code>### 找到gssapiauthentication yes,修改為</code>

<code>### gssapiauthentication no</code>

<code>### 注意,這裡你也需要将usedns修改為no,centos預設是yes,即使這行已被注釋,你也需要加上</code>

<code>### usedns no</code>

<code>### 有看到人說usedns yes不需要修改為usedns no,mitchell測試下來是需要的。</code>

<code>### 儲存檔案,退出</code>

當禁用之後,我們需要重新開機ssh服務來保證新的配置檔案被正确應用:

<code>service sshd restart</code>

這個時候,再次使用ssh登入這個主機時,是不是感覺飛快了?

呼~ 終于完成了這篇長文,要一邊搗騰一邊弄出這些個文字,還是真是有點困難。不過,這樣也就将問題搗騰的差不多了,希望看文章的你能夠看的明白,歡迎讨論。  

1. gssapi:generic security services application program interface,gssapi本身是一套api,由ietf标準化。其最主要也是著名的實作是基于kerberos的。一般說到gssapi都暗指kerberos實作。

2. usedns:是openssh伺服器上的一個dns查找選項,而且預設還是打開的,在打開的狀态下,每當用戶端嘗試連接配接openssh伺服器的時候,服務端就自動根據使用者用戶端的ip進行dns ptr反向查詢(ip反向解析才會有記錄),查詢出ip對應的hostname,之後在根據用戶端的hostname進行dns正向a記錄查詢。通過這個查詢,驗證ip是否和連接配接的用戶端ip一緻。但絕大部分我們的機器是動态擷取ip的,也就是說,這個選項對于這種情況根本就沒用——即使是普通靜态ip伺服器,隻要沒有做ip反向解析,也難以适用。如果你符合這些情況,建議關閉usedns以提高ssh遠端登入時候的認證速度。

<b>原文釋出時間為:2015-07-20</b>

<b></b>

<b>本文來自雲栖社群合作夥伴“linux中國</b>

繼續閱讀