Описание состояния

Описание состояния

Описание состояния

Я столкнулся со странной ситуацией с systemd и ssh на Ubuntu 18.04.3 LTS

Я проверил состояние устройства 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 не работает непрерывно, а вызывается только для обработки одного клиента. И, напротив, systemd будет прослушивать порт 22. Поскольку systemd и sshd не могут прослушивать один и тот же порт, ssh.socket определяет ssh.service как конфликтующий.

решение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, шаблон службы[email protected]должен существовать, из которого создаются экземпляры служб для каждого входящего соединения

Итак, всего существует два разных способа запустить sshd:

  • ssh.service( sshd.serviceэто просто псевдоним) запускает основной процесс sshd, и с этого момента процесс обрабатывает все входящие соединения, порождает дочерние процессы и т. д. и т. п.
  • ssh.socket+ [email protected], здесь systemd подключает каждое входящее соединение с управляемого сокетом порта к новому экземпляру[email protected], inetd-style. Вот почему в шаблонной службе , StandardInput=socketи ExecStart=/usr/sbin/sshdесть -iопция.

Очевидно, что одновременно можно использовать только один подход, поэтому Conflicts=убедитесь, что оба не работают одновременно. (кстати: фактическое размещение строфы Conflicts=не важно, эквивалентную строфу можно было бы написать в ssh.service, но одной достаточно)

Связанный контент