SSHのConnection refusedとtimed outの違いと対処法
SSHの「Connection refused」はサーバーが応答した証拠です。「Connection timed out」との原因の違いを、どこから何を確認すべきか具体的に解説します。
SSH で表示される「Connection refused」と「Connection timed out」の意味
SSH 接続の拒否と SSH 接続のタイムアウトは、正反対の障害です。一方の対処方法が、もう一方に有効とは限りません。拒否は、パケットがサーバーに到達し、サーバーのカーネルが「ここでは何も待ち受けていない」と応答したことを意味します。タイムアウトは、応答する相手にパケットが到達しなかったため、クライアントが待機を続けた後に処理を諦めたことを意味します。拒否はサーバー上のサービスの問題です。タイムアウトは、サーバーの手前にあるネットワーク経路の問題です。
クライアントが出力した正確な行を確認してください。表示内容だけで原因を特定できるためです。
ssh: connect to host 203.0.113.10 port 22: Connection refused
ssh: connect to host 203.0.113.10 port 22: Connection timed out応答時間も手掛かりになります。拒否は、通常は 1 往復にかかる時間程度で、すぐに返ります。タイムアウトは、クライアントが諦めるまで再送を続けるため、表示までに数秒以上かかります。同じ状態を macOS では Operation timed out と表示します。SSH の仕組み自体に不慣れな場合は、SSH の動作と sshd の役割が、このガイドの前提となる背景知識です。
「Connection refused」は朗報です
拒否は、TCP(transmission control protocol)のリセットです。クライアントはポート 22 に SYN パケットを送信します。パケットはインターネットを経由してサーバーのネットワークスタックに到達し、カーネルはそのポートで待ち受けているソケットを見つけられないため、RST(reset)パケットで応答します。SSH クライアントは、この RST を Connection refused というメッセージに変換します。
この 1 つの応答パケットから、多くのことが確認できます。アドレスは正しい状態です。ホストは稼働しており、ルーティングも機能しています。経路上で、そのポート宛てのトラフィックが黙って破棄されているわけでもありません。遠端から応答が返ってきているためです。つまり、残る原因候補はすべてサーバー自体にあります。
sshdが実行されていません。起動に失敗したか、自動起動が有効になっていないためです。sshdが別のポートで待ち受けています。通常は、セキュリティ強化の変更後に発生します。sshdがListenAddress 127.0.0.1など 1 つのアドレスにだけバインドされています。そのため、サーバー自身からしか接続できません。- ファイアウォールが drop ではなく reject に設定されています。この場合、ファイアウォールがホストの代わりに RST を送信します。ufw の
rejectアクションと、reject with tcp resetで終わる nftables ルールはいずれもこの動作をします。
もう 1 つ、これらと似ていて実際には異なるケースがあります。入力したアドレスが、別の稼働中のホストのものだった場合です。そのホストは SYN に応答しますが、ポート 22 で SSH を待ち受けていないため、接続を拒否します。誤ったサーバーを 1 時間調べる前に、アドレスを確認してください。Linux で待ち受けポートが実際に何を意味するかを理解しておくと、このセクションをより速く読み進められます。
接続拒否を解決する方法
これは SSH 経由では解決できません。壊れているのが SSH 自体だからです。プロバイダーの Web コンソールまたはシリアルコンソールを開いてサインインし、次のコマンドを順に実行します。
systemctl status ssh
sudo ss -tlnp
sudo sshd -T | grep -Ei '^(port|listenaddress|addressfamily)'systemctl status ssh は Ubuntu と Debian で unit 名を指定します。RHEL と AlmaLinux などの派生ディストリビューションでは、unit は sshd です。ss -tlnp は、待ち受け状態にあるすべての TCP ソケットと、それを所有するプロセスを一覧表示します。これは実際の状態を確認する基準です。設定ファイルの内容にかかわらず、sshd を示す行がなければ、何も待ち受けていません。sshd -T は、すべての Include ファイルを統合した後の有効な設定を出力します。/etc/ssh/sshd_config.d/ にポートの指定が残っている場合は、ここで確認できます。
アドレス列を注意して確認します。0.0.0.0:22 は、このサーバー上のすべての IPv4 アドレスを意味します。[::]:22 は、すべての IPv6 アドレスを意味します。127.0.0.1:22 は loopback のみを意味します。そのため、ローカルの ssh localhost は正常に動作しても、リモートからの接続はすべて拒否されます。
何も待ち受けていない場合は、サービスを起動し、起動できない場合はそのエラーを確認します。
sudo sshd -t
sudo systemctl enable --now ssh
sudo journalctl -u ssh -n 50 --no-pagersshd -t は設定を解析し、問題のあるディレクティブのファイル名と行番号を出力します。実行中のサービスには変更を加えません。再起動する前には必ず実行してください。設定が拒否されると、sshd は起動時に終了し、次の接続が拒否されるためです。
Ubuntu におけるソケットアクティベーションの落とし穴
Ubuntu 24.04 には、OpenSSH 用の systemd socket unit が含まれています。この unit が有効な場合、systemd が待ち受けポートを保持し、接続ごとに sshd を起動します。そのため、sshd_config 内の Port 2222 を変更しても何も変わらず、サーバーは古いポートで応答し続けます。編集する前に、自分の環境がどちらのモードか確認してください。
systemctl is-enabled ssh.socket
systemctl status ssh.socketsocket が有効な場合は、sshd_config ではなく socket unit でポートを設定します。
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222空の ListenStream= 行は必須です。systemd のリスト設定は、既存の設定に追加されるためです。この行を省くと、サーバーは両方のポートで待ち受けます。sudo systemctl daemon-reload と sudo systemctl restart ssh.socket で変更を適用し、sudo ss -tlnp で新しいポートが保持されていることを確認してください。ポートの変更は VPS 上の SSH のセキュリティ強化で通常行う手順ですが、接続不能になる原因として最も多い手順でもあります。
「Connection timed out」は応答がなかったことを意味します
タイムアウトは無応答です。クライアントは SYN を送信し、1、2 分にわたって何度も再送しましたが、返答パケットを 1 つも受信できませんでした。ここからサーバーの状態は判断できません。サーバーから何も返ってきていないためです。
無応答は、DROP ルールが生成する状態そのものです。パケットの破棄は意図的な動作です。拒否すると、スキャンしている側にホストの存在を知らせてしまいます。そのため、ufw や各クラウドプロバイダーのネットワークファイアウォールは不要なパケットを破棄し、何も返しません。今回のタイムアウトは通常、開放したはずのポートでファイアウォールが正常に動作していることを示します。
- アドレスが誤っています。再構築したサーバーを指したままの DNS レコードや、誰も使用していないアドレスに到達する入力ミスが考えられます。
- ホストが稼働していません。電源が切れているか、再起動の途中です。料金未払いによるプロバイダーの利用停止も、外部からは同じように見えます。
- ホストのファイアウォールが port 22 を破棄しています。多くの場合、allow ルールを追加する前に
ufw enableを実行したことが原因です。 - インスタンスの前段にあるプロバイダーのファイアウォールがパケットを破棄しています。この場合、オペレーティングシステムはパケットをまったく認識しません。
- 使用しているネットワークが outbound port 22 をブロックしています。オフィスやホテルの接続ではよくあります。
接続の適切な側からテストを実行する
最も多くの時間を浪費するのが、この誤りです。パケットが到達していないサーバー内部から、パケットのドロップを診断することはできません。コマンドを実行するためにログインできるなら、そもそも問題は発生していません。このセクションのコマンドはすべて、自分のマシンで実行します。
getent hosts vps.example.com
ssh -G vps.example.com | grep -Ei '^(hostname|port|user)'
ssh -vvv -o ConnectTimeout=10 user@vps.example.com
nc -vz -w 5 203.0.113.10 22getent hosts は、実際にマシンが使用するアドレスを表示します。これにより、古い DNS レコードを数秒で見つけられます。ssh -G は、~/.ssh/config を読み込んだ後にクライアントが適用する設定を表示します。そのため、ホスト名、ポート、ユーザーを静かに書き換える古い Host ブロックを検出できます。ssh -vvv は、接続試行がどこまで進んだかを示します。アドレスへの接続に関する最後の行の後に長い停止がある場合はタイムアウトです。一方、リモートの OpenSSH バージョンを示す行が表示される場合は TCP 接続がすでに成功しており、実際の問題は認証です。Windows では、PowerShell の Test-NetConnection 203.0.113.10 -Port 22 が nc の代わりになります。
ホストではなく、ポートをテストします。ping が失敗しても、何も証明できません。多くのプロバイダーは、ネットワークの境界で ICMP(internet control message protocol)をフィルタリングしているためです。ping が成功しても、やはり何も証明できません。ポート 22 については何も分からないためです。
次に、どのコマンドでも変更できない 1 つの変数、ネットワークを変更します。スマートフォンのテザリング経由で再試行してください。テザリング経由では接続でき、デスクのネットワークからは接続できない場合、ブロックはインターネット側の自分のネットワークにあります。または、オフィスのアドレスがサーバーで拒否されています。
サーバーからは見えないプロバイダー側ファイアウォール
ほとんどの VPS パネルには、ネットワークファイアウォールがあります。これはセキュリティグループやクラウドファイアウォールと呼ばれることもあります。インスタンスより上流で動作し、独自のルール一覧を保持します。サーバー上の ufw status からはこのファイアウォールを確認できません。そのため、「ポート 22 はすでに許可したはずだ」という状況がよく発生します。サーバー上のルールを 1 つでも書き換える前に、パネルを開いてこの一覧を確認してください。
この問題は、1 つのコマンドで切り分けられます。ただし、コンソールアクセスが必要です。サーバー上でコマンドを開始し、実行中にラップトップから接続を試みます。
sudo tcpdump -ni any tcp port 22クライアントが接続を試みている間に何も表示されない場合、パケットはオペレーティングシステムに到達する前に破棄されています。原因はプロバイダー側ファイアウォールか、ホストまでの経路です。SYN パケットが到着しているのに応答が送信されない場合、ローカルで破棄されています。原因は ufw または nftables です。この 1 回のテストで、タイムアウトの原因を半分に絞り込めます。そのため、コンソールへアクセスして実行する価値があります。
ufw の順序、IPv6、そして自分で設定した ban
ufw の順序を誤ると、この中で最も多くの利用者を締め出すことになります。sudo ufw enable は受信のデフォルトポリシーを直ちに deny に設定するため、SSH ルールがない状態では、現在のセッションは確立済み接続として維持されますが、新しい接続はすべてタイムアウトします。先に許可し、その後で有効化します。
sudo ufw allow OpenSSH
sudo ufw status verboseOpenSSH の application profile が対象とするのは port 22 だけです。SSH を 2222 に移す予定がある場合は、必要なルール sudo ufw allow 2222/tcp を port の変更前に追加します。変更後に追加してはいけません。より広いルールセットについては VPS の ufw firewall の基本 を、設定の安全な順序については 新しい VPS の最初の 10 分間に行うこと を参照してください。
IPv6 では、原因が分かりにくい timeout が発生します。hostname に AAAA record がある場合、client は最初に IPv6 を試します。そのため、server の IPv6 rules が不足していると接続が停止しますが、通常の IPv4 接続は成功します。2 つを手動で分けて確認してください。
ssh -4 user@vps.example.com
ssh -6 user@vps.example.com-4 は接続できて -6 は接続できない場合、修正すべき箇所は server の IPv6 rules です。ufw で IPv6 に同じ port を開放する方法 で手順を説明しています。
自分で ban している可能性もあります。fail2ban は authentication log を監視し、認証に繰り返し失敗する address に対する firewall rule を追加します。そのため、誤った key やバックグラウンドで再試行を続ける script によって、office 全体の address が締め出されることがあります。drop する ban は timeout のように見えます。reject する ban の場合は、代わりに No route to host が返ります。console から実行します。
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 198.51.100.24自分の address を ignoreip に追加する手順は、Ubuntu 24.04 で fail2ban を正しく設定する方法 に含まれています。
拒否もタイムアウトも発生しないエラー
No route to host は、ICMP 到達不能メッセージが返されたことを示します。自分のマシンにそのネットワークへの経路がないか、経路上の何かが管理上の拒否を返しています。後者は iptables の REJECT ルールが送信する応答です。
Network is unreachable は、自分のマシンが返していることを示します。そのアドレスファミリーへの経路がまったくありません。IPv4 のみの接続で、ホスト名が IPv6 アドレスにしか解決されない場合によく発生します。
kex_exchange_identification: Connection closed by remote host は、TCP 接続は確立したものの、鍵交換が完了する前にサーバーが切断したことを示します。ポートは開いており sshd も稼働しているため、サーバーの負荷、MaxStartups、または接続中に適用された ban を確認します。
Permission denied (publickey) は、認証処理まで到達したものの、そこで失敗したことを示します。ネットワークとファイアウォールには問題がないため、このガイドの内容は適用されません。SSH で Permission denied (publickey) を解決する を参照してください。
再接続する方法と、2 回目のロックアウトを防ぐ方法
すべての主要な VPS ホストには、ゲストのネットワークに依存しないコンソールがあります。シリアルコンソール、またはブラウザベースの VNC 画面です。このガイドのどちらの分岐でも、このコンソールが復旧経路になります。sshd が停止している場合も、ファイアウォールルールがすべての通信を破棄している場合も機能するためです。管理パネルでコンソールを開き、root または通常のユーザーでログインして、上記の確認を実行してください。root パスワードを設定していない場合でも、多くの管理パネルではパスワードをリセットできます。
コンソールがない場合は、プロバイダーの rescue mode が代替手段になります。小さな復旧システムを起動してディスクをマウントするため、オフラインで /etc/ssh/sshd_config を編集したり、ファイアウォールルールを削除したりしてから再起動できます。
次のロックアウトを防ぐには、2 つの習慣が役立ちます。sshd またはファイアウォールを編集するときは、2 つ目の SSH セッションを開いたままにしてください。新しい接続をテストしている間も、確立済みの状態によりそのセッションは維持されます。また、ファイアウォールを変更する前に、自動的に元に戻す仕組みを用意してください。
sudo systemd-run --unit=ufw-rollback --on-active=10min /usr/sbin/ufw disable
sudo systemctl stop ufw-rollback.timer1 行目は、10 分後に ufw 自身を無効にする処理を予約します。新しいルールを適用し、新しい SSH セッションを開いて動作を確認してから、2 行目を実行してロールバックをキャンセルします。誤ってロックアウトされた場合は、10 分待つとファイアウォールが自動的に停止します。ufw を再度有効にするまでサーバーはフィルタリングされない状態になるため、キーボードの前で作業しているときに使用し、恒久的な設定にはしないでください。
作業する順序
- エラーメッセージを読み、表示されるまでにかかった時間を確認します。
- 「Refused」の場合: コンソールに移動し、
sudo ss -tlnpで待ち受けソケット、そのポート、バインド先アドレスを確認します。 - 「Timed out」の場合: 自分のマシンからアドレスを確認し、次にパネルのプロバイダーファイアウォール、最後にサーバー上のホストファイアウォールを確認します。
- どちらの文字列でもない場合: すでに TCP 接続が確立しています。ネットワークの問題ではなく、認証またはサーバー負荷の問題として扱います。
FAQ
SSH を実行中の sshd があるのに「Connection refused」と表示されるのはなぜですか?
拒否はサービスではなくソケットから返されるためです。sshd が実行中でも、接続は拒否されることがあります。プロバイダーのコンソールを開き、sudo ss -tlnp を実行します。127.0.0.1:22 のソケットは loopback のみにバインドされているため、すべてのリモートクライアントを拒否します。別のポートで待ち受けているソケットは、22 番ポートを使い続けているすべての接続元を拒否します。systemd の socket activation を使用している場合、ポートは sshd_config ではなく ssh.socket から決まるため、systemctl is-enabled ssh.socket も確認します。ufw の reject ルールもホストに代わって拒否を返すため、判断する前に sudo ufw status verbose を確認してください。
ufw でポート 22 を許可しているのに SSH がタイムアウトするのはなぜですか?
タイムアウトは応答が返ってこなかったことを意味し、経路上にあるファイアウォールは ufw だけではないためです。多くの VPS パネルはインスタンスの前段でネットワークファイアウォールを実行しており、そのファイアウォールが破棄した通信はオペレーティングシステムに届きません。コンソールから sudo tcpdump -ni any tcp port 22 を実行し、その実行中にラップトップから接続を試します。到着するパケットがなければ、パネル側の上流で破棄されています。パケットは到着しているのに応答が送信されなければ、ufw または nftables によってローカルで破棄されています。
ping に失敗すると、VPS が停止しているということですか?
いいえ。多くのプロバイダーはネットワーク境界で ICMP をフィルタリングするため、正常に通信を提供しているサーバーでも、送信した ping をすべて無視できます。逆に、ping が成功しても判断材料としては不十分です。ポート 22 が開いているかどうかは分からないためです。自分のマシンから nc -vz -w 5 203.0.113.10 22 でポート自体をテストするか、Windows の PowerShell で Test-NetConnection 203.0.113.10 -Port 22 を実行してください。
SSH のポートを変更したら、接続できなくなりました。何が問題ですか?
順序に関する原因が 2 つあります。ファイアウォールに新しいポートのルールを追加していない場合、新しいポートへの接続はタイムアウトし、ポート 22 への接続は拒否されます。そのため sudo ufw allow 2222/tcp はポート変更の後ではなく、前に実行する必要があります。ホストが SSH に systemd の socket activation を使用している場合、sshd_config 内の Port 2222 は無視され、systemd は古いポートを保持し続けます。これは systemctl is-enabled ssh.socket で確認できます。プロバイダーのコンソールから復旧し、該当する原因を修正してください。その後、sudo ss -tlnp に新しいソケットが表示されたら、ssh -p 2222 user@203.0.113.10 で接続します。