インフラ作業支援ラボInfra Support Lab ← ガイド一覧← 戻る
問題発生時のトラブル解決ガイド

SSH接続できない原因と確認手順

このページの目的

SSH接続失敗を「接続先へ届かない」「設定されたSSHポートで受け付けていない」「SSHの認証で拒否されている」に分け、エラー文だけで原因を決めつけず、確認結果から次に見る場所を決められるようにします。

最初にやること

まず ssh -G で実際に使われる接続先・ポート・ユーザーを確認し、ssh -vvv で詳細ログを取ります。そのうえで、確認した接続先とポートへ nc -vz を実行し、「通信段階」と「認証段階」を分けます。

このページの対象:SSHクライアントからLinuxサーバーへ接続できないケースです。SSH接続自体は成功し、ログイン後のコマンドだけが Permission denied になる場合は、Permission deniedの切り分けガイドを確認してください。

SSH Connection refused・timed out・publickey の原因早見表

Connection refused と timed out の違い:refused は接続先から拒否応答が返った状態なので、まず接続先・ポート・sshdの待受を確認します。timed out は応答が返らないため、Firewall・ACL・ルーティング・クラウド側通信制御を優先します。

最初に表示されたエラーから、優先して確認する範囲を決めます。エラー文だけで原因を断定せず、設定変更の前に確認コマンドで切り分けます。

エラー・症状まず疑う範囲最初の確認
Connection refusedsshd停止、待受ポート違い、接続先側の拒否nc -vz → ss -lntp
Connection timed outFirewall、ACL、経路、クラウド側通信制御nc -vz → 経路・Firewall確認
No route to hostルーティング、到達性、Firewallip route get
Permission denied (publickey)接続ユーザー、秘密鍵、公開鍵登録、認証設定ssh -vvv → 認証ログ
Could not resolve hostnameホスト名、DNS、名前解決設定getent hosts
Host key verification failed
REMOTE HOST IDENTIFICATION HAS CHANGED
接続先の変更、ホスト鍵不一致接続先確認 → fingerprint照合
使い方:該当するエラーを早見表で確認したら、下の手順で「接続先 → TCP接続 → 待受 → sshd設定 → Firewall/経路 → ログ」の順に原因を絞ります。

SSH接続のどの段階で失敗しているか

SSH接続は、おおまかに名前解決 → TCP接続 → SSH開始・鍵交換 → ユーザー認証 → ログインの順に進みます。最初に止まっている段階を分けると、関係のない設定を変更せずに済みます。

ssh -vvv user@example-host ssh -G example-host | grep -E '^(hostname|port|user) '

原因を順番に確認する

  1. 接続先・ポート・ユーザーを確認

    ssh -G example-host | grep -E '^(hostname|port|user) ' getent hosts example-host

    ~/.ssh/config などにより、想定と違うホスト・ポート・ユーザーへ接続していないか確認します。ここが違っていれば、サーバー側の設定を変更する前に接続条件を見直します。

  2. SSHポートへTCP接続できるか確認

    nc -vz example-host 22 ssh -vvv user@example-host

    SSHポートが22以外なら実際のポートで確認します。ここで Connection refused、Connection timed out、またはTCP接続成功のどれになるかを見ます。

Connection refusedの場合

Connection refused は、一般に接続先からTCPの拒否応答を受けたときに表示されます。接続先・ポート → 待受 → sshd状態 → 実効設定の順で確認します。 最初に ssh -G でポートを確定し、nc -vz と接続先の ss -lntp を対応させて確認します。

# 接続先 sudo ss -lntp | grep -E ':(22|SSH_PORT)\b' sudo systemctl status sshd # Debian/Ubuntu系では ssh の場合があります sudo systemctl status ssh sudo sshd -t sudo sshd -T | grep -E '^(port|listenaddress) '
先に再起動しない:LISTENの有無と sshd -t / sshd -T の結果を確認してから変更します。Match を使う環境では、必要に応じて sshd -T -C user=...,host=...,addr=... で条件適用後の値も確認します。

Connection timed outの場合

Connection timed out は応答が返っていないため、FirewallのDROP、ACL、ルーティング、クラウド側通信制御などを優先して確認します。 接続元IPと許可CIDRも同時に確認し、OS内だけで原因を決めつけないようにします。

ip route get 192.0.2.10 sudo firewall-cmd --list-all sudo nft list ruleset # 必要に応じて接続先で sudo tcpdump -ni any 'tcp port 22'

接続先の tcpdump にSYNが届かないなら途中経路、SYNが届くのに応答しないなら接続先側へ調査範囲を寄せます。外部Firewallやクラウドのセキュリティ制御がある場合はOS側だけで完結しません。

  1. 接続先でsshdが待ち受けているか確認

    sudo ss -lntp | grep -E ':(22|SSH_PORT)\b' sudo systemctl status sshd # Debian/Ubuntu系ではサービス名が ssh の場合があります sudo systemctl status ssh

    sshdが起動していても、Port や ListenAddress により意図したポート・アドレスで待ち受けていない場合があります。

  2. sshd設定の構文と実効値を確認

    sudo sshd -t sudo sshd -T | grep -E '^(port|listenaddress|passwordauthentication|pubkeyauthentication|permitrootlogin) '

    sshd -t は構文確認、sshd -T は実効設定の確認に使います。設定変更時は既存SSHセッションを残し、新規接続を確認してから切り替えます。

  3. Firewallと許可元CIDRを確認

    sudo firewall-cmd --list-all sudo nft list ruleset

    接続元IPが許可範囲に含まれるか確認します。CIDRの範囲確認にはCIDR計算ツールも使えます。クラウドや外部Firewallがある場合は、経路上のルールも確認します。

  4. サーバー側ログを確認

    sudo journalctl -u sshd -b --no-pager # 環境により sudo tail -n 100 /var/log/secure sudo tail -n 100 /var/log/auth.log

    クライアントの ssh -vvv と同じ時刻のサーバー側ログを突き合わせます。TCP接続後の切断や認証拒否は、ログから理由を確認できる場合があります。

  5. 必要ならパケット到達を確認

    sudo tcpdump -ni any 'tcp port 22'

    経路と接続先のどちらで止まっているか判断できない場合に使います。常時実行するのではなく、上の確認で絞り切れないときの追加確認です。

既存環境でnetstat・serviceを使っている場合

古いLinuxや既存の運用手順では、待受確認にnetstat、サービス状態確認にserviceを使う場合があります。利用可能なら現行手順のss・systemctlと読み替えて確認できます。

# 現在一般的な確認 sudo ss -lntp | grep -E ':(22|SSH_PORT)\b' sudo systemctl status sshd # 既存環境で見かける確認 sudo netstat -lntp | grep -E ':(22|SSH_PORT)\b' sudo service sshd status
まず環境確認:ps -p 1 -o comm=とcommand -v ss netstat systemctl serviceで、そのホストで使う管理方式を確認します。ディストリビューションによってサービス名がsshの場合もあります。

Permission denied (publickey)の場合

Permission denied (publickey) まで進んでいる場合、通信・sshd起動より後の公開鍵認証フェーズで失敗しています。ここでは段階だけ判断し、ユーザー・使用鍵・公開鍵登録・権限・実効設定の詳細確認は専用ページへ分けます。

ssh -G example-host | grep -E '^(hostname|user|port|identityfile) ' ssh -vvv user@example-host
publickeyエラーを詳しく切り分ける:Permission denied (publickey)の原因と確認手順で、鍵選択からサーバーログまで順番に確認できます。権限だけを確認したい場合はauthorized_keysの権限ガイドを使ってください。

その他のSSHエラー

Could not resolve hostname

getent hosts example-host ssh -G example-host | grep '^hostname '

ホスト名の入力、SSH設定で展開される接続先、DNS・名前解決の順に確認します。名前解決できない段階では、sshdや公開鍵を変更しても解決しません。getentでも解決できない場合は、DNS名前解決トラブルガイドでNSS・resolver・DNSサーバーを切り分けてください。

Host key verification failed / REMOTE HOST IDENTIFICATION HAS CHANGED

接続先が本当に想定したサーバーかを確認し、管理経路など信頼できる方法でホスト鍵のfingerprintを照合します。

known_hostsを先に消さない:サーバー再構築やホスト鍵変更が正当なものか確認する前に警告を消すと、中間者攻撃などの異常を見逃す可能性があります。

確認結果から次の対応を決める

確認結果対処
nc が Connection refused接続先でsshdが起動・LISTENしているか確認し、停止原因やPort/ListenAddressの誤りを修正します。sshd設定を変更したらsshd -tで構文確認してからreload/restartします。
nc がtimeout正しい宛先IP・経路を確認し、Firewall/ACL/セキュリティ制御で接続元CIDRとSSHポートを必要最小限だけ許可します。調査目的で全開放しません。
TCP接続後に Permission denied (publickey)通信は到達済みです。ネットワーク設定を触らず、publickey専用ガイドでユーザー・鍵・AuthorizedKeysFile・権限を修正します。
ホスト名だけ名前解決できないSSH設定ではなくDNS/hosts側の問題です。接続先名の誤りや名前解決設定を修正し、getent hostsで解決してからSSHを再試行します。
SSHログインは成功するSSH接続問題は解決済みです。実行コマンドやファイル操作で失敗する場合はOS権限・sudo・アプリ設定へ調査範囲を移します。
設定方法から確認したい場合:SSHの基本構成、公開鍵認証、sshd設定はSSH作業ガイドで整理しています。

修正後の再確認

変更後は、既存セッションを残したまま新しい端末から段階的に再確認します。

nc -vz example.com 22 ssh -vvv user@example.com

サーバー側ではssでLISTEN、sshd -tで構文、認証ログで拒否が消えたことを確認します。Firewallやsshd設定を変更した場合は、想定外の接続元まで許可していないことも再確認してください。

再発防止

CIDRの作業ガイドでは、接続元IPが許可ネットワークに含まれるか確認する考え方を整理しています。ファイル権限が原因の場合はLinux権限ガイドも参照してください。

接続元CIDRを確認

SSHを許可しているネットワーク範囲と実際の接続元IPが一致しているか、CIDR計算ツールで確認できます。

CIDRを確認