状態の説明
Ubuntu 18.04.3 LTS で systemd と ssh に奇妙な問題が発生しました
ユニットのステータスを確認しましたssh.socket
:
$ systemctl status ssh.socket
● ssh.socket - OpenBSD Secure Shell server socket
Loaded: loaded (/lib/systemd/system/ssh.socket; disabled; vendor preset: enabled)
Active: inactive (dead)
Listen: [::]:22 (Stream)
Accepted: 0; Connected: 0
非アクティブでしたが、同時に ssh でログインしており、サービス自体は実行されており、SSH のソケットと対応するポートは開いていました。
$ lsof -P -i -n | grep sshd
sshd 26785 root 3u IPv4 14858764 0t0 TCP 10.200.130.28:22->10.100.40.141:42188 (ESTABLISHED)
sshd 26875 xxx_root 3u IPv4 14858764 0t0 TCP 10.200.130.28:22->10.100.40.141:42188 (ESTABLISHED)
sshd 63859 root 3u IPv4 238437 0t0 TCP *:22 (LISTEN)
sshd 63859 root 4u IPv6 238439 0t0 TCP *:22 (LISTEN)
そこで、ssh.socket のユニット ファイルを調べてみました/lib/systemd/system/ssh.socket
。
[Unit]
Description=OpenBSD Secure Shell server socket
Before=ssh.service
Conflicts=ssh.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Socket]
ListenStream=22
Accept=yes
[Install]
WantedBy=sockets.target
ディレクティブにより、Before=ssh.service
ssh サービスの前に起動する必要があり、Conflicts=ssh.service
ssh サービスが起動するとディレクティブによって停止します。
これは、ユニット ファイルの観点からなぜこれが発生するのかを説明しますが、他の疑問も生じます。
質問
ssh.socket ユニットの非アクティブ状態が実際の ssh ソケットに影響を与えないのはなぜですか?
メンテナーがConflict
ディレクティブを追加したのはなぜですか? たとえば、 のユニット ファイルを確認すると、docker.socket
と競合するように設定されていませんdocker.service
。 sshd の場合はどう違うのでしょうか?
追加情報
古い fedora 30 ワークステーションでもこれを確認しました。条件は同じですが、わずかな違いがあります。ユニット名としてsshd.service
とが使用され、ユニット ファイルにディレクティブsshd.socket
がありません。Before
sshd.socket
どちらのシステムでも、この状態から生じる問題は確認されていません。何らかの目的があるのではないかと疑っていますが、見つけることができません。
答え1
systemd ソケットは、systemd 自体をポート (または UNIX ドメイン ソケット ファイル パスなどの他のリソース) にバインドし、接続ごとにサービスの新しいインスタンスを生成する特殊なタイプのユニットです。ssh.service を有効にすると、lsof が示すように、sshd が継続的に実行され、ソケットにバインドされます。代わりに ssh.socket をオンにすると、sshd は継続的に実行されず、1 つのクライアントを処理するためだけにインスタンスが呼び出されます。また、対照的に、systemd がポート 22 でリッスンしていることが示されます。systemd と sshd の両方が同じポートでリッスンすることはできないため、ssh.socket は ssh.service を競合として指定します。
答え2
理解しておくべき重要なことは、ここで見ているのは「ソケット」ユニットの特定の使用法の1つであり、合計すると、三つ:http://0pointer.de/blog/projects/inetd.html
したがって、 の場合ssh.socket
、これは旧式のinetdのような呼び出し(コアソケットユニット設定:Accept=yes
)、ポート22(systemdによって管理)へのすべての着信リクエストは、別の[email protected]
実例。
systemd.socket のマニュアルページも参照してください:https://www.freedesktop.org/software/systemd/man/systemd.socket.html
Accept=yesが設定されている場合、サービステンプレート[メールアドレス]各着信接続に対してインスタンス化されるサービスが存在する必要がある
したがって、sshd を起動する方法は全部で 2 つあります。
ssh.service
(sshd.service
は単なるエイリアスです) はメインの sshd プロセスを開始し、そこからプロセスはすべての着信接続を処理し、子プロセスを生成するなどを行います。ssh.socket
+[email protected]
、ここでsystemdはソケット管理ポートからのすべての着信接続を新しいインスタンスに接続します[メールアドレス]、inetd スタイル。これが、テンプレート サービスでStandardInput=socket
、およびにオプションExecStart=/usr/sbin/sshd
がある理由です-i
。
当然のことながら、一度に使用できるのは 1 つのアプローチだけなので、Conflicts=
両方が同時に実行されないようにします。(ちなみに、スタンザの実際の配置はConflicts=
重要ではありません。同等のスタンザを ssh.service に記述することもできますが、1 つで十分です)