fprintf to stderr in daemon
От: k55 Ниоткуда  
Дата: 22.03.23 23:31
Оценка:
День добрый.

Linux, Ubuntu.
Код на Си.

Есть dropbear утилита. Умельцы прикрутили к нему библиотеку и делают логирование через оную при новом ssh соединении.

В некоторых случаях (когда не могуд достучаться до dbus клиента) делают логирование через

fprintf(stderr, "%s", "Message");


Прикол в том что эти логи видны в ssh пакетах во время договорки о поддерживаемых протоколах, от чего ssh клиент сходит с ума и отваливается.

Т.к. dropbear стартуется через systemd socket то dropbear работает как демон. И по логике у него нет stderr.

Вопрос, связаны ли эти "побочные эффекты" с тем что dropbear демон и вообще, что ожидать в случае записи в stderr в демоне?
Если есть желание — найдется 1000 возможностей.
Если нет желания — найдется 1000 причин.
Re: fprintf to stderr in daemon
От: cppguard  
Дата: 23.03.23 07:17
Оценка:
Здравствуйте, k55, Вы писали:

k55>Вопрос, связаны ли эти "побочные эффекты" с тем что dropbear демон и вообще, что ожидать в случае записи в stderr в демоне?


Если верить systemd.service(5), то по-умолчанию дескриптор для stdout используется и для stderr.
Re[2]: fprintf to stderr in daemon
От: k55 Ниоткуда  
Дата: 23.03.23 14:42
Оценка:
Похоже дело в dropbear. Если его запустить без ключа -i (inetd mode) без перехода в бэкграунд то все работает и ошибка печатается на консоль.

Inetd режим супер-пупер сервера. Я так понимаю в этом режиме у него нет stdout/stderr. Сам dropbear ругается если пытаешься включить verbose вместе с inetd.
Если есть желание — найдется 1000 возможностей.
Если нет желания — найдется 1000 причин.
Re[3]: fprintf to stderr in daemon
От: cppguard  
Дата: 23.03.23 20:12
Оценка: 6 (1)
Здравствуйте, k55, Вы писали:

k55>Inetd режим супер-пупер сервера. Я так понимаю в этом режиме у него нет stdout/stderr. Сам dropbear ругается если пытаешься включить verbose вместе с inetd.


Смешались в кучу кони-люди. Во-первых, stdin, stdout и stderr есть всегда. Вопрос в том, куда они ведут. Я выше писал, что если сервис запущен через systemd socket activation, то stdin и stdout связаны с сокетом, а stderr, если верить документации systemd, дублирует значение stdout, то есть, тоже связан с сокетом. Далее, при чём тут inetd, если речь про systemd? Имеется в виду systemdd socket activation в режиме совместимости c systemd или что-то другое?
Re[4]: fprintf to stderr in daemon
От: k55 Ниоткуда  
Дата: 24.03.23 14:19
Оценка:
C>Смешались в кучу кони-люди. Во-первых, stdin, stdout и stderr есть всегда. Вопрос в том, куда они ведут. Я выше писал, что если сервис запущен через systemd socket activation, то stdin и stdout связаны с сокетом, а stderr, если верить документации systemd, дублирует значение stdout, то есть, тоже связан с сокетом. Далее, при чём тут inetd, если речь про systemd? Имеется в виду systemdd socket activation в режиме совместимости c systemd или что-то другое?

Спасибо, я теперь понял что имелось ввиду.

"Я выше писал, что если сервис запущен через systemd socket activation, то stdin и stdout связаны с сокетом, а stderr, если верить документации systemd, дублирует значение stdout"
Это ключевое. В сервисе для dropbear был указан только StandardInput=socket и как следствие все остальное тоже было сокетом.
Прописал StandardError=syslog+console и теперь ошибка попадает на консоль и в логи, ssh работает.
Если есть желание — найдется 1000 возможностей.
Если нет желания — найдется 1000 причин.
Re[4]: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.03.23 12:11
Оценка:
Здравствуйте, cppguard, Вы писали:

k55>>Inetd режим супер-пупер сервера. Я так понимаю в этом режиме у него нет stdout/stderr. Сам dropbear ругается если пытаешься включить verbose вместе с inetd.


C>Смешались в кучу кони-люди. Во-первых, stdin, stdout и stderr есть всегда.


Вообще-то нет. То, что что-то открыто на дескрипторах 0-2 — это правило хорошего тона, но не обязанность. Но тут речь явно не про этот случай.

C> Вопрос в том, куда они ведут. Я выше писал, что если сервис запущен через systemd socket activation, то stdin и stdout связаны с сокетом, а stderr, если верить документации systemd, дублирует значение stdout, то есть, тоже связан с сокетом. Далее, при чём тут inetd, если речь про systemd? Имеется в виду systemdd socket activation в режиме совместимости c systemd или что-то другое?


Я думаю, имеется в виду inetd-режим подчинённого демона.
В одном проекте, что сейчас ломаю, как раз sshd.socket в systemd запускает sshd%.service
с командой "sshd -i", а это -i как раз показывает sshd, что он запущен из-под inetd / xinetd / аналога (как systemd) на одно входящее соединение.

И если в самом сервере не доработано, что в этом состоянии не надо всякую хрень посылать на дефолтные дескрипторы — то он ССЗБ.
The God is real, unless declared integer.
Re: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.03.23 12:13
Оценка: +1
Здравствуйте, k55, Вы писали:

k55>Т.к. dropbear стартуется через systemd socket то dropbear работает как демон. И по логике у него нет stderr.


Это как раз не "как демон". Демон — если бы он сам свой процесс держал, который слушает сокет.
The God is real, unless declared integer.
Re[5]: fprintf to stderr in daemon
От: cppguard  
Дата: 30.03.23 13:01
Оценка:
Здравствуйте, netch80, Вы писали:

N>Вообще-то нет. То, что что-то открыто на дескрипторах 0-2 — это правило хорошего тона, но не обязанность. Но тут речь явно не про этот случай.


Так никто не говорит, что нет возможности запустить программу так, чтобы чтение stdin сломалось, но, насколько мне известно, по-умолчанию всё таки stdin, stdout и stderr предоставлены процессу.

N>Я думаю, имеется в виду inetd-режим подчинённого демона.

N>В одном проекте, что сейчас ломаю, как раз sshd.socket в systemd запускает sshd%.service
N>с командой "sshd -i", а это -i как раз показывает sshd, что он запущен из-под inetd / xinetd / аналога (как systemd) на одно входящее соединение.

N>И если в самом сервере не доработано, что в этом состоянии не надо всякую хрень посылать на дефолтные дескрипторы — то он ССЗБ.


Тут соль в том, что socket activation умеет запускать программы, которые были разработаны под inetd, есть специальная опция для этого. Но механика передачи файловых дескрипторов меняется. Я не разбирался до конца, но точно знаю, что, например, в Java System.inheritedChannel() работает только в режиме совместимости с inetd. Поэтому я хотел уточнить, что там вообще происходит. Может вообще inetd одновременно с systemd работает?
Re[6]: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.03.23 06:09
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Тут соль в том, что socket activation умеет запускать программы, которые были разработаны под inetd, есть специальная опция для этого. Но механика передачи файловых дескрипторов меняется. Я не разбирался до конца,


Есть дока, хоть и кривая: тут.
Тест показывает, что без опции inetd приходит один сокет номер 3.
Банально, проверка в духе "echo 123 1>&3" пишет в него, без этого — пишет куда-то на другой stdout.
Я не понял, почему дока говорит про несколько сокетов.

C> но точно знаю, что, например, в Java System.inheritedChannel() работает только в режиме совместимости с inetd. Поэтому я хотел уточнить, что там вообще происходит. Может вообще inetd одновременно с systemd работает?


Ну не запрещено же и даже в чём-то удобно.
The God is real, unless declared integer.
Re[7]: fprintf to stderr in daemon
От: cppguard  
Дата: 31.03.23 07:21
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, cppguard, Вы писали:


N>Я не понял, почему дока говорит про несколько сокетов.


Если флаг --inetd есть, то переиспользуются stdin/stdout процесса-демона. Если нет, то процесс наследует stdin/stdout порождающего процесса, а activated sockets доступны с fd=3 и далее, а их количество можно узнать из LISTEN_FDS или вызвав sd_listen_fds().
Re[8]: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.03.23 08:23
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Здравствуйте, netch80, Вы писали:


N>>Я не понял, почему дока говорит про несколько сокетов.


C>Если флаг --inetd есть, то переиспользуются stdin/stdout процесса-демона. Если нет, то процесс наследует stdin/stdout порождающего процесса, а activated sockets доступны с fd=3 и далее, а их количество можно узнать из LISTEN_FDS или вызвав sd_listen_fds().


Каким образом возможно наличие нескольких activated sockets для входящих сетевых соединений?
The God is real, unless declared integer.
Re[9]: fprintf to stderr in daemon
От: cppguard  
Дата: 31.03.23 11:43
Оценка:
Здравствуйте, netch80, Вы писали:

N>Каким образом возможно наличие нескольких activated sockets для входящих сетевых соединений?



ListenStream=, ListenDatagram=, ListenSequentialPacket=

...

These options may be specified more than once, in which case incoming traffic on any of the sockets will trigger service activation, and all listed sockets will be passed to
the service, regardless of whether there is incoming traffic on them or not. If the empty string is assigned to any of these options, the list of addresses to listen on is
reset, all prior uses of any of these options will have no effect.

Re[10]: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.03.23 11:51
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Здравствуйте, netch80, Вы писали:


N>>Каким образом возможно наличие нескольких activated sockets для входящих сетевых соединений?


C>ListenStream=, ListenDatagram=, ListenSequentialPacket=


Я эту херь вроде видел. Я не могу понять, чего они добиваются. Что за сценарий когда это реально нужно?

TCP, SCTP — приняли соединение и с ним работаем. Когда другое придёт — ХЗ.
Слушать из-за этого другой сокет — мешать вероятному соседу делать то же самое.
UDP — вроде та же проблема.

Или это на тот вариант, что в классическом inetd звался wait?
Дело systemd захватить сокеты, а целевой программы — слушать?
Тогда и это вроде делается иначе.

Надо покопать, что пишут про сценарии для этого режима.
The God is real, unless declared integer.
Re[11]: fprintf to stderr in daemon
От: cppguard  
Дата: 31.03.23 12:19
Оценка:
Здравствуйте, netch80, Вы писали:

N>Надо покопать, что пишут про сценарии для этого режима.


По-мойму, всё просто — слушать на разных интерфейсах. Как-минимум, PostgreSQL так умеет — и юникс сокет слушать, и сеть. Мне кажется, что в дизайне systemd нет какой-то хитрой идеи, разработчики просто пытаются подстроить систему под уже известные сценарии.
Re[12]: fprintf to stderr in daemon
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.03.23 14:36
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>Надо покопать, что пишут про сценарии для этого режима.


C>По-мойму, всё просто — слушать на разных интерфейсах.


Это не объясняет, зачем слушающие сокеты передавать в запущенный серверный процесс после этого.

C> Как-минимум, PostgreSQL так умеет — и юникс сокет слушать, и сеть.


Многие умеют. Этого недостаточно.
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.