SSHサーバへ接続出来ない・遅い時の原因と対処法

先日、仕事でサーバの環境変更を行っていた時にSSHに接続できなくなったので、備忘として残しておく。
UNIX系のOSに接続する際は、基本的にSSHでの接続を行う事が多いと思うが、その接続ができなかったり、接続が遅い時の事象と原因、対処方法を記述する。

なお、この対処法は以下の確認ができている事が前提。

  • Pingが通っていること(SSHサーバは疎通が取れる状態であること)
  • SSHで利用するポートが開いていること(iptablesなどのファイアウォールでポートが閉じられていないこと)
  • sshdサービスが起動していること
  • ユーザ名・パスワードが間違っていないこと
  • ログインの認証方式が正しいこと(チャレンジレスポンス認証にプレーンテキスト認証で接続を試みていないことなど)

1.DNSへ接続できない状態で、IPアドレスの逆引き設定が有効になっている

おそらく、一番よくあるのがこれではないだろうか。SSHコマンド実行時にパスワードの入力プロンプトが表示されるまでにタイムアウトしてしまうか、異常に時間がかかる場合が該当する。Teratermでは事象の切り分けが難しいので、可能であればsshコマンドで確認したい。

事象の特徴

クライアントのIPアドレスを逆引きするためにDNSサーバにアクセスするが、接続ができずにタイムアウトになるのがその原因。
そのため、SSH以外のサービスでクライアントの逆引きを行うサービス(FTPなど)でも接続に時間がかかったり、タイムアウトになったりする。

原因

もうすでにタイトルで出ているが、クライアントのIPアドレスを逆引きするためにDNSサーバにアクセスするが、それがタイムアウトになっている事が原因だ。
とりあえず、以下の図を見てもらいたい。

今回、簡単に作った図だが、大まかな流れとしてはこのようになっている。
クライアントのIPアドレスをDNSサーバ側で逆引き設定するケースは少ないと思うが、その確認がsshd_configでデフォルトで有効になっている。
また、manの情報を見るとそのクライアントのIPアドレスからホスト名を逆引きし、さらにホスト名からIPアドレスを正引きするような処理になっているようだが、そもそもDNSサーバから逆引き出来なくても、即座にDNSサーバ側でエラーメッセージを返し、SSH接続自体は出来てしまう。

※このUseDNSを用いる機能としてはrhostsを用いたホスト指定でのログイン制限機能などだが、この認証方式はセキュアではないとしてデフォルトで有効になっていない。このUseDNS、なぜデフォルトで有効になっているのかがよくわからない機能だ。

ただ接続が遅い場合であれば問題は無いが、HP-UXなどの場合、このタイムアウトにDNSサーバ1台につき75秒もかかる(デフォルトで5秒×4回となっており、回数を追うごとに秒数が倍になっていく。なお、DNSサーバが一台増えるごとに5秒づつ時間が増えていく。)。このタイムアウトの秒数によっては、SSHサーバへの接続自体が出来ない事もある。

対策

対策としては4つ。

1つ目は、まずそもそもSSH接続出来ない場合の対策としてクライアント(今回はWindows)側のSSH接続のタイムアウト時間を延長する方法だ。
これは、SSHクライアントとしてTeratermを使っているのであれば「TERATERM.INI」にある「ConnectingTimeout」の値を大きくする事だ。とりあえず90秒程度にすれば接続自体は出来るようになるだろう。

2つ目は、DNSのタイムアウト時間を短縮する方法だ。対症療法的な感じが拭えないが、現状すでに運用が始まっているシステム等では色々としがらみがあるため、この方法で対処を行うのもいいだろう。
基本的に、resolv.confにオプションを書き加える事で対応可能だ。オプションの内容自体は各OSごとに変わるため、自身の環境に応じて別途確認してもらいたい。

3つ目は、サーバ側のhostsファイルにクライアントのホスト名とIPアドレスを対応付けてあげることだ。
しかし、この方法はあまりおすすめ出来ない。まずnsswitch.confの設定がDNSよりもhostsファイルの方が優先されている必要もあるし、接続するクライアントが限定されている必要がある。

4つ目は、そもそもこの機能自体いらないので、無効にしてしまう事だ。そもそも、この機能を有効にしていても、SSHサーバ側のログにクライアントのホスト名が記述されるくらいにしか使われない。
UseDNSを無効にするには、以下の一行を「sshd_config」に書き加え、sshdを再起動するだけだ。

UseDNS=no

sshd再起動のコマンドは以下。

/etc/init.d/sshd restart

2.クライアント側でIPv6で接続、DNS逆引きを行おうとしてタイムアウトになっている

クライアント側で接続時にホスト名を利用しており、それをIPv6で名前解決するために発生している。
IPv4しか使っていない環境であれば、以下の内容をクライアント側の「ssh_config」に対し設定する。

AddressFamily inet

3.GSSAPI 認証が有効になっている

サーバ、クライアントのどちらかでGSSAPI認証が有効になっていると、SSHへの接続に時間がかかる事がある。
GSSAPI認証は、SSHでKerberos認証を利用したい場合によく使われるオプションだ。とは言え、利用する環境はかなり限られている。この機能を無効にする場合は、以下の内容をクライアント側の「ssh_config」に対し設定する。

GSSAPIAuthentication no

4.authログの領域が100%になっている

サーバ側のauthログが書き込まれるパーティションの使用容量が100%になり、ログを書き込むことが出来ないためにSSHログインできない場合がある。そもそもログローテーションをしていない、機能していない場合によく発生し、OSは古いUNIX系OS(HP-UXなど)で発生する傾向が強い。

対処は、authログが書き込まれる領域の空き容量を増やすことだ。不要ファイルを削除したり、パーティションの容量を増やすことで対応したい。

この事象によりssh接続出来ない状態でも、コンソールログインは可能であるため、iLOやマネジメントポートなどからコンソールログインを行い、そこから対処を行うと良いだろう。