条件説明

条件説明

条件説明

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ユニットファイルにディレクティブがありません。Beforesshd.socket

どちらのシステムも、これによって発生する問題を発見できませんでした。何か目的があると思われますが、見つかりません。

答え1

systemdソケットは、systemdが自分自身をポート(またはUnixドメインソケットファイルパスなどの他のリソース)にバインドし、すべての接続に対して新しいサービスインスタンスを作成できるようにする特別な種類のデバイスです。 ssh.serviceが有効になると、sshdはlsofに示されているように継続的に実行され、ソケットにバインドされます。対照的に、ssh.socketを有効にすることは、sshdが継続的に実行されず、クライアントを処理するために1つのインスタンスのみを呼び出すことを意味します。代わりに、systemdがポート22でリッスンしていることを示します。 systemdとsshdは同時に同じポートでリッスンできないため、ssh.serviceを指定するssh.socketに競合があります。

答え2

理解すべき重要な点は、あなたが見ているのが「ソケット」デバイスの特定の用途であることです。サム: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に設定されている場合、サービステンプレートは[Eメール保護]存在する必要があり、サービスは着信接続ごとにインスタンス化されます。

したがって、sshdを起動する方法は2つあります。

  • ssh.servicesshd.serviceエイリアスのみ)デフォルトのsshdプロセスを開始し、すべての着信接続を処理し、子プロセスを作成するなどの操作を実行します。
  • ssh.socket+ [email protected]、ここでsystemdは、ソケット管理ポートから着信する各接続を新しいインスタンスに接続します。[Eメール保護]、inetdスタイル。そのため、テンプレートサービスには、、StandardInput=socketのオプションがExecStart=/usr/sbin/sshdあります-i

明らかに一度に1つの方法しか使用できないので、両方のConflicts=方法を同時に実行しないでください。 (しかし、セクションの実際の場所はConflicts=重要ではありません。ssh.serviceにそのセクションを作成できますが、1つだけで十分です。)

関連情報