Table of Contents
はじめに
Ubuntu 24.04 で SSH ポートを変更したら、UFW ではちゃんとポートが開いているのに接続が「Connection refused」になる現象にハマったので、原因と対処をメモします。
発生した現象
やりたかったことは「SSH の待ち受けポートを 22 から 1000(例) に変える」だけです。
- OS: Ubuntu 24.04 LTS
- UFW で 22 と 1000 を許可済み
UFW の設定は以下の通り。
sudo ufw status numbered
Status: active
To Action From -- ------ ----[ 1] 22 ALLOW IN Anywhere[ 2] 1000 ALLOW IN Anywhere/etc/ssh/sshd_config には次のように書いてあります。
Port 1000この状態でクライアントから、
ssh -p 1000 user@example.comと叩くと「Connection refused」。一方で22番に対しては普通に接続できる状態でした。
切り分け:本当に1000でlistenしているか?
まず、サーバ側でSSHデーモンがどのポートをlistenしているか確認します。
sudo ss -tlnp | grep ssh結果:
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=28580,fd=3),("systemd",pid=1,fd=112))LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=28580,fd=4),("systemd",pid=1,fd=113))22番しかlistenしていません。
つまり「UFWでは1000を開けているけど、そもそもSSHサーバが1000で待ち受けていない」という状態です。
sshd_config の設定も念のため確認します。
sudo grep -i '^Port' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null
/etc/ssh/sshd_config:Port 1000設定ファイルには1000と書いてあるのに、実際のプロセスは22番しかlistenしていない、という矛盾が起きています。
原因:Ubuntu 24.04のSSHはsystemdの「socket activation」で動いている
Ubuntu 22.10以降のOpenSSHは、標準でsystemdのsocket-based activationで動作するように変更されています。
ポイントだけ書くと、
sshd自身がポートを開いて待つのではなく、systemdのssh.socketがポート22をlisten する- 接続が来たタイミングで
ssh.socketがssh.serviceを起動し、接続を渡す - Ubuntu 24.04では、
sshd_configのPort設定を systemd が動的に解釈する仕組みだが、ケースによっては期待通りに反映されず、「設定は1000と書いてあるのに、実際は22でしか待ち受けていない」という状態になることがある
そのため、単に、
sudo vi /etc/ssh/sshd_configsudo systemctl restart sshのような「従来のやり方」だけでは、ポート変更が反映されない場合があります。
対処方針
この記事では、以下のどちらかの方針を取ることを想定します。
22を残したまま1000を追加したい(段階的に移行したい人向け)systemdのsocket activationをやめて、従来どおりssh.serviceだけで動かしたい
いきなり 22 を閉じるとロックアウトリスクがあるので、まずは 1 をおすすめします。
手順 1: 22 と 1000 の両方で待ち受けるようにする
1-1. sshd_config で複数ポートを指定する
/etc/ssh/sshd_configに複数行でポートを指定します。
Port 22Port 1000Ubuntu 24.04では、Portの設定はsystemd側のgeneratorによって解釈され、ssh.socketのListenポートに反映される設計になっています。
1-2. 設定の構文チェック
sudo sshd -tエラーが何も出なければ OK です。
1-3. systemd に設定を反映させる
Ubuntu24.04の場合、socket activationを使っているので、ssh.serviceではなくssh.socketを再起動する必要があります。
sudo systemctl daemon-reloadsudo systemctl restart ssh.socket必要に応じてサービスも再起動
sudo systemctl restart ssh.service1-4. 本当に両方で listen しているか確認
sudo ss -tlnp | grep ssh期待する形
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",...),("systemd",...))LISTEN 0 4096 0.0.0.0:1000 0.0.0.0:* users:(("sshd",...),("systemd",...))LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",...),("systemd",...))LISTEN 0 4096 [::]:1000 [::]:* users:(("sshd",...),("systemd",...))ここまで来て初めて、クライアントから:
ssh -p 1000 user@example.comで接続が通るようになります。
手順 2: socket activation をやめて従来型の ssh.service のみに戻す
「この挙動がややこしいので、昔ながらの『sshdが自分でポート開いて常駐する』方式に戻したい」という場合は、socket activationを無効化することもできます。
2-1. ssh.socket を止める
sudo systemctl disable --now ssh.socket2-2. ssh.service を有効化して起動
sudo systemctl enable --now ssh.serviceこれで、Ubuntu 20.04などと同じように「sshdが直接ポートをlistenして起動する」形に戻ります。
以降は、従来どおり、
/etc/ssh/sshd_configのPort設定を書き換えるsudo sshd -tで構文チェックsudo systemctl restart sshで再起動
という流れでポート変更が反映されます。
2-3. listen ポート確認
sudo ss -tlnp | grep sshこの時点で、
LISTEN 0 4096 0.0.0.0:1000 0.0.0.0:* users:(("sshd",pid=...,fd=3))LISTEN 0 4096 [::]:1000 [::]:* users:(("sshd",pid=...,fd=4))のようにsystemdのPID ではなくsshdだけが見える状態になっていれば OK です。
UFW の設定も忘れずに
UFW の設定は最初から正しかったのですが、手順としては以下のようにしておくと安全です。
# SSH 旧ポート(22)を一旦開けるsudo ufw allow 22/tcp
# 新ポート(例: 1000)を許可sudo ufw allow 1000/tcp
# 状態確認sudo ufw status numbered最終的に22を閉じる場合は、必ず「新ポートで SSH ログインできることを確認してから」ルールを削除します。
sudo ufw delete 1 # ルール番号は環境に合わせて今回ハマりポイントのまとめ
- UFW のルールは正しくても、「そのポートで SSH サーバが listen していなければ」当然接続は拒否される
- Ubuntu 24.04 の OpenSSH はデフォルトで socket-based activation になっているため、従来の「sshd_config を直して ssh.service を再起動」だけではポート変更が反映されないケースがある
- 対処方法は大きく2つ
- sshd_config に複数ポートを指定した上で
ssh.socketを再起動する - そもそも socket activation を無効化して、ssh.service で従来どおり動かす
- sshd_config に複数ポートを指定した上で
Ubuntu 24.04 で SSH のポート変更がうまくいかず、「UFW も開いているのに Connection refused」という状況にハマった方の参考になれば幸いです。