状態の説明

状態の説明

状態の説明

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.servicessh サービスの前に起動する必要があり、Conflicts=ssh.servicessh サービスが起動するとディレクティブによって停止します。

これは、ユニット ファイルの観点からなぜこれが発生するのかを説明しますが、他の疑問も生じます。

質問

ssh.socket ユニットの非アクティブ状態が実際の ssh ソケットに影響を与えないのはなぜですか?

メンテナーがConflictディレクティブを追加したのはなぜですか? たとえば、 のユニット ファイルを確認すると、docker.socketと競合するように設定されていませんdocker.service。 sshd の場合はどう違うのでしょうか?

追加情報

古い fedora 30 ワークステーションでもこれを確認しました。条件は同じですが、わずかな違いがあります。ユニット名としてsshd.serviceとが使用され、ユニット ファイルにディレクティブsshd.socketがありません。Beforesshd.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 つで十分です)

関連情報