まえがき
近年、セキュリティと効率のバランスを取るために、多くのシステム管理者がSSHの設定方法を見直し、カスタマイズを進めています。この記事では、Ubuntuの最新バージョンにおけるSSHの設定と管理方法について、わかりやすく説明します。特に、Ubuntu 22.10で導入され、Ubuntu 24.04でデフォルトとなったssh.socketの使い方に焦点を当て、セキュリティを強化するための一例として、SSHポートの変更方法にも触れます。これにより、いかにしてセキュリティを強化しつつ効率的にシステムを運用できるかをお伝えします。
この記事は、システム管理者やノードオペレーター、SSHのカスタマイズに関心がある技術者の皆さんに向けて書かれています。旧来の手法と新しいアプローチを比較しながら、最新の技術がどのように問題解決に役立ち、新たな可能性をもたらすかを探ります。実際のコマンド例を交えて、ポート変更を含む、理論から実践へとステップを踏む過程を丁寧に解説します。
このガイドを通じて、皆さんがSSHの設定を最適化し、より安全かつ効率的なシステム環境を築く手助けができれば幸いです。まずは基本からしっかり学び、安全なネットワーク管理への第一歩を一緒に踏み出しましょう。
1. Ubuntu 22.10からの変化
ssh.serviceとssh.socketの導入とその影響
Ubuntu 22.10以降では、ssh.socket
とssh.service
がデフォルトで導入され、システムのSSHサービスの管理に新たなアプローチが採用されています。ここでは、それぞれの役割と、これまでのssh.service
のみを使用していた方法との比較を簡単にまとめます。
ssh.serviceについて
-
役割:
ssh.service
はOpenSSHサーバー (sshd
) のサービスユニットで、システム起動時や手動でのコマンドによってSSHサーバーを直接起動します。 -
従来の方法: Ubuntu 22.10以前では、主に
ssh.service
が用いられ、SSHサーバーが常時実行される設定が一般的でした。この方法では、SSHサーバーがシステム起動時に自動的に開始され、継続的にリソースを消費する可能性がありました。
ssh.socketについて
-
役割:
ssh.socket
はソケットベースのアクティベーションを利用してSSHサーバーを管理するためのソケットユニットです。特定のポート(デフォルトは22番ポート)での接続要求をリッスンし、要求があった場合にのみssh.service
を起動します。 -
新しいアプローチ: Ubuntu 22.10以降では、
ssh.socket
がデフォルトで利用されるようになりました。この設定により、SSHサービスは要求があるまで実際には起動せず、リソースの無駄遣いを防ぎながらセキュリティを維持することができます。接続要求がない限り、SSHサーバーは起動しないため、不必要なリソースの使用を削減し、システムの全体的な効率を向上させます。
比較とメリット
-
効率性:
ssh.socket
の採用により、SSHサーバーが動作するのは実際に必要な時のみとなり、リソースの節約が図られます。これにより、サーバーのパフォーマンスが向上し、低リソース環境での運用が容易になります。 - セキュリティ: 接続要求がある場合のみSSHサービスが起動するため、不要な外部からのアクセスポイントが減少し、セキュリティが向上します。
-
応答性:
ssh.socket
は接続要求を即座に捉え、必要に応じてssh.service
を起動するため、ユーザーの体感速度は改善されます。
Ubuntu 22.10以降のこの変更は、システムの保守管理をより柔軟で効率的なものにし、多くのユーザーにとっての利便性を高めるものとなっています。
以下のようにまとめます。
-
Ubuntu 20.04 以前:
ssh.service
のみがデフォルトで有効。SSH サーバーは常に起動しており、ソケットアクティベーションは利用されていません。 -
Ubuntu 22.04 LTS:
ssh.service
が引き続きデフォルトで有効となっており、ssh.socket
は無効です。SSH サーバーは従来通り常時稼働する設定で、ソケットアクティベーションは導入されていません。 -
Ubuntu 22.10 以降:
ssh.socket
がデフォルトで有効となり、SSH サーバーはソケットアクティベーションで管理されるように変更されました。SSH 接続要求があるときにのみssh.socket
によりssh.service
が起動する仕組みに変わり、常時稼働しない設定が標準です。
Ubuntu バージョン | ssh.service | ssh.socket | 動作 |
---|---|---|---|
20.04 および以前 | デフォルトで有効 | 未使用 | SSHサーバーは常に稼働 |
22.04 LTS | デフォルトで有効 | 無効 | SSHサーバーは常に稼働 |
22.10 および以降 | ssh.socket によって管理される | デフォルトで有効(ソケットアクティベーション) | SSHサーバーは要求時に起動(ソケットアクティベーション) |
これにより、22.10 以降は効率的なリソース管理が可能になり、必要なときだけ SSH サービスが起動するようになっています。
2. ssh.socket コマンド
これらのコマンドはすべて関連しており、以下の表に各コマンドの説明を簡潔にまとめました。
コマンド | 説明 |
---|---|
sudo systemctl status ssh.socket | ssh.socketユニットの現在の状態を表示します。 |
sudo systemctl enable ssh.socket | システム起動時にssh.socketユニットが自動的に起動するように設定します。 |
sudo systemctl disable ssh.socket | システム起動時のssh.socketユニットの自動起動を無効にします。 |
sudo systemctl start ssh.socket | ssh.socketユニットを直ちに起動します。 |
sudo systemctl restart ssh.socket | ssh.socketユニットを停止してから再起動します。 |
これらのコマンドを使用して、SSHサービスのsocketベースのアクティベーションを管理することができます。
3. 旧方式設定 - Ubuntu22.04以前
- Ubuntu22.04以前のデフォルト
-
ssh.service
のみ使用し、ssh.socket
は不使用 -
ssh.service
は、/etc/ssh/sshd_config
を編集
Ubuntu22.04以前までは、この設定方法がデフォルトになっています。ただしUbuntu24.04ではssh.socket
がデフォルトでアクティブになっています。旧方式で進めたい場合は、以下の手順を踏みます。また、すでにUbuntu22.10以降を使っており、これからsshポートを変更したい場合は、4. 新方式設定 - Ubuntu20.10以降
へ進んでください。
3-1. ssh.serviceの設定
-
/etc/ssh/sshd_config
を編集
sudo nano /etc/ssh/sshd_config
- 使いたいSSHPortを追加する。ここでは
31425
とする - 必要ならユーザーも追加する
Port 31425 # Port 22 から別のものに変更する
AllowUsers Doraemon
-
Control+X
→Y
→Enterキー
で保存 -
ssh.service
を再起動
sudo systemctl restart ssh
# sudo service ssh restart でもよい
3-2. ssh.socketの設定
- ssh.socketの現状確認
sudo systemctl status ssh.socket
- アクティブになっている場合は、ssh.socketを止める
sudo systemctl stop ssh.socket
- ssh.socketを無効にする
sudo systemctl disable ssh.socket
使えるようにするためには、
- ssh.socketを使用可能にする
sudo systemctl enable ssh.socket
- ssh.socketをアクティブにする
sudo systemctl start ssh.socket
- 確認
sudo systemctl status ssh.socket
- Portの確認
sudo netstat -tuln | grep 31425
4. 新方式設定 - Ubuntu22.10以降
- Ubuntu22.10以降のデフォルト
ssh.service
もssh.socket
も両方使用-
ssh.service
は、/etc/ssh/sshd_config
を編集 -
ssh.socket
は、/lib/systemd/system/ssh.socket
を編集
4-1. ssh.serviceの設定
- 先に
/etc/ssh/sshd_config
を編集しておく
sudo nano /etc/ssh/sshd_config
- 使いたいSSHPortを追加する。ここでは
31425
とする - 必要ならユーザーも追加する
Port 31425 # Port 22 から別のものに変更する
AllowUsers Doraemon
-
Control+X
→Y
→Enterキー
で保存 -
ssh.service
を再起動
sudo systemctl restart ssh
# sudo service ssh restart でもよい
"/etc/ssh/sshd_config.d/*.conf" とは
/etc/ssh/sshd_config.d/
ディレクトリにconfigファイル(設定ファイル)があります。
/etc/ssh/sshd_config.d/
ディレクトリ内の設定ファイルは、通常の/etc/ssh/sshd_config
ファイルと組み合わせて読み込まれます。しかし、優先順位の観点では、次のルールが適用されます。
-
/etc/ssh/sshd_config
がメインの設定ファイルです。このファイルが最初に読み込まれます。 -
/etc/ssh/sshd_config.d/
ディレクトリ内のファイルは、sshd_config
ファイルの後に読み込まれます。そのため、同じ設定項目が重複している場合は、sshd_config.d/
内の設定が優先されます。
これにより、sshd_config
ファイルの基本設定を保ちつつ、必要に応じてsshd_config.d/
ディレクトリ内のファイルで特定の設定を上書きすることができます。
例えば、以下のような状況を考えます。
-
/etc/ssh/sshd_config
でポート22が指定されている。 -
/etc/ssh/sshd_config.d/custom.conf
でポート2222が指定されている。
この場合、SSHはポート2222でリッスンします。これはsshd_config.d/
内の設定がsshd_config
内の設定を上書きするからです。
また、sshd_config.d/
内の設定ファイルはアルファベット順に読み込まれるため、同じディレクトリ内のファイルで設定が競合する場合も、後に読み込まれたファイルの設定が適用されます。
まとめると、sshd_config.d/
ディレクトリ内のファイルはsshd_config
の後に読み込まれ、設定が重複している場合には**sshd_config.d/
内のファイルの設定が優先される**という仕組みです。
そして/etc/ssh/sshd_config
ファイルには、次のような行があります。
Include /etc/ssh/sshd_config.d/*.conf
この行が重要な役割を果たしており、コメントアウトするかどうかによって、/etc/ssh/sshd_config.d/
ディレクトリ内の設定ファイルを読み込むかどうかが決まります。この設定に基づいて、読み込みの挙動は次のように変わります。
Include
行が有効な場合(デフォルト)
/etc/ssh/sshd_config
にこの行が有効なままであれば、SSHサーバーは/etc/ssh/sshd_config.d/
ディレクトリ内の*.conf
ファイルを読み込みます。この場合の挙動は次の通りです。
-
優先順位:
sshd_config
が最初に読み込まれ、その後に/etc/ssh/sshd_config.d/*.conf
が読み込まれます。どちらも読み込まれるため、設定が重複する場合は、/etc/ssh/sshd_config.d/
内の設定が上書きされます。 -
柔軟性: 複数の設定ファイルに設定を分割することで、管理が容易になります。たとえば、メインの
sshd_config
ファイルには標準の設定を維持し、sshd_config.d/
ディレクトリには特定のカスタマイズや追加設定を行うことができます。 -
上書きの仕組み: 上述のように、同じ設定項目が
sshd_config
とsshd_config.d/
で重複している場合、後者の設定が優先され、SSHサーバーの動作を制御します。
Include
行が無効な場合
一方、Include /etc/ssh/sshd_config.d/*.conf
の行をコメントアウトすると、/etc/ssh/sshd_config.d/
ディレクトリ内のファイルは読み込まれなくなります。この場合の挙動は次の通りです。
-
優先順位: この場合、SSHの設定は完全に
/etc/ssh/sshd_config
に依存します。sshd_config
だけが読み込まれるため、すべての設定をこのファイル内で行う必要があります。 - 柔軟性の低下: 設定を分割して管理することができなくなるため、大規模な設定や複数のカスタマイズを行いたい場合、すべてを1つのファイルにまとめる必要があります。これにより、設定の管理が煩雑になる可能性があります。
-
カスタマイズの制限:
sshd_config.d/
内のカスタム設定が無視されるため、たとえばポートや認証方法に関する変更が適用されないことになります。
まとめ
-
Include
行が有効な場合:-
/etc/ssh/sshd_config.d/*.conf
の設定が読み込まれる。 -
sshd_config
の設定よりもsshd_config.d/*.conf
の設定が優先され、重複する設定がある場合は後者が適用される。 - 柔軟に設定を分割でき、管理が容易になる。
-
-
Include
行をコメントアウトした場合:-
/etc/ssh/sshd_config.d/*.conf
の設定は無視される。 - すべての設定を
/etc/ssh/sshd_config
内で行う必要があり、設定が分散されない分管理が複雑になる。 - カスタム設定が無効になり、標準の
sshd_config
のみが適用される。
-
このように、Include
行をコメントアウトするかどうかは、設定の管理方法や適用したいカスタマイズの度合いに応じて決めることが重要です。
具体例
Ubuntu 24.04では/etc/ssh/sshd_config.d/*.conf
はデフォルトで存在しています。このディレクトリは、SSHの設定を分割して管理するために用意されており、設定の柔軟性を向上させる目的で使用されます。
そこでは/etc/ssh/sshd_config.d/
内の設定ファイルは/etc/ssh/sshd_config
内のInclude /etc/ssh/sshd_config.d/*.conf
行によって自動的に読み込まれ、設定が優先される場合もあります。
/etc/ssh/sshd_config
内でPasswordAuthentication no
に設定していても、/etc/ssh/sshd_config.d/
内のファイルが読み込まれる場合、その後に読み込まれる設定が優先されます。
具体的に言うと、次のようなシナリオになります:
-
/etc/ssh/sshd_config
で次のように設定されているとします。PasswordAuthentication no
-
その後、
/etc/ssh/sshd_config.d/50-cloud-init.conf
が読み込まれ、次の設定が適用されます。PasswordAuthentication yes
この場合、Include /etc/ssh/sshd_config.d/*.conf
が有効であれば、sshd_config.d/
内の設定がsshd_config
の設定を上書きし、結果としてパスワード認証が有効になります。
つまり、SSHデーモンは以下の順序で設定を処理します。
-
/etc/ssh/sshd_config
を読み込む。 -
/etc/ssh/sshd_config.d/
内の設定ファイルを読み込む(Include
行が有効な場合)。 - 重複している設定については、後に読み込まれたものが優先される。
Include
行をコメントアウトするか、/etc/ssh/sshd_config.d/
内のファイルを削除・編集することで、この動作を調整できます。
/etc/ssh/sshd_config.d/*.conf
だけを編集すれば、/etc/ssh/sshd_config
を編集する必要がなくなります。Include /etc/ssh/sshd_config.d/*.conf
がデフォルトで有効になっている場合、SSHの設定はsshd_config.d/
内のファイルによって上書きされます。
シナリオ: /etc/ssh/sshd_config.d/*.conf
のみ編集する場合
例として、私がいつも使っている設定内容を/etc/ssh/sshd_config.d/custom.conf
に記述するとします。ここでは、Portは31425、ユーザーはDoraemonとします。公開鍵の設定が、正しく行われていない場合、完全に閉め出されてしまうので注意してください。とはいえ、その場合はサーバープロバイダのダッシュボードから、コンソールを使って修正することできます。
Port 31425
AllowUsers Doraemon
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no # ChallengeResponseAuthentication no
UsePAM no
この場合の動作は次のようになります:
-
Port 31425:
- SSHサーバーはデフォルトのポート22ではなく、ポート31425でリッスンします。
- SSHサーバーはデフォルトのポート22ではなく、ポート31425でリッスンします。
-
AllowUsers Doraemon:
-
Doraemon
ユーザーのみがSSH接続を許可され、他のユーザーはアクセスできません。
-
-
PermitRootLogin no:
- rootユーザーによるSSHログインは禁止されます。
- rootユーザーによるSSHログインは禁止されます。
-
PubkeyAuthentication yes:
- 公開鍵認証が有効になります。公開鍵認証を使用してSSH接続を行います。
- 公開鍵認証が有効になります。公開鍵認証を使用してSSH接続を行います。
-
PasswordAuthentication no:
- パスワード認証が無効になります。パスワードによるログインは許可されません。
- パスワード認証が無効になります。パスワードによるログインは許可されません。
-
PermitEmptyPasswords no:
- 空のパスワードでのログインが禁止されます。
- 空のパスワードでのログインが禁止されます。
-
KbdInteractiveAuthentication no or ChallengeResponseAuthentication no:
-
KbdInteractiveAuthentication no
という設定は、SSHログイン時にサーバーがユーザーに対して一連のプロンプト(パスワードやワンタイムパスコードなど)を提示し、その応答によってユーザーを認証するキーボードインタラクティブ認証方式を無効にするものです。この設定により、その認証方法が使えなくなります。 -
また
ChallengeResponseAuthentication no
は、はSSHでのチャレンジレスポンス認証を有効または無効にするオプションです。これが有効な場合、PAM (Pluggable Authentication Modules) を使用してチャレンジレスポンス認証が行われる可能性があります。 -
Ubuntu 24.04では、
ChallengeResponseAuthentication
は廃止され、KbdInteractiveAuthentication
が推奨されています。これはOpenSSHのバージョン8.7以降に関する変更で、古い認証方式から現代的な認証方式への移行を反映しています。この情報は信頼性のある技術的文献からのものです。以下、KbdInteractiveAuthenticationについての参照
-
-
UsePAM no:
- Pluggable Authentication Modules (PAM) の使用が無効化されます。
/etc/ssh/sshd_config
の役割
-
この設定を
/etc/ssh/sshd_config.d/
のファイルで行う場合、SSHサーバーの動作はその設定に従い、/etc/ssh/sshd_config
の設定は参照されません。 -
sshd_config
に同じ設定が記述されていたとしても、後に読み込まれるsshd_config.d/
内の設定が優先されます。したがって、
/etc/ssh/sshd_config
は基本的に触らず、設定変更を/etc/ssh/sshd_config.d/*.conf
に追加することで、システム全体のSSH設定を管理することができます。
/etc/ssh/sshd_config.d/*.conf
のみ編集する場合の利点
-
/etc/ssh/sshd_config
は編集しなくても良い。すべての設定は/etc/ssh/sshd_config.d/*.conf
でカバーされます。 -
Include /etc/ssh/sshd_config.d/*.conf
がデフォルトで有効なので、設定が正常に読み込まれます。 - 設定を一箇所にまとめ、
sshd_config.d/
を使って管理することができるため、柔軟に設定を調整できます。
4-2. ssh.socketの設定
- ssh.socketの状態を確認
sudo systemctl status ssh.socket
- アクティブになっていない場合は、ssh.socketをスタート
sudo systemctl start ssh.socket
ただしdisable
になっていた場合は、アクティブにする前にenable
する必要がある。
- ssh.socketを有効にする
sudo systemctl enable ssh.socket
- ssh.socketをスタートさせてアクティブ化
sudo systemctl start ssh.socket
- ssh.socketの状態を確認
sudo systemctl status ssh.socket
- 編集
sudo nano /lib/systemd/system/ssh.socket
- 以下のようにポートを変更
[Unit]
Description=OpenBSD Secure Shell server socket
Before=sockets.target ssh.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Socket]
ListenStream=31425 # sshポートに変更する。ここでは`31425`。
Accept=no
[Install]
WantedBy=sockets.target
RequiredBy=ssh.service
この設定ファイルの [Socket]
セクションにある ListenStream
と Accept
の設定について説明します。
【解説】
ListenStream
-
ListenStream=31425
はSSHサーバーがリッスンするポート番号を指定します。ここで指定された31425
は標準のSSHポート(22番)と異なります。これにより、セキュリティを強化するために非標準ポートを使用しています。
Accept
-
Accept=no
とAccept=yes
の違いは、ソケット接続を受け入れた後の動作に影響します。-
Accept=yes
の設定では、新しい接続が受け入れられるたびに、指定されたサービス(この場合はssh.service
)の新しいインスタンスが起動します。これは、各接続が独自のプロセスで処理されることを意味し、並列処理が可能になりますが、リソース使用量が増加する可能性があります。 -
Accept=no
とすると、ソケットを介して接続は受け入れられますが、すべての接続が既存のサービスインスタンスで処理されます。これにより、リソース使用が抑えられますが、接続ごとの隔離がなくなるため、セキュリティや障害の影響を受けやすくなる可能性があります。
-
どちらの設定を使うかは、サーバーのセキュリティポリシー、パフォーマンス要求、およびリソース管理のバランスに基づいて決定することが推奨されます。
- 編集後の読み込み、再スタート、確認
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo systemctl status ssh.socket
- ポートを確認
sudo netstat -tuln | grep 31425
5. 旧方式から新方式への切り替え
- デフォルトで無効化されている
ssh.socket
を有効にする -
ssh.service
と併用する
- ssh.socketの状態を確認
sudo systemctl status ssh.socket
-
disable
を確認できたら有効にする
sudo systemctl enable ssh.socket
- 次にスタート、確認
sudo systemctl start ssh.socket
sudo systemctl status ssh.socket
- ポートを確認
sudo netstat -tuln | grep 31425
- 編集
sudo nano /lib/systemd/system/ssh.socket
- 以下のようにポートを変更
[Unit]
Description=OpenBSD Secure Shell server socket
Before=sockets.target ssh.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Socket]
ListenStream=31425 # sshポートに変更する。ここでは`31425`。
Accept=no
[Install]
WantedBy=sockets.target
RequiredBy=ssh.service
- 編集後の読み込み、再スタート、確認
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo systemctl status ssh.socket
- ポートを確認
sudo netstat -tuln | grep 31425
6. IPv6 dual-stackについて
https://chatgpt.com/share/95127b7d-bc38-4a61-8803-0f081c36e628
実は、tcp6
でリッスンしている場合でも、場合によっては IPv4 も同時にリッスンしていることがあります。これは "IPv6 dual-stack" という機能に関係しています。
IPv6 Dual-Stackとは?
-
Dual-Stack とは、システムが同時に IPv4 と IPv6 の両方を扱えるように設定されている場合、
tcp6
でリッスンしているときに、IPv4 の接続も許可する仕組みです。 - 一般的に、Linux のデフォルトの設定では、IPv6 のリッスンソケットが IPv4 からの接続も受け入れるように構成されている場合が多いです。このため、
tcp6
で:::12345
と表示されているときも、IPv4 の0.0.0.0:12345
でもリッスンしている可能性があります。
どう確認するか?
-
システムの設定によっては、IPv6ソケットがIPv4を含むすべてのアドレスでリッスンするように構成されていることがあります。この場合、
netstat
の出力ではtcp6
と表示されていても、IPv4 からの接続も受け付けます。 -
ただし、
dual-stack
の設定が無効になっていると、IPv4 と IPv6 は別々のソケットでリッスンしなければなりません。この設定はsysctl
のnet.ipv6.bindv6only
パラメータによって制御されています。
確認する方法
次のコマンドを実行して、net.ipv6.bindv6only
の値を確認できます:
sysctl net.ipv6.bindv6only
-
0
であれば、Dual-Stackが有効であり、IPv6ソケットでIPv4接続も受け付けます。 -
1
であれば、IPv6ソケットはIPv6専用であり、IPv4の接続は受け付けません。
まとめ
-
bindv6only = 0 の場合:
tcp6
でリッスンしている場合でも、IPv4 からの接続も受け付ける。 -
bindv6only = 1 の場合:
tcp6
でリッスンしているのはIPv6接続のみ。
もし、IPv4とIPv6で分けたい場合や確認したい場合は、個別に tcp
(IPv4)用のソケットを開いて、どちらでもリッスンしているかどうか確認するのが確実です。