エラーの概要
いつものようにSSHコマンドを実行すると、次のエラーが表示されます:
$ ssh user@192.168.1.100
ssh: connect to host 192.168.1.100 port 22: Connection refused
タイムアウトもなく、パスワードのプロンプトも出ない — ただちに接続が拒否されます。サーバーはpingには応答するのに、SSHは完全にシャットアウトされます。この即時拒否は実は重要な手がかりです。OSが能動的に接続を拒否しているということは、原因が次の3つのいずれかに絞られます:sshdが起動していない、ファイアウォールがポート22をブロックしている、またはSSHが非標準ポートに移動されている、のいずれかです。
まず診断する
やみくもに設定を変更するのは禁物です。クライアント側から2つのクイックチェックを行うだけで、多くのことがわかります:
# ポート22が開いているか確認する
nc -zv 192.168.1.100 22
# ncが使えない場合はnmapを使う
nmap -p 22 192.168.1.100
ncからConnection refusedが返ってきた場合、ポートが能動的に閉じられています — OSがTCP RSTパケットを送り返しています。これはパケットを静かにドロップするケース(タイムアウトが発生する)とは異なります。パケットをサイレントにドロップするファイアウォールの場合は、あきらめるまで30〜60秒かかります。即時拒否の場合は別の原因があります。
サーバーへのコンソールまたはVNCアクセスがある場合は、以下も実行してください:
# ポート22でリッスンしているものを確認する
ss -tlnp | grep 22
# 古いシステムの場合
netstat -tlnp | grep 22
修正1:SSHデーモンが起動していない
ほとんどの場合、これが原因です。sshdサービスがクラッシュしていた、一度も有効化されていなかった、または設定変更後にサイレントで失敗していたケースです。
# サービスのステータスを確認する
sudo systemctl status sshd
# ディストリビューションによってはsshdではなくsshという名前の場合もある
sudo systemctl status ssh
inactiveまたはfailedと表示された場合は、起動します:
# すぐに起動する
sudo systemctl start sshd
# 再起動後も有効になるよう設定する
sudo systemctl enable sshd
サービスの起動を拒否された場合は、ログに原因が記録されています:
sudo journalctl -u sshd -n 50 --no-pager
よくある原因:/etc/ssh/sshd_configのタイポ、ホストキーの欠落(移行に失敗した場合によく起こります)、またはポート22を既に使用している別のプロセスです。根本的な問題を修正してから、サービスを再起動してください。
修正2:ファイアウォールがポート22をブロックしている
sshdが正常に動作していても、ファイアウォールルールがすべての着信接続を静かにブロックすることがあります。まずファイアウォールを確認しましょう。
UFW(Ubuntu/Debian)
# 現在のルールを確認する
sudo ufw status
# SSHを許可する
sudo ufw allow ssh
# またはポートを明示的に指定する
sudo ufw allow 22/tcp
firewalld(CentOS/RHEL/Fedora)
# SSHサービスが許可されているか確認する
sudo firewall-cmd --list-services
# SSHを永続的に追加する
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
iptables(直接ルール設定)
# 既存のルールを確認する
sudo iptables -L INPUT -n -v
# ポート22を許可する
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# ルールを保存する(Debian/Ubuntu)
sudo iptables-save | sudo tee /etc/iptables/rules.v4
修正3:SSHが別のポートでリッスンしている
セキュリティを強化した多くのサーバーでは、自動スキャナーのノイズを減らすためにSSHをポート22以外に移動しています。ポート2222がよく使われる代替ポートです。sshdが実際に使用しているポートを確認しましょう:
# 設定されているポートを確認する(サーバー上で実行する)
sudo grep -i ^Port /etc/ssh/sshd_config
出力がない場合は、デフォルトのポート22を引き続き使用しています。別の番号が表示された場合は、-pオプションで接続します:
ssh -p 2222 user@192.168.1.100
毎回ポートを入力するのが面倒な場合は、クライアントの~/.ssh/configにホストエントリを追加しましょう:
Host myserver
HostName 192.168.1.100
User user
Port 2222
これでssh myserverと入力するだけで接続できます。
修正4:サーバーにSSHがインストールされていない
新規コンテナや最小構成のサーバーインストールでは、OpenSSHが省略されていることがよくあります。他に原因が見当たらない場合は、確認する価値があります。
# Debian/Ubuntu
sudo apt update && sudo apt install openssh-server -y
# CentOS/RHEL
sudo dnf install openssh-server -y
# 一度に起動と有効化を行う
sudo systemctl enable --now sshd
確認方法
修正を適用した後、SSHを試す前にポート22が接続を受け付けているか確認してください:
# クライアントから実行する
nc -zv 192.168.1.100 22
# 期待される出力: Connection to 192.168.1.100 22 port [tcp/ssh] succeeded!
# 次にSSHを試す
ssh user@192.168.1.100
サーバー側でsshdが実際にポートにバインドされているか確認します:
ss -tlnp | grep sshd
# 次のような出力が表示されるはずです: LISTEN 0 128 0.0.0.0:22 ...
補足tips
- クラウドVM(AWS/GCP/Azure):OS内のファイアウォールだけが唯一の防御層ではありません。セキュリティグループやネットワークACLはVM外部に存在しており、クラウドレベルでポート22がブロックされると、UFWやiptablesの設定に関わらず全く同じエラーが発生します。必ず両方のレイヤーを確認してください。
- fail2banによるブロック? 最近ログイン試行に失敗が続いた場合、fail2banなどのツールが自動的にあなたのIPをブロックしている可能性があります。
sudo fail2ban-client status sshdで確認してください。IPがブロックリストにある場合は解除します:sudo fail2ban-client set sshd unbanip YOUR_IP - ネットワーク設計:サブネットやVPNをまたいでSSHアクセスを設定する場合、ホワイトリストに登録するCIDR範囲の計算が面倒になることがあります。ToolCraftのサブネット計算ツールを使えば、ブラウザ上で計算できます — インストール不要です。

