Linux'taki tüm işlem başlatmalarını nasıl günlüğe kaydedebilirim?


55

Başlatıldıkları zaman başlatılan tüm işlemlerin ve başlattıkları argümanların bir günlüğünü almak istiyorum. Linux'ta bu mümkün mü?

Yanıtlar:


43

Başlangıç ​​noktanız denetçi olmalıdır.

Böyle bir şey dene:

apt-get install auditd
auditctl -a task,always
ausearch -i -sc execve

1
Hata alıyorum The audit system is disabledNerede etkinleştirebilirim?
Tombart

1
iyi bir sorun çözüldü chmod 0750 /sbin/audispdama hala işe yaramadı (Debian Wheezy)
Tombart

diyor, Unable to set audit pid, exitingancak asıl sorunun, sistemin LXC konteynerinde çalışması olacak sanırım
Tombart

Denetim sistem dergisi ile nasıl bütünleşir? İşlevleri örtüşüyor mu?
CMCDragonkai

Bunu canlı bir sunucuda denedim ve etkili bir şekilde öldürdüm, neredeyse tepkisiz hale geldi. Bu kuralı kaldırmayı ve sunucuyu tekrar yanıt vermeye
zorladım

10

Bunu yapmam gerekiyordu, (1) Zamana ihtiyacım yoktu ve (2) Sadece belirli bir sürecin başlattığı süreçlerle, çocukları ve sonraki torunlarla ilgileniyordum. Ayrıca, ben kullanıyordum ortamda, bunu elde etmek mümkün değildi auditdya accton, ama yoktu valgrind.

Aşağıdakileri komut satırındaki ilgilenilen sürece önek edin:

valgrind --trace-children=yes

İhtiyacınız olan bilgi STDERR'de görüntülenen log çıktısında olacaktır.


3
Varsayılan olarak, valgrind aracıyla çalışır memcheck. Aracı ve ilgili günlüğü devre dışı bırakmak ve yalnızca (programın her zaman aldığı sonuçlara ek olarak) yeni komutlar oluşturulmasını yazdırmak için, bunun yerine aşağıdaki komutu kullanın: valgrind --tool=none --trace-children=yes [command and args here]. Her ne zaman bir alt işlem ortaya çıkarsa, Valgrind kendisine iletilen argümanlar da dahil olmak üzere tam komutu kaydeder.
Rob W

6

Bunun için snoopy kullanabilirsiniz .

Kurulumu çok basittir ve 2.x'ten beri isteğe bağlı verileri (argümanlar, çevresel değişkenler, cwd vb.) Kaydedebilir.

Açıklama: Burada Snoopy koruyucu.


2

Startmon komutunu çalıştırabilir ve bittiğinde standart Ctrl-C çıkışını takip edebilirsiniz. İşte en son Red Hat türetilmiş dağıtımlarında (RHEL, Fedora, CentOS) nasıl derhal çalıştırılacağı ve çalıştırılacağı:

sudo yum install git cmake gcc-c++
git clone https://github.com/pturmel/startmon
cd startmon
cmake .
make
sudo ./startmon -e

Debian'da (ve Ubuntu vb.), Yukarıdakilerin ilk satırı şu şekilde değişir:

sudo apt-get install git cmake g++

Alternatif olarak execsnoopsenaryoyu perf-tools içerisinde deneyebilirsiniz, bu cevaba bakınız . Varsayılan olarak sadece ilk 8 argüman gösterilir (program adı dahil 9); bunu artırabilirsin

sudo ./execsnoop -a 16

Sisteme kök erişiminiz yoksa, yapabileceğiniz en iyi şey oylamaya devam etmek /procve her şeyi yakalayacağını ummaktır (ki işe yaramayacak), ancak bütünlük için bunu yapmak için bir komut dosyası (yinelenen kaldırma işlemi koydum) çıktıyı basitleştirmek için) —bu yukarıdaki yöntemlerden biriyle onları doğru şekilde izlemek kadar iyi olmasa da, komut satırındaki argümanlar arasında açıkça ayırıcıları açıkça gösterme avantajına sahiptir; boşluklar arasındaki fark içinde bir bağımsız değişken ve mekan arasında bağımsız değişkenler. Bu betiğin işlemciyi kullanması nedeniyle verimsiz (peki, özlerinden biri) zamanın% 100'ünü.

function pstail () { python -c 'import os
last=set(os.listdir("/proc")) ; o=x=""
while True:
 pids=set(os.listdir("/proc"))
 new=pids.difference(last);last=pids
 for n in new:
  try: o,x=x,[j for j in open("/proc/"+n+"/cmdline")
    .read().split(chr(0)) if j]
  except IOError: pass
  if x and not o==x: print n,x' ; }

pstail

Ayrıca execsnoop, hangi argümanın hangisinin olduğunu daha açık bir şekilde söyleyebilmek için yama yapabilirsiniz :grep -v sub.*arg < execsnoop > n && chmod +x n && mv n execsnoop


1

CONFIG_FTRACEve CONFIG_KPROBESboyuncabrendangregg/perf-tools

git clone https://github.com/brendangregg/perf-tools.git
cd perf-tools
git checkout 98d42a2a1493d2d1c651a5c396e015d4f082eb20
sudo ./execsnoop

Başka bir kabukta:

while true; do sleep 1; date; done

İlk kabuk, format verilerini gösterir:

Tracing exec()s. Ctrl-C to end.                                                        
Instrumenting sys_execve                                                               
   PID   PPID ARGS 
 20109   4336 date                                                                                       
 20110   4336 sleep 1                                                                                    
 20111   4336 date                                                                                                                                                                                                 
 20112   4336 sleep 1                                                                                    
 20113   4336 date                                                                                       
 20114   4336 sleep 1                                                                                    
 20115   4336 date                                                                                       
 20116   4336 sleep 1

CONFIG_PROC_EVENTS

Örnek oturum:

$ su
# ./proc_events &
# /proc_events.out &
set mcast listen ok
# sleep 2 & sleep 1 &
fork: parent tid=48 pid=48 -> child tid=56 pid=56
fork: parent tid=48 pid=48 -> child tid=57 pid=57
exec: tid=57 pid=57
exec: tid=56 pid=56
exit: tid=57 pid=57 exit_code=0
exit: tid=56 pid=56 exit_code=0

CONFIG_PROC_EVENTSolayları kullanıcı topluluğuna bir netlink soketi aracılığıyla gösterir .

proc_events.c adapte edilmiştir: https://bewareofgeek.livejournal.com/2945.html

#define _XOPEN_SOURCE 700
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/connector.h>
#include <linux/cn_proc.h>
#include <signal.h>
#include <errno.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

static volatile bool need_exit = false;

static int nl_connect()
{
    int rc;
    int nl_sock;
    struct sockaddr_nl sa_nl;

    nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
    if (nl_sock == -1) {
        perror("socket");
        return -1;
    }
    sa_nl.nl_family = AF_NETLINK;
    sa_nl.nl_groups = CN_IDX_PROC;
    sa_nl.nl_pid = getpid();
    rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
    if (rc == -1) {
        perror("bind");
        close(nl_sock);
        return -1;
    }
    return nl_sock;
}

static int set_proc_ev_listen(int nl_sock, bool enable)
{
    int rc;
    struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
        struct nlmsghdr nl_hdr;
        struct __attribute__ ((__packed__)) {
            struct cn_msg cn_msg;
            enum proc_cn_mcast_op cn_mcast;
        };
    } nlcn_msg;

    memset(&nlcn_msg, 0, sizeof(nlcn_msg));
    nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
    nlcn_msg.nl_hdr.nlmsg_pid = getpid();
    nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;

    nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
    nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
    nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);

    nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;

    rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
    if (rc == -1) {
        perror("netlink send");
        return -1;
    }

    return 0;
}

static int handle_proc_ev(int nl_sock)
{
    int rc;
    struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
        struct nlmsghdr nl_hdr;
        struct __attribute__ ((__packed__)) {
            struct cn_msg cn_msg;
            struct proc_event proc_ev;
        };
    } nlcn_msg;
    while (!need_exit) {
        rc = recv(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
        if (rc == 0) {
            /* shutdown? */
            return 0;
        } else if (rc == -1) {
            if (errno == EINTR) continue;
            perror("netlink recv");
            return -1;
        }
        switch (nlcn_msg.proc_ev.what) {
            case PROC_EVENT_NONE:
                printf("set mcast listen ok\n");
                break;
            case PROC_EVENT_FORK:
                printf("fork: parent tid=%d pid=%d -> child tid=%d pid=%d\n",
                        nlcn_msg.proc_ev.event_data.fork.parent_pid,
                        nlcn_msg.proc_ev.event_data.fork.parent_tgid,
                        nlcn_msg.proc_ev.event_data.fork.child_pid,
                        nlcn_msg.proc_ev.event_data.fork.child_tgid);
                break;
            case PROC_EVENT_EXEC:
                printf("exec: tid=%d pid=%d\n",
                        nlcn_msg.proc_ev.event_data.exec.process_pid,
                        nlcn_msg.proc_ev.event_data.exec.process_tgid);
                break;
            case PROC_EVENT_UID:
                printf("uid change: tid=%d pid=%d from %d to %d\n",
                        nlcn_msg.proc_ev.event_data.id.process_pid,
                        nlcn_msg.proc_ev.event_data.id.process_tgid,
                        nlcn_msg.proc_ev.event_data.id.r.ruid,
                        nlcn_msg.proc_ev.event_data.id.e.euid);
                break;
            case PROC_EVENT_GID:
                printf("gid change: tid=%d pid=%d from %d to %d\n",
                        nlcn_msg.proc_ev.event_data.id.process_pid,
                        nlcn_msg.proc_ev.event_data.id.process_tgid,
                        nlcn_msg.proc_ev.event_data.id.r.rgid,
                        nlcn_msg.proc_ev.event_data.id.e.egid);
                break;
            case PROC_EVENT_EXIT:
                printf("exit: tid=%d pid=%d exit_code=%d\n",
                        nlcn_msg.proc_ev.event_data.exit.process_pid,
                        nlcn_msg.proc_ev.event_data.exit.process_tgid,
                        nlcn_msg.proc_ev.event_data.exit.exit_code);
                break;
            default:
                printf("unhandled proc event\n");
                break;
        }
    }

    return 0;
}

static void on_sigint(__attribute__ ((unused)) int unused)
{
    need_exit = true;
}

int main()
{
    int nl_sock;
    int rc = EXIT_SUCCESS;

    signal(SIGINT, &on_sigint);
    siginterrupt(SIGINT, true);
    nl_sock = nl_connect();
    if (nl_sock == -1)
        exit(EXIT_FAILURE);
    rc = set_proc_ev_listen(nl_sock, true);
    if (rc == -1) {
        rc = EXIT_FAILURE;
        goto out;
    }
    rc = handle_proc_ev(nl_sock);
    if (rc == -1) {
        rc = EXIT_FAILURE;
        goto out;
    }
    set_proc_ev_listen(nl_sock, false);
out:
    close(nl_sock);
    exit(rc);
}

GitHub upsatream .

Ancak exec_proc_eventçok az veri içerdiğinden UID ve işlem argümanları gibi işlem verilerini alabileceğinizi sanmıyorum : https://github.com/torvalds/linux/blob/v4.16/include/uapi/linux/cn_proc .h # L80 Hemen okumayı deneyebiliriz /proc, ancak işlemin bitmesi ve bir başkasının PID'sini alma riski vardır, bu nedenle güvenilir olmaz.

Ubuntu 17.10'da test edilmiştir.


0

Ayrıca, kaynak kullanımı süreçlerini görüntülemek için üstüne kullanabilirsiniz . Bu, zamanın her bir bölümünde kaynak kullanımını günlüğe kaydetmek ve analiz etmek için faydalı bir araçtır.


-3

Deneyebilirsin cat ~/.bash_history Var system log viewer, bu size yardımcı olabilir.


1
~/.bash_historygörünüşe göre sadece bir terminalde yürüttüğüm komutları içeriyor. Yürütülen tüm programların bir günlüğünü arıyorum, örneğin e-posta istemcimi açmak için bir simgeye tıkladığımda, gedit veya tarayıcımı açtığımda ve tarayıcım kendi başına başka bir işlemi yürütüyor. new123456'nın cevabı hile yaptı.
19'da runeks

1
Ayrıca, komutun historybu bilgilere erişmenin normal yolu olduğunu ekleyelim .
bryn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.