一般的なSSHエラーのトラブルシューティング: 接続拒否と認証拒否

「接続拒否」と「アクセス許可拒否」のエラーを診断することで、イライラするSSH接続の問題を解決します。この実践ガイドでは、sshdサービスの状態確認、ファイアウォールルール(UFW)のデバッグ、鍵ベース認証のパーミッション修正、サーバー認証ログの解釈など、迅速な解決のための体系的なトラブルシューティング手順を詳しく説明します。

一般的なSSHエラーのトラブルシューティング: 接続拒否と認証拒否

SSHの障害は、トランスポートの問題と認証の問題を分離すると修正が容易になります。Connection refusedは、SSHクライアントがホストに到達したが、そのポートでTCP接続を受け入れるものがなかったことを意味します。Permission deniedは、SSHサーバーが応答したが、ログインを拒否したことを意味します。どちらも「入れない」という点では同じでも、異なるインシデントです。

サーバー設定を変更する間は、アクティブなSSHセッションを1つ開いたままにしておいてください。最も痛いSSH停止は、誰かが/etc/ssh/sshd_configを編集し、サービスを再起動し、切断した後で、新しい設定がすべてのログインパスをブロックしていることに気づいたときに発生します。

エラーの理解: 拒否と拒否の違い

何かを変更する前に、正確なクライアントメッセージを読んでください:

  • Connection refused: ホストがTCP接続を積極的に拒否しました。通常、sshdがそのポートでリッスンしていないか、ファイアウォールが拒否しています。
  • Connection timed out: パケットがドロップされているか、ネットワークパスが壊れています。これは、ファイアウォール、ルート、VPN、セキュリティグループ、または間違ったIPである可能性が高いです。
  • Permission denied (publickey): サーバーには到達可能ですが、あなたの鍵を受け入れませんでした。
  • Permission denied (publickey,password): サーバーは1つ以上の認証方法を試み、それらを拒否しました。
  • Host key verification failed: クライアントが、そのホスト名またはIPに対して現在提示されているサーバーIDを信頼していません。

パート1: 接続拒否のトラブルシューティング

ssh: connect to host example port 22: Connection refusedは、通常、リモートホストまたはポートを指します。マシンは応答しましたが、SSHはそこで接続を受け入れていませんでした。

1. SSHデーモン(sshd)の状態を確認する

拒否の最も一般的な原因は、SSHサーバープロセスが実行されていないか、クラッシュしたことです。

実行可能な手順(リモートサーバー上):

多くのLinuxディストリビューションでは、サービスはsshdと呼ばれます。DebianとUbuntuでは、しばしばsshと呼ばれます。システムが使用する方を試してください:

systemctl status sshd
systemctl status ssh

サービスが非アクティブまたは失敗した場合は、起動します:

sudo systemctl start sshd
sudo systemctl enable sshd

設定変更後にsshdの起動に失敗した場合は、設定を検証します:

sudo sshd -t

このコマンドは、SSHを再起動する前に実行できる最も安全なチェックの1つです。

2. リッスンポートと設定を確認する

デフォルトでは、SSHはTCPポート22を使用しますが、多くのサーバーは別のポートを使用します。サーバーが2222でリッスンしている場合、クライアントコマンドにそれを含める必要があります:

ssh -p 2222 [email protected]

A. sshd_configを確認する

SSH設定ファイル(通常は/etc/ssh/sshd_configにあります)を調べます。Portディレクティブを探します:

# /etc/ssh/sshd_config の例
Port 2222  # これが22でない場合、クライアント側で指定する必要があります

ファイルを編集した後、リロードする前にsudo sshd -tを実行します。構文が有効な場合は、サービスをリロードまたは再起動します。リロードは通常、中断が少ないです:

sudo systemctl reload sshd

B. リッスンソケットを確認する

ssを使用して、sshdがリッスンしていることを確認します:

sudo ss -tuln | grep 22

# リッスン状態を示す期待される出力:
# LISTEN 0      128    0.0.0.0:22               0.0.0.0:* 

SSHが127.0.0.1:22のみでリッスンしている場合、リモートクライアントは接続できません。0.0.0.0:22または特定のプライベートインターフェースアドレスでリッスンしている場合、ファイアウォールルールによってはリモートアクセスが可能な場合があります。

3. ファイアウォールとネットワークのチェック

パケットをドロップするファイアウォールは通常、タイムアウトを引き起こします。パケットを拒否するファイアウォールは、拒否を引き起こす可能性があります。ホストファイアウォールとホスト外部のネットワークファイアウォールの両方を確認します。

一般的なファイアウォールコマンド(Ubuntu/DebianのUFW):

SSHトラフィックが許可されていることを確認します:

# 現在の状態を確認
sudo ufw status

# デフォルトポート22のトラフィックを許可
sudo ufw allow ssh
# またはポート番号で
sudo ufw allow 22/tcp

# ファイアウォールルールをリロード
sudo ufw reload

クラウドセキュリティグループ、ネットワークACL、VPNルート、オフィスファイアウォールは、トラフィックがサーバーに到達する前にSSHをブロックする可能性があります。sshdがリッスンしており、ホストファイアウォールが開いている場合は、同じプライベートネットワーク内のマシンからテストします。これにより、問題がサーバー自体にあるのか、外部パスのどこかにあるのかがわかります。


パート2: アクセス許可拒否のトラブルシューティング

サーバーがPermission deniedで応答した場合、ネットワークパスは機能しています。ユーザー名、許可された認証方法、鍵、アカウントの状態、ファイルのパーミッションに焦点を当てます。

1. ユーザー名とパスワードを確認する

これは最も簡単なチェックですが、見落とされがちです:

  • ユーザー名: クラウドイメージは、ubuntuec2-useradmindebianrockyなどの特定のユーザーをよく使用します。rootは無効になっている場合があります。
  • パスワード: パスワード認証が有効になっている場合は、タイプミス、アカウントロックアウト、期限切れのパスワード、PAMルールを確認します。
  • ポートとホスト: 認証失敗のかなりの数は、たまたまSSHを実行している間違ったサーバーに接続することが原因です。

クライアント側のチェック: 詳細なデバッグ出力を表示するには、クライアントを冗長フラグで実行します:

ssh -vvv user@hostname

この出力には、クライアントが試行した認証方法と、サーバーが拒否した方法が明確に表示されます。

2. 鍵ベース認証の失敗

鍵認証は、クライアントが間違った秘密鍵を提供した場合、サーバーが一致する公開鍵を持っていない場合、パーミッションが開きすぎている場合、またはsshd_configがログインをブロックしている場合に失敗します。

A. .sshディレクトリの誤ったパーミッション

SSHはセキュリティのためにファイルのパーミッションに非常に厳格です。パーミッションが開きすぎていると、サーバーは鍵ファイルを完全に無視します。

リモートサーバー上(パーミッションの修正):

# ユーザーのホームディレクトリのパーミッションは通常問題ありませんが、.sshフォルダを確認します
chmod 700 ~/.ssh

# authorized_keysファイルは所有者のみが書き込み可能である必要があります
chmod 600 ~/.ssh/authorized_keys

所有権も確認します:

chown -R "$USER:$USER" ~/.ssh

サーバーでは、StrictModesが一般的に有効になっています。ホームディレクトリ、.sshディレクトリ、またはauthorized_keysファイルが他のユーザーによって書き込み可能な場合、sshdは鍵を無視する可能性があります。

B. 鍵が存在しない、または不正な形式

公開鍵がターゲットユーザーの~/.ssh/authorized_keysにあり、1行に1つの鍵であることを確認します。秘密鍵はクライアントに残します。authorized_keysに秘密鍵を貼り付けないでください。

クライアントから、デバッグ中に特定の鍵を強制します:

ssh -i ~/.ssh/id_ed25519 -vvv [email protected]

冗長出力で、どの鍵が提供され、サーバーがそれらを受け入れたか拒否した理由を示す行を探します。

C. 鍵を無効にするサーバー設定

サーバーの/etc/ssh/sshd_configをチェックして、鍵認証が許可されていることを確認します:

PubkeyAuthentication yes

# パスワードに依存する場合、パスワード認証が無効になっていないことを確認します
PasswordAuthentication yes

AllowUsersAllowGroupsDenyUsers、またはDenyGroupsが存在する場合、それらは有効な鍵設定のように見えるものを上書きする可能性があります。正しい鍵を持つユーザーでも、これらのディレクティブによってブロックされる可能性があります。

3. サーバー側のログ調査

サーバーログは通常、拒否の本当の理由を教えてくれます。サーバーでターミナルを開いたままにし、クライアントからのログイン試行中にログを監視します。

一般的なログの場所:

  • Debian/Ubuntu: /var/log/auth.log
  • RHEL/CentOS/Fedora: /var/log/secure

grepを使用して、最近の接続試行をフィルタリングします:

# RHEL/CentOSシステムの場合
sudo grep 'Failed password' /var/log/secure

# または一般的なSSHアクティビティを探す
sudo tail -f /var/log/secure

systemdジャーナリングを使用するシステムでは、これは多くの場合簡単です:

sudo journalctl -u sshd -f
sudo journalctl -u ssh -f

ログメッセージには、「bad ownership or modes」、「user not allowed」、「invalid user」、「authentication refused」、またはPAMアカウント障害が表示される場合があります。これらのメッセージは、クライアント側だけで推測するよりも信頼性が高くなります。

ホスト鍵検証の失敗

Host key verification failedは、パスワードや鍵の間違いと同じではありません。これは、クライアントがそのホスト名またはIPに対して保存されたサーバーIDを持っており、サーバーが現在異なるIDを提示していることを意味します。これは、再構築後、IPの再利用、ロードバランサーの変更、または実際のman-in-the-middleリスクの後に発生する可能性があります。

本番環境で警告を盲目的に削除しないでください。クラウドコンソール、構成管理、または既存の信頼できるチャネルを通じてサーバーフィンガープリントを確認します。変更が予期されていることがわかったら、古いエントリを削除します:

ssh-keygen -R example.com
ssh-keygen -R 192.0.2.10

次に、再度接続し、フィンガープリントが期待どおりである場合にのみ新しいホスト鍵を受け入れます。


信頼性の高いSSHアクセスのためのベストプラクティスまとめ

  1. 鍵ペアを使用する: 2番目のセッションで鍵アクセスをテストした後にのみ、パスワード認証を無効にします。
  2. ログインできるユーザーを制限する: 適切な場合はAllowUsersまたはAllowGroupsを使用しますが、将来のオペレーターが誤った権限の問題を追跡しないように文書化します。
  3. PermitRootLogin noを使用する: sudoを持つ通常ユーザーを優先します。
  4. 設定をバックアップする: /etc/ssh/sshd_configを変更する前に、コピーを作成します:
    
    

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F) ``` 5. リロード前に検証する: sudo sshd -tを実行します。 6. 緊急時のパスを維持する: クラウドサーバーの場合、SSHが壊れた場合にシリアルコンソール、レスキューモード、インスタンス接続機能、または構成管理を使用する方法を知っておきます。

SSHトラブルシューティングの最短経路は次のとおりです: 正確なエラーを特定し、サーバーがリッスンしているかどうかを確認し、ネットワークパスがそのポートに到達するかどうかを確認し、認証失敗のサーバーログを読み取ります。推測は、これらのチェックを順番に実行するよりも時間がかかることがよくあります。