Saya ingin mendapatkan log dari semua proses yang diluncurkan dengan waktu mereka diluncurkan dan argumen mereka diluncurkan. Apakah ini mungkin di Linux?
Saya ingin mendapatkan log dari semua proses yang diluncurkan dengan waktu mereka diluncurkan dan argumen mereka diluncurkan. Apakah ini mungkin di Linux?
Jawaban:
Titik awal Anda harus diaudit.
Coba sesuatu seperti ini:
apt-get install auditd
auditctl -a task,always
ausearch -i -sc execve
chmod 0750 /sbin/audispd
tetapi masih tidak berfungsi (Debian Wheezy)
Unable to set audit pid, exiting
tetapi saya kira masalah sebenarnya adalah bahwa sistem tersebut berjalan dalam wadah LXC
Saya perlu melakukan ini, kecuali (1) Saya tidak membutuhkan waktu dan (2) Saya hanya tertarik pada proses yang dimulai oleh proses tertentu, dan anak-anaknya serta keturunan selanjutnya. Juga, di lingkungan saya menggunakan, itu tidak mungkin untuk mendapatkan auditd
atau accton
, tapi ada valgrind
.
Awali yang berikut ini ke proses yang menarik di baris perintah:
valgrind --trace-children=yes
Informasi yang Anda butuhkan ada di log output yang ditampilkan di STDERR.
memcheck
alat ini. Untuk menonaktifkan alat dan logging terkait, dan hanya mencetak penciptaan perintah baru (selain output biasa program anda), gunakan perintah berikut ini sebagai gantinya: valgrind --tool=none --trace-children=yes [command and args here]
. Setiap kali subproses muncul, Valgrind kemudian akan mencatat perintah lengkap, termasuk argumen yang diteruskan ke sana.
Anda bisa menggunakan snoopy untuk ini.
Sangat mudah untuk menginstal, dan karena 2.x dapat mencatat data sewenang-wenang (argumen, variabel lingkungan, cwd, dll.).
Pengungkapan: Snoopy maintainer di sini.
Anda dapat menjalankan startmon dan mengikuti output standarnya, Ctrl-C saat selesai. Berikut ini cara mengkompilasi dan menjalankan startmon pada distro yang diturunkan Red Hat baru-baru ini (RHEL, Fedora, CentOS):
sudo yum install git cmake gcc-c++
git clone https://github.com/pturmel/startmon
cd startmon
cmake .
make
sudo ./startmon -e
Pada Debian (dan Ubuntu dll), baris pertama dari perubahan di atas menjadi:
sudo apt-get install git cmake g++
Atau Anda dapat mencoba execsnoop
skrip di perf-tools, lihat jawaban ini . Secara default hanya 8 argumen pertama yang ditampilkan (9 termasuk nama program); Anda dapat meningkatkan ini melalui
sudo ./execsnoop -a 16
Jika Anda tidak memiliki akses root ke sistem, yang terbaik yang dapat Anda lakukan adalah tetap melakukan polling /proc
dan berharap itu menangkap segalanya (yang tidak akan terjadi), tetapi untuk kelengkapannya adalah skrip untuk melakukan itu (saya telah membuat duplikat-penghapusan untuk menyederhanakan output) - walaupun ini tidak sebagus melacak mereka dengan benar dengan salah satu metode di atas, itu memang memiliki sedikit keuntungan menampilkan pemisah antara argumen baris perintah, jika Anda perlu memberitahu perbedaan antara spasi di dalam argumen dan ruang antara argumen. Script ini tidak efisien karena menggunakan CPU (well, salah satu core-nya) 100% dari waktu.
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
Anda juga dapat menambal execsnoop
untuk memberi tahu Anda secara lebih eksplisit argumen mana yang:grep -v sub.*arg < execsnoop > n && chmod +x n && mv n execsnoop
CONFIG_FTRACE
dan CONFIG_KPROBES
melaluibrendangregg/perf-tools
git clone https://github.com/brendangregg/perf-tools.git
cd perf-tools
git checkout 98d42a2a1493d2d1c651a5c396e015d4f082eb20
sudo ./execsnoop
Di shell lain:
while true; do sleep 1; date; done
Shell pertama menunjukkan data format:
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
Sesi sampel:
$ 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_EVENTS
mengekspos peristiwa ke userland melalui soket netlink .
proc_events.c diadaptasi dari: 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);
}
Namun saya tidak berpikir bahwa Anda dapat memperoleh data proses seperti UID dan memproses argumen karena exec_proc_event
mengandung data yang sangat sedikit: https://github.com/torvalds/linux/blob/v4.16/include/uapi/linux/cn_proc .h # L80 Kita dapat mencoba untuk segera membacanya /proc
, tetapi ada risiko bahwa proses selesai dan yang lain mengambil PID-nya, sehingga tidak dapat diandalkan.
Diuji di Ubuntu 17.10.
Anda dapat mencoba cat ~/.bash_history
Ada system log viewer
, ini dapat membantu Anda keluar.
~/.bash_history
hanya berisi perintah yang sudah saya jalankan di terminal, rupanya. Saya mencari log semua program yang dijalankan, misalnya ketika saya mengklik ikon untuk membuka klien email saya, gedit, atau saya membuka browser saya, dan browser saya menjalankan proses lain dengan sendirinya. jawaban new123456 berhasil.
history
adalah cara biasa mengakses informasi ini.
The audit system is disabled
Di mana saya bisa mengaktifkannya?