エラーメッセージで最初の確認先を決める

SSH(サーバーに暗号化された経路でログインする仕組み)の接続失敗は、表示されるエラーで原因の層がおおよそ分かります。最初にメッセージを正確に読み取り、下の表で最初に確認する場所を決めてください。

表示されるメッセージ意味最初の確認先
Connection timed outパケットが相手に届かないか、途中で破棄されているネットワーク到達性、ファイアウォール、セキュリティグループ、fail2ban
Connection refusedホストには届いたが、そのポートで待ち受けがないか拒否されたsshdの稼働状態と待ち受けポート
Connection reset by peer、Connection closed byTCP接続の直後にサーバー側から切断されたfail2ban等のブロック、sshdのログ
Permission denied (publickey)sshdには到達したが認証に失敗したユーザー名、鍵、パーミッション、sshd_config
REMOTE HOST IDENTIFICATION HAS CHANGED以前記録したホスト鍵と、今回サーバーが提示した鍵が異なる接続を止め、鍵が変わった理由を確認する

メッセージだけでは判断がつかない場合は、クライアント側で詳細ログを出します。どの段階で止まっているかが分かります。

ssh -vvv [email protected]

Connecting to の後で止まればネットワークの問題です。Authentications that can continue が出ていれば、認証の段階まで進んでいます。

Connection timed out:経路と通信制御を確認する

宛先と経路が正しいか

最初に、接続先のIPアドレスとホスト名を確認します。クラウドのインスタンスは停止して再起動するとパブリックIPが変わることがあります。DNSが古いIPを返している場合もあります。dig や nslookup で解決結果を確認し、管理画面のIPと比べてください。

次に、TCPの22番ポート(変更している場合はそのポート)に届くかを確認します。pingはICMPを止めている環境が多いため、pingが通らないだけでは判断できません。

nc -vz example.com 22

別のネットワーク(スマートフォンのテザリングなど)からは接続できる場合、手元側の社内ファイアウォールやプロキシが外向きの22番を止めている可能性があります。この場合は社内のネットワーク管理者に確認します。

ファイアウォールとセキュリティグループ

どこからも届かない場合は、サーバー側の通信制御を確認します。クラウドではセキュリティグループやネットワークACLの受信ルールを確認します。特に多い原因は、送信元IPを自宅やオフィスのIPに限定していて、そのIPが回線の都合で変わった場合です。現在の送信元IPがルールに含まれているかを確認してください。

OS側のファイアウォール(ufw、firewalld、nftables/iptables)は、コンソールから入れる場合に確認します。SSHのポートを変更した直後であれば、新しいポートが許可されていない可能性が高いです。

fail2ban等による自動ブロック

しばらく前まで接続できていて、パスワードや鍵の失敗を繰り返した後に急に繋がらなくなった場合は、fail2ban(ログイン失敗を検知して送信元IPを一定時間遮断するツール)などによるブロックを疑います。遮断方式によって、表示がtimed outになる場合もresetになる場合もあります。別のIPから入れるなら、次のコマンドで状況を確認し、自分のIPを解除します。

sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10

管理用の固定IPがあれば、設定の ignoreip に登録すると再発を防げます。ただし、除外範囲を広く取りすぎると防御の意味が薄れます。クラウド事業者側のDDoS対策やIDS/IPSが遮断している例もあるため、サーバー内で該当する記録が見つからなければ、そちらのログも確認します。

Connection refused:sshdの稼働とポートを確認する

refusedは、ホストまでは届いていることを示します。原因の多くは、sshdが止まっている、別のポートで待ち受けている、特定のアドレスでしか待ち受けていない、のいずれかです。確認にはコンソールなど別の経路が必要になることが多いです。

sudo systemctl status ssh    # Debian/Ubuntu
sudo systemctl status sshd   # RHEL系
sudo ss -tlnp | grep ssh

sshdが起動していない場合は、まず設定の文法チェックを実行します。設定ファイルの誤りで起動に失敗していることがよくあります。

sudo sshd -t

エラーが出なければ起動し、journalctl -u ssh(RHEL系は -u sshd)で起動時のメッセージを確認します。ss の結果でポートや ListenAddress が想定と違う場合は、その値に合わせて接続するか設定を直します。Ubuntuの比較的新しいリリースでは、ソケットアクティベーション(systemdが代わりにポートを開いて待ち受ける方式)が既定になっています。この場合、sshd_configのPortを変えた後に systemctl daemon-reload と ssh.socket の再起動が必要になることがあります。手順は使用しているリリースの公式ドキュメントで確認してください。

Permission denied (publickey):鍵とパーミッションを確認する

クライアント側で確認すること

手間の少ない順に、ユーザー名、使用している鍵、鍵の種類を確認します。クラウドのイメージは初期ユーザー名が ubuntu、ec2-user などイメージごとに異なります。鍵は -i で明示し、-o IdentitiesOnly=yes を付けて意図した鍵だけを使わせます。ssh-agentに多数の鍵が登録されていると、正しい鍵を試す前に試行回数の上限に達して拒否されることがあります。

OpenSSH 8.8以降は、SHA-1を使う ssh-rsa 署名を既定で無効にしています。古いサーバーや古い鍵の組み合わせで、ある日を境に入れなくなった場合はこれが原因のことがあります。署名方式を戻して回避するより、Ed25519などの鍵への移行を優先してください。

サーバー側で確認すること

サーバー側のログに、拒否の理由が具体的に出ます。journalctl -u ssh、または /var/log/auth.log(Debian系)、/var/log/secure(RHEL系)を確認します。Authentication refused: bad ownership or modes と出ていれば、パーミッションが原因です。sshdは既定の StrictModes yes により、他のユーザーが書き換えられる鍵ファイルを信用しません。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~

ホームディレクトリと .ssh の所有者が、ログインするユーザー本人になっているかも確認します。SELinuxが有効なRHEL系では、ファイルを別の場所からコピーした際にセキュリティコンテキストがずれることがあります。restorecon -Rv ~/.ssh で既定の状態に戻せます。

sshd_configの設定:実際に効いている値を確認する

ログに設定由来の拒否(not allowed because など)が出ている場合は、sshd_configを確認します。設定ファイルを目で読むより、実際に効いている値を出力するほうが確実です。

sudo sshd -T | grep -Ei 'port|pubkey|permitroot|allowusers|allowgroups|authorizedkeys'

確認するのは、PubkeyAuthentication、AuthorizedKeysFile、AllowUsers/AllowGroups、PermitRootLogin、末尾の Match ブロックです。OpenSSHは同じ項目が複数回書かれていると最初の値を採用します。ディストリビューションによっては、ファイル冒頭で /etc/ssh/sshd_config.d/ 配下を読み込みます。このため、本体を書き換えても配下のファイルの値が優先されることがあります。各項目の意味はOpenSSHのsshd_configマニュアルで確認できます。

設定を変更するときは、既存のSSHセッションを1つ開いたままにします。そのうえで sshd -t で検証してから再起動し、別の端末から新規接続を試します。この順序を守れば、設定ミスで締め出される事態を避けられます。

どうしても入れないときはコンソールから復旧する

SSHを経由しない経路を使います。クラウドでは、各社が提供するシリアルコンソールやブラウザ経由の接続機能(AWS Systems Manager Session Manager、EC2シリアルコンソールなど)が使えます。オンプレミスでは、IPMI、iDRAC、iLOなどのリモート管理機能や物理コンソールを使います。これらは事前に有効化やエージェント導入が必要な場合があります。障害が起きる前に、使える状態か確認しておいてください。

コンソールにも入れない場合は、クラウドならディスク(ボリューム)を停止したインスタンスから外し、別のインスタンスにマウントします。そこでauthorized_keysやsshd_configを修正します。作業前にスナップショットを取得してください。

REMOTE HOST IDENTIFICATION HAS CHANGEDを無視しない判断基準

この警告は、接続先が以前と別のサーバーである可能性を示します。正当な理由としては、OSの再インストール、インスタンスの作り直し、同じIPの別サーバーへの再割り当て、ホスト鍵の意図的な更新などがあります。一方で、通信を横取りする中間者攻撃(MITM)でも同じ警告が出ます。

判断の基準は、鍵が変わった理由を自分または管理者が具体的に説明できるかです。説明できる場合でも、SSH以外の経路で正しいフィンガープリント(鍵を識別する短い値)を確認します。コンソールで次を実行し、警告に表示された値と一致するか比べます。

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

一致した場合に限り、ssh-keygen -R ホスト名 で古い記録を削除して接続し直します。StrictHostKeyChecking=no や UserKnownHostsFile=/dev/null で警告を消す回避策は、検証そのものを無効にするため使わないでください。

変更の理由が説明できない場合や、フィンガープリントが一致しない場合は、その経路でパスワードや鍵を使ったログインを試みないでください。接続をやめ、ネットワーク管理者やセキュリティ担当に報告します。公衆Wi-Fiなど特定のネットワークでだけ警告が出る場合は、そのネットワーク側を疑う根拠になります。

切り分けが行き詰まったときの次の一手

上の手順で原因が見つからない場合は、クライアントの ssh -vvv の出力と、同じ時刻のサーバー側ログを並べて比べてください。サーバー側に接続の記録が一切なければネットワーク層の問題です。記録があれば認証か設定の問題です。この境界を決めてから、クラウド事業者やネットワーク担当に問い合わせると話が早く進みます。今回の障害で使った復旧経路は、次の障害に備えて手順書に残しておきます。