当我查看时journalctl
,它会告诉我日志条目的 PID 和程序名称(或服务名称?)。
然后我想知道,日志是由其他进程创建的,当进程可能只将原始字符串写入正在侦听的 unix 域套接字时,如何systemd-journald
知道这些进程的 PID systemd-journald
。此外,是否sytemd-journald
始终使用相同的技术来检测一段日志数据的 PID,即使进程正在使用类似的函数生成日志sd_journal_sendv()
?
我应该阅读有关此的任何文档吗?
我阅读了 JdeBP 的答案并知道systemd-journald
在 Unix Domian Socket 上侦听,但是即使可以知道发送日志消息的对等套接字地址,它如何知道 PID?如果该发送套接字被许多非父子进程打开怎么办?
SCM_CREDENTIALS
它通过unix 套接字上的辅助数据接收 pidrecvmsg()
,参见unix(7)
. 不必显式发送凭据。例子:
带有数据的进程
CAP_SYS_ADMIN
可以通过 ; 发送他们想要的任何 pidSCM_CREDENTIALS
;在 的情况下systemd-journald
,这意味着他们可以伪造条目,就像被另一个进程记录一样:systemd-journald
处理通过辅助数据发送的数据报和凭据在server_process_datagram()
函数 from 中journald-server.c
。默认情况下,syslog(3)
标准函数 fromlibc
和sd_journal_sendv()
from都libsystemd
将通过套接字发送数据,并且不适用于数据报(无连接)套接字。既不也不接受. _SOCK_DGRAM
getsockopt(SO_PEERCRED)
systemd-journald
rsyslogd
SOCK_STREAM
/dev/log
scm_cred.c
假的.c
内核告诉它。
AF_LOCAL
连接流套接字的原始客户端进程的 EUID、EGID 和 PID/run/systemd/journal/stdout
可通过内核使用的套接字SO_PEERCRED
选项从内核获得。UCSPI-UNIX 工具通过相同的系统调用获得同样的信息。子服务进程当然会继承它们已经打开的标准 I/O 文件描述符(当然,除非父服务进程更改了这一点),因此
systemd-journald
所有日志输出都具有原始父进程的凭据。AF_LOCAL
通过套接字生成的日志输出/run/systemd/journal/socket
表明特殊systemd-journald
协议来自数据报套接字,而不是流套接字。该套接字使用套接字选项进行标记,SO_PASSCRED
以便内核在发送的每个数据报中记录相同的信息,这些信息由systemd-journald
.进一步阅读
getsockopt()
. Linux 程序员手册。2017-09-15。socket
. Linux 程序员手册。2018-02-02。local-stream-socket-accept
. 小吃指南。软件。