Connection refused と Connection timed out は兄弟のように見えます。どちらも SSH がつながらなかったのですから。けれども両者は正反対の所見で、スタックの別々の半分を指しています。どちらを見ているのかが分かるだけで、診断コマンドを 1 つ打つ前に容疑者のリストが半分になります。これはその 2 分間の手順です。各エラーが何を証明するか、両者を他のすべてから切り分ける唯一のプローブ、そして分岐ごとのチェックリスト。(TCP 接続が成功した 後 に起きるエラー、つまり認証失敗、ホスト鍵の警告、死んでいくセッションについては、読み解きの早見表をご覧ください。)
| エラー | 証明すること | ありそうな原因 | 最初のコマンド |
|---|---|---|---|
Connection refused | ホストは起きていて、能動的に拒否した(RST が返ってきた) | そのポートで何も待ち受けていない、または REJECT のファイアウォールルール | コンソールから ss -tlnp | grep sshd |
Connection timed out | 何も返ってこなかった。経路上は沈黙 | IP が違う、ホストが落ちている、または静かな DROP(クラウドのセキュリティグループ/ファイアウォール) | nc -vz host 22、その後クラウドのファイアウォールを確認 |
各エラーが実際に証明すること
Connection refused は、マシンがあなたに応答したことを意味します。 あなたの TCP SYN が生きたホストに届き、ホストが能動的に拒否しました。RST パケットか ICMP の port-unreachable が返ってきたのです。これは意外なほど多くの朗報です。IP は正しく、経路は機能し、ホストは起きていて、経路上の何もあなたのパケットを食べていません。問題は狭い範囲です。そのポートで何も待ち受けていないか、ファイアウォールのルールがそれを(ドロップではなく)拒否している かです。
Connection timed out は沈黙を意味します。 あなたのパケットは出ていき、何ひとつ返ってきませんでした。これはサーバーについてほとんど何も証明しません。落ちているのかもしれず、IP が違うのかもしれず、あるいは(最も多いのは)あなたとサーバーの間の何かがパケットを黙って ドロップしている のかもしれません。クラウドのセキュリティグループ、DROP ポリシーのファイアウォール、NAT や VPN のブラックホールです。
覚え方を 1 つ。refused = マシンがあなたに話した。timed out = 一度も話さなかった。 refused はホストの問題。timed out はたいてい経路の問題です。
ステップ 1:ホストではなくポートをプローブする
最初の一手として ping は飛ばしてください。どちらの向きにも、見当違いのものを調べてしまいます。ping に応答するホストでも 22 番ポートはドロップしているかもしれず(クラウドのファイアウォールはポートごとにフィルタします)、ping を無視するホストでも SSH は元気に提供しているかもしれません(ICMP はあちこちでブロックされています)。ping は、あなたに必要なことを何も証明しません。
実際のポートをプローブします。
nc -vz example.com 22
(netcat がない? telnet example.com 22 で代用できます。SSH-2.0-... で始まる出力が出れば、sshd が応答したということです。)結果は 3 通り。
Connection refused。 下の refused の分岐へ。- 固まって、やがてタイムアウト。 timed-out の分岐へ。
- 成功。 TCP は問題なく、あなたの問題は SSH 自体の中にあります。ユーザーか鍵の誤り(
Permission denied (publickey)には専用のガイド(英語)があります)、ホスト鍵の不一致、あるいはssh -vがはっきり名指しする何か。
refused の分岐:何が待ち受けていない(いる)かを突き止める
マシンに入る別の手段が要ります。プロバイダーのウェブコンソールは、まさにこの瞬間のために存在しています。
sshd は動いているか?
systemctl status sshd # the unit is "ssh" on Debian/Ubuntu
死んでいるなら、ただ再起動するのではなく、なぜ かを確認してください。journalctl -u sshd(または -u ssh)が、どう終了したかを示します。よくある原因は、解析できない設定の編集です。sshd -t はファイルを検証し、同じ失敗へ再起動してしまう前に、問題の行を名指しします。
思っている場所で待ち受けているか?
sudo ss -tlnp | grep sshd
この出力には落とし穴が 2 つ隠れています。ポート。誰かが SSH を 2222 に移したのに、あなたは 22 を叩いている。ssh -p 2222 で接続し、二度と割り出さずに済むよう~/.ssh/config で(英語)ホストごとに固定します。アドレス。ListenAddress の行が sshd を 1 つのインターフェースに縛ることがあり、その場合はプライベート IP で応答し、パブリック IP では拒否します。
ローカルのファイアウォールが拒否しているか? sudo ufw status、sudo iptables -L -n、または nft list ruleset で、あなたのポートを覆う REJECT ルールを探します。REJECT ルールは、まさにこのエラーを生みます。ホストは起きていて、sshd すら待ち受けているかもしれないのに、ファイアウォールが代わりに応答するのです。
禁止されていないか? fail2ban の既定の動作は 拒否 なので、禁止はあなたの IP からだけ Connection refused に見えます。見分け方は、スマートフォンのテザリングからは動くのに、自分のネットワークからは動かないこと。コンソールから fail2ban-client status sshd、次に fail2ban-client unban <your-ip>。そして、禁止を招くほど誤った認証情報を繰り返した原因を直してください。
timed-out の分岐:パケットがどこで死ぬかを突き止める
まずアドレスを確認する。 これは一度だけ、きまりの悪い思いをします。ssh -v は、実際にダイヤルする IP を表示します。それをプロバイダーのダッシュボードと照合してください。移行後の古い DNS、インスタンス停止を生き延びなかった Elastic IP は、どちらも定番です。
次にクラウドのファイアウォールを確認する。たいていの場合、これが答えだからです。 セキュリティグループ(AWS)、NSG(Azure)、VPC のファイアウォールルール(GCP)は、既定で受信トラフィックをドロップします。しかも静かに、です。それがまさにタイムアウトの正体です。あなたのアドレスから TCP 22 を許可する受信ルールを探してください。ずるい変種は、数か月前に「My IP」に固定したルールで、以来あなたの IP が変わっているケースです。サブネットレベルのネットワーク ACL は、あまり見られない 2 つ目の層で、セキュリティグループが正しそうに見えるときには一見の価値があります。
クラウドのルールが問題なさそうなら、経路をたどります。
traceroute example.com # mtr example.com for a live view
sudo traceroute -T -p 22 example.com # TCP to the actual port — closest to the truth
素の traceroute は UDP か ICMP を使い、ファイアウォールはそれらを TCP 22 とは別に扱います。-T -p 22 の形は、SSH が実際に経験するものを試します。ホップが応答しなくなる場所が、おおよそあなたのパケットが死ぬ場所です。
自分側を疑う。 ホテル、カフェ、オフィスのゲストネットワークは日常的に送信 22 番をブロックし、企業の VPN はそれを経路変更したりドロップしたりします。切り分けのテストはスマートフォンのテザリングです。そこで SSH が動くなら、サーバーは問題なく、さっきまでいたネットワークが原因です。
ホスト自身の DROP ポリシーのファイアウォールは、外から見るとクラウド側のドロップと見分けがつきません。コンソールにアクセスできるなら、マシン上の iptables/nftables も確認してください。
風変わりなもの:ポートノッキング。 knockd を動かすサーバーは、他のポートへの秘密の接続試行の並びを見るまで、すべてをドロップします。前任者がマシンをセットアップしていて、どこからでもどのポートもタイムアウトするなら、経路の理屈に午後を 1 つ費やす前に、周りに聞いてみてください。
2 分版を覚えておく
手順全体はうまく圧縮できます。nc -vz でポートをプローブする。refused → コンソールから入り、sshd、待ち受けポート、REJECT ルール、fail2ban を確認。timed out → IP を確認し、クラウドのセキュリティグループを確認し、次に traceroute と自分のネットワーク。 ping はどこにも登場しません。
繰り返し出てくる事実(どのポートか、どのユーザーか、どのホストにキープアライブが要るか)は、あなたの記憶ではなく~/.ssh/config に(英語)置くべきものです。そして診断の一部は、障害のさなかの慌てた作業ではなく、常時そこにある状態にできます。Termalin は、保存した各ホストにポート、ユーザー、鍵、キープアライブの設定をひもづけて保存し、ホストごとにライブの状態を表示します。だから「そもそもマシンは起きているのか?」や「あのポートは何番だったか?」が、接続する前に分かり、2222 番でしか待ち受けないサーバーが、四半期ごとに再発見するものでなくなります。
Termalin は無料のクロスプラットフォーム SSH クライアントで、ホストごとのポート、ユーザー、鍵、キープアライブをホストとともに保持し、ライブのホスト状態を表示します。ダウンロード、または全機能一覧をご覧ください。