AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 491416
Accepted
炸鱼薯条德里克
炸鱼薯条德里克
Asked: 2018-12-29 21:51:03 +0800 CST2018-12-29 21:51:03 +0800 CST 2018-12-29 21:51:03 +0800 CST

Como journald sabe o PID de um processo que produz dados de log?

  • 772

Quando olho para journalctl, ele me diz o PID e o nome do programa (ou nome do serviço?) de uma entrada de log.

Então eu me perguntei, os logs são criados por outros processos, como systemd-journaldsaber o PID desses processos quando os processos podem apenas gravar strings brutas no soquete do domínio unix que systemd-journaldestá ouvindo. Além disso, sytemd-journaldsempre use a mesma técnica para detectar o PID de um dado de log, mesmo quando os processos estiverem produzindo log usando funções como sd_journal_sendv()?

Existe alguma documentação que eu deveria ler sobre isso?

Eu li a resposta do JdeBP e sei systemd-journaldescutar em um Unix Domian Socket, mas mesmo sabendo o endereço do soquete do peer que envia a mensagem de log, como ele sabe o PID? E se esse soquete de envio for aberto por muitos processos não pai-filhos?

ipc systemd-journald
  • 2 2 respostas
  • 1916 Views

2 respostas

  • Voted
  1. Best Answer
    mosvy
    2018-12-29T23:04:09+08:002018-12-29T23:04:09+08:00

    Ele recebe o pid através dos SCM_CREDENTIALSdados auxiliares no soquete unix com recvmsg(), veja unix(7). As credenciais não precisam ser enviadas explicitamente.

    Exemplo:

    $ cc -Wall scm_cred.c -o scm_cred
    $ ./scm_cred
    scm_cred: received from 10114: pid=10114 uid=2000 gid=2000
    

    Processos com CAP_SYS_ADMINdados podem enviar o pid que quiserem via SCM_CREDENTIALS; no caso de systemd-journald, isso significa que eles podem falsificar entradas como se fossem registradas por outro processo:

    # cc -Wall fake.c -o fake
    # setcap CAP_SYS_ADMIN+ep fake
    
    $ ./fake `pgrep -f /usr/sbin/sshd`
    
    # journalctl --no-pager -n 1
    ...
    Dec 29 11:04:57 debin sshd[419]: fake log message from 14202
    # rm fake
    # lsb_release -d
    Description:    Debian GNU/Linux 9.6 (stretch)
    

    systemd-journaldmanipula datagramas e credenciais enviados por meio de dados auxiliares está na server_process_datagram()função de journald-server.c. Tanto a syslog(3)função padrão de libcquanto sd_journal_sendv()de libsystemdenviará seus dados por meio de um SOCK_DGRAMsoquete por padrão e getsockopt(SO_PEERCRED)não funciona em soquetes de datagrama (sem conexão). Nem systemd-journaldnem rsyslogdaceitar SOCK_STREAMconexões em /dev/log.

    scm_cred.c

    #define _GNU_SOURCE     1
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <unistd.h>
    #include <err.h>
    
    int main(void){
            int fd[2]; pid_t pid;
            if(socketpair(AF_LOCAL, SOCK_DGRAM, 0, fd)) err(1, "socketpair");
            if((pid = fork()) == -1) err(1, "fork");
            if(pid){ /* parent */
                    int on = 1;
                    union {
                            struct cmsghdr h;
                            char data[CMSG_SPACE(sizeof(struct ucred))];
                    } buf;
                    struct msghdr m = {0};
                    struct ucred *uc = (struct ucred*)CMSG_DATA(&buf.h);
                    m.msg_control = &buf;
                    m.msg_controllen = sizeof buf;
                    if(setsockopt(fd[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof on))
                            err(1, "setsockopt");
                    if(recvmsg(fd[0], &m, 0) == -1) err(1, "recvmsg");
                    warnx("received from %d: pid=%d uid=%d gid=%d", pid,
                            uc->pid, uc->uid, uc->gid);
            }else   /* child */
                    write(fd[1], 0, 0);
            return 0;
    }
    

    fake.c

    #define _GNU_SOURCE     1
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <err.h>
    
    int main(int ac, char **av){
            union {
                    struct cmsghdr h;
                    char data[CMSG_SPACE(sizeof(struct ucred))];
            } cm;
            int fd; char buf[256];
            struct ucred *uc = (struct ucred*)CMSG_DATA(&cm.h);
            struct msghdr m = {0};
            struct sockaddr_un ua = {AF_UNIX, "/dev/log"};
            struct iovec iov = {buf};
            if((fd = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) err(1, "socket");
            if(connect(fd, (struct sockaddr*)&ua, SUN_LEN(&ua))) err(1, "connect");
            m.msg_control = &cm;
            m.msg_controllen = cm.h.cmsg_len = CMSG_LEN(sizeof(struct ucred));
            cm.h.cmsg_level = SOL_SOCKET;
            cm.h.cmsg_type = SCM_CREDENTIALS;
            uc->pid = ac > 1 ? atoi(av[1]) : getpid();
            uc->uid = ac > 2 ? atoi(av[2]) : geteuid();
            uc->gid = ac > 3 ? atoi(av[3]) : getegid();
            iov.iov_len = snprintf(buf, sizeof buf, "<13>%s from %d",
                    ac > 4 ? av[4] : "fake log message", getpid());
            if(iov.iov_len >= sizeof buf) errx(1, "message too long");
            m.msg_iov = &iov;
            m.msg_iovlen = 1;
            if(sendmsg(fd, &m, 0) == -1) err(1, "sendmsg");
            return 0;
    }
    
    • 5
  2. JdeBP
    2018-12-29T23:56:00+08:002018-12-29T23:56:00+08:00

    O kernel diz isso.

    O EUID, EGID e PID do processo cliente original que conectou o AF_LOCALsoquete de fluxo em /run/systemd/journal/stdoutestá disponível no kernel por meio da SO_PEERCREDopção de soquete, que ele usa . As ferramentas UCSPI-UNIX obtêm esta mesma informação através da mesma chamada de sistema.

    É claro que os processos de serviço filho herdam seus descritores de arquivo de E/S padrão já abertos (a menos que o processo de serviço pai altere isso, é claro) e, portanto, systemd-journaldtodas as saídas de log têm as credenciais do processo pai original.

    A saída de log gerada através do AF_LOCALsoquete em /run/systemd/journal/socketque fala que o systemd-journaldprotocolo idiossincrático está vindo de um soquete de datagrama, em vez de um fluxo. Este socket é sinalizado usando a SO_PASSCREDopção socket para que o kernel registre a mesma informação em cada datagrama enviado, que é retirado de cada datagrama por systemd-journald.

    Leitura adicional

    • getsockopt(). Manual do programador Linux . 2017-09-15.
    • socket. Manual do programador Linux . 2018-02-02.
    • Jonathan de Boyne Pollard (2017). local-stream-socket-accept. Guia de no . Programas.
    • Jonathan de Boyne Pollard (2015). " Variáveis ​​de ambiente ". O gen na Interface de Programa Cliente-Servidor UNIX . Respostas Frequentes.
    • 1

relate perguntas

  • Por que o journalctl não exibe a mensagem de log se eu usar a filtragem por unidade?

  • Posso mascarar o serviço systemd-journal-flush e executar journalctl --flush mais tarde manualmente?

  • Manipulando várias mensagens na fila de mensagens

  • Manipulando o SIGALRM de duas maneiras diferentes

  • Pub / sub de linha de comando sem um servidor?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve