はじめに
AWS EC2で初めてAmazon Linux 2023ではなくUbuntuを使ってみました。
AL2023は通常サポートが2027年6月までで、次世代版(AL2025等)の発表もまだなかったので、長期サポートが確実なUbuntu 24.04 LTSに移ってみた次第です。
SSH接続のポート番号をデフォルトの22から変更しようとしたら、思いのほかハマりました。ssh.socketというものを知らなかったのが原因です。同じ状況で詰まっている方の参考になれば嬉しいです。
環境
| 項目 | 内容 |
|---|---|
| OS | Ubuntu 24.04 LTS (Noble Numbat) |
| インフラ | AWS EC2 |
| 変更前ポート | 22 |
| 変更後ポート | 2222(例) |
何が起きたか
sshd_configを変更しても新しいポートが開かなかった
まず /etc/ssh/sshd_config に Port 2222 を追加して ssh.service を再起動しました。
sudo nano /etc/ssh/sshd_config
# Port 2222 を追加
sudo systemctl restart ssh
ところが、ポート2222でSSH接続しようとしてもつながりません。ss で確認するとポート2222がListenされていませんでした。
$ ss -tulpn | grep ssh
tcp LISTEN 0 128 0.0.0.0:22 ...
ポート22は開いたまま。2222は開いていない。
原因:Ubuntu 24.04 はssh.socketがポートを管理している
調べてみると、Ubuntu 22.10 以降ではSSHにsystemdのソケットアクティベーションが採用されていました。
従来のLinuxでは sshd が起動時からポート22を自分で掴んで待ち続けます。ソケットアクティベーションでは、systemdが ssh.socket というユニットでポートを管理し、接続が来たときに初めて sshd プロセスを起動します。メモリ節約が目的のようです。
Ubuntu 22.10以降、openssh-serverはソケットベースのアクティベーションを採用しています。
— Ubuntu Community Hub
このため、sshd_config の Port を変更しても、ssh.socket 側の設定が22のままなのでポート22しか開きません。Ubuntu 24.04では daemon-reload を実行することでジェネレーターが sshd_config の設定を読み直してくれるのですが、当時はそれを知りませんでした。
ssh.socketを無効化した
「socketが邪魔してる」と思い、とりあえず ssh.socket を無効化して ssh.service を直接起動する方法に切り替えました。
sudo systemctl disable --now ssh.socket
sudo systemctl enable --now ssh.service
一旦ポートの変更に成功し、新しいポートでSSH接続できることを確認しました。
後日、SSH接続できなくなった
数日後、EC2インスタンスを再起動したらSSH接続がrefusedになりました。
ssh: connect to host xxx.xxx.xxx.xxx port 2222: Connection refused
サービスの状態を確認する手段もなく、詰まりました。
復旧:SSMセッションマネージャーを使う
EC2にはSSMセッションマネージャーという、SSH接続なしにシェルを開く手段があります。必要なのはIAMロールとSSMエージェント(Ubuntu公式AMIには最初から入っている)のみで、インバウンドポートを開ける必要がありません。
AWSコンソールから操作できます(EC2 → インスタンスを選択 → 接続 → セッションマネージャー)。
事前にIAMロール(AmazonSSMManagedInstanceCore ポリシー)をインスタンスにアタッチしておくだけで使えます。インスタンス起動後にアタッチした場合は再起動が必要です。
SSMで接続できるようになったら、セッションマネージャー経由でSSHサービスを有効化します。
sudo systemctl enable --now ssh.service
このコマンドによりシンボリックリンクも自動的に作成され、SSH接続が復旧しました。
正しいやり方:ssh.socketのポートを変更する
ssh.socket を無効化したことで sshd.service が再起動後に起動しなくなっていました。原因は /etc/systemd/system/ssh.service.d/00-socket.conf に BindsTo=ssh.socket という設定が残っていたためです。ssh.socket が停止すると ssh.service も停止する、という依存関係になっていたわけです。
素直に sshd_config でポートを変更して daemon-reload を実行するべきでした。
手順
# 1. sshd_configにポートを追加
sudo nano /etc/ssh/sshd_config
# Port 2222 を追加
# 2. ジェネレーターに設定を読み直させる
sudo systemctl daemon-reload
# 3. ssh.socketを再起動
sudo systemctl restart ssh.socket
# 4. 確認
ss -tulpn | grep ssh
daemon-reload を実行することで、systemdのジェネレーターが sshd_config の設定を読み直し、ssh.socket のListenポートが自動的に更新されます。
セキュリティグループも忘れずに
EC2の場合、セキュリティグループのインバウンドルールも変更が必要です。新しいポートを追加してSSH接続できることを確認してからポート22を閉じると安全です。
まとめ
| 操作 | 結果 |
|---|---|
sshd_config だけ変更して ssh.service 再起動 |
新しいポートが開かない(Ubuntu 24.04では daemon-reload が必要) |
ssh.socket を無効化 |
再起動後に ssh.service が起動しない |
ssh.socket のオーバーライドファイルでポートを変更 |
再起動後も正常動作する |
Ubuntu 24.04でSSHポートを変更するなら、sshd_config を変更 → systemctl daemon-reload → systemctl restart ssh.socket が最もシンプルな手順です。
おわりに
AL2023からUbuntuに移ってみたら早速ハマりました。ssh.socketの存在は知っておかないと詰まりやすいと思います。
EC2の設定変更時は事前にSSMセッションマネージャーが使える状態にしておくと、ロックアウト時の復旧が楽になります。今回の件でその重要性を実感しました。