Ssh

為什麼 ssh.socket 設置為與 ssh.service (Ubuntu 18.04.3) 衝突?

  • May 19, 2022

條件描述

我在 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

在這兩個系統上,我都沒有註意到這種情況會導致任何問題,我懷疑它有某種目的,但找不到。

systemd 套接字是一種特殊類型的單元,它使 systemd 自身綁定到埠(或其他資源,例如 unix 域套接字文件路徑)並為任何連接生成一個新的服務實例。啟用 ssh.service 後,它的 sshd 會連續執行並綁定到套接字,如 lsof 所示。開啟 ssh.socket 意味著 sshd 不會連續執行,而是呼叫它的一個實例來處理一個客戶端。相反,它會顯示 systemd 在埠 22 上偵聽。由於 systemd 和 sshd 不能同時偵聽同一埠,因此 ssh.socket 將 ssh.service 指定為衝突的。

引用自:https://unix.stackexchange.com/questions/674691