记录在任何 shell 中键入的每个命令:输出(从记录器函数到 syslog-ng/journald)包含命令的重复条目?

5 syslog-ng systemd audit systemd-journald

我安装syslog-ng在我的桌面上使用(Gentoo 64 位,升级到 systemd,即之前是 OpenRC ,只有 Openbox 和 Slim)与我的普通用户一起记录我在 shell 中输入的所有命令(首先是 bash,然后是 zsh)。我探索了不同的解决方案,以及不同的设置方法,无论是旧的还是新的,这通常是使用.bash_history文件来实现的。我试图从几年前开始实施这个解决方案,依赖于配套陷阱。首先,我修改.bashrc并设置了一些历史变量,因为该解决方案依赖于格式化历史数据,然后确保将其保存到其文件中,然后推送它通过logger在 shell 环境中调用的函数发送到日志消息传递系统。所以首先是变量:

export HISTCONTROL=
export HISTFILE=$HOME/.bash_history
export HISTFILESIZE=2000
export HISTIGNORE=
export HISTSIZE=1000
export HISTTIMEFORMAT="%a %b %Y %T %z "

typeset -r HISTCONTROL
typeset -r HISTFILE
typeset -r HISTFILESIZE
typeset -r HISTIGNORE
typeset -r HISTSIZE
typeset -r HISTTIMEFORMAT

shopt -s cmdhist
shopt -s histappend

PROMPT_COMMAND="history -a"
typeset -r PROMPT_COMMAND

ex. history command output with timestamps
860  Tue Jan 2014 10:33:50 -0900 exit
861  Tue Jan 2014 10:33:56 -0900 ls
862  Tue Jan 2014 10:33:58 -0900 history
Run Code Online (Sandbox Code Playgroud)

然后,如链接文章中所述,您必须添加在 .bashrc中使用的这个陷阱logger(有对 /etc/profile 的引用,但在这里我只希望我的普通用户使用它,而 ~/.profile不是来自类似的东西lxterminal):

function log2syslog
{
   declare command
   command=$(fc -ln -0)
   logger -p local1.notice -t bash -i -- $USER : $command
}
trap log2syslog DEBUG
Run Code Online (Sandbox Code Playgroud)

在原始文档中(错误地?)使用了一个长连字符,后跟一个空格和 $USER。

我已经替换了我原来的 syslog-ng 配置文件。我已经尝试了Arch建议的配置,但是在一些警告之后,我已经像对 Gentoo解释的那样配置了它,这也是 Arch 文档所基于的:

@version: 3.4
options {
        chain_hostnames(no);

        # The default action of syslog-ng is to log a STATS line
        # to the file every 10 minutes.  That's pretty ugly after a while.
        # Change it to every 12 hours so you get a nice daily update of
        # how many messages syslog-ng missed (0).
        stats_freq(43200);
};

source src {
    unix-dgram("/dev/log" max-connections(256));
    internal();
};

source kernsrc { file("/proc/kmsg"); };

# define destinations
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination mail { file("/var/log/mail.log"); };

destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };
destination console { usertty("root"); };

# By default messages are logged to tty12...
destination console_all { file("/dev/tty12"); };

# ...if you intend to use /dev/console for programs like xconsole
# you can comment out the destination line above that references /dev/tty12
# and uncomment the line below.
#destination console_all { file("/dev/console"); };

# create filters
filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(authpriv, mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info..warn)
        and not facility(auth, authpriv, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };
filter f_failed { message("failed"); };
filter f_denied { message("denied"); };

# connect filter and destination
log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
log { source(src); filter(f_daemon); destination(daemon); };
log { source(kernsrc); filter(f_kern); destination(kern); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };

log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

# default log
log { source(src); destination(console_all); };
Run Code Online (Sandbox Code Playgroud)

值得注意的是,评论了来自Arch维基有关unix-stream参考行为不端,并禁止在启动时加载的syslog-ng的。更改对unix-dgram的引用基本上是所用模型的唯一更改,除了在第一行提供版本号。之后,您可以systemctl enable syslog-ng在启动时使用它。

所以它在这里手动启动并运行:

# systemctl status syslog-ng
syslog-ng.service - System Logger Daemon
   Loaded: loaded (/usr/lib64/systemd/system/syslog-ng.service; disabled)
   Active: active (running) since Tue 2014-01-28 20:23:36 EST; 1s ago
     Docs: man:syslog-ng(8)
 Main PID: 9238 (syslog-ng)
   CGroup: /system.slice/syslog-ng.service
           \u2514\u25009238 /usr/sbin/syslog-ng -F

Jan 28 20:23:36 gentoouser3x86_64 systemd[1]: Starting System Logger Daemon...
Jan 28 20:23:36 gentoouser3x86_64 systemd[1]: Started System Logger Daemon.
Run Code Online (Sandbox Code Playgroud)

我在 /var/log/messages 中得到了所需的基本输出:

Jan 28 20:42:00 gentoouser3x86_64 bash[9878]: myuser : shopt
Jan 28 20:42:04 gentoouser3x86_64 bash[9880]: myuser : su -
...
Jan 29 03:30:58 gentoouser3x86_64 bash[4386]: myuser : ls
Jan 29 03:30:58 gentoouser3x86_64 bash[4389]: myuser : ls  <--- duplicate
Jan 29 03:30:58 gentoouser3x86_64 bash[4391]: myuser : ls  <--- entries
Jan 29 04:36:31 gentoouser3x86_64 bash[4491]: myuser : cat .bashrc
Jan 29 04:37:14 gentoouser3x86_64 bash[4495]: myuser : cat .bashrc  <---
Jan 29 04:37:14 gentoouser3x86_64 bash[4497]: myuser : cat .bashrc  <---
Jan 29 04:37:35 gentoouser3x86_64 bash[4500]: myuser : nedit .bashrc
Jan 29 04:37:35 gentoouser3x86_64 bash[4503]: myuser : nedit .bashrc  <---
Jan 29 04:37:35 gentoouser3x86_64 bash[4505]: myuser : nedit .bashrc  <---
Run Code Online (Sandbox Code Playgroud)

或者,如果我使用 禁用 syslog-ng systemctl stop syslog-ng,我会使用journalctl -f(或journalctl -f -o verbose详细信息)从日志二进制日志中获得完全相同的输出,因为在这种情况下systemd “接管”了。重新启动syslog-ng和/或其套接字立即回收输出并将其发送到其配置中指定的分类文件。

问题

  • 无论我使用 syslog-ng 还是 journald,我都会在日志中得到很多重复的行,而这些命令只执行了一次。例如ls,当我使用许多终端窗口时,列出目录的内容可能会在日志中显示2-3 次。特别是,在 CLI 中按 Enter 似乎会回显日志中的最后一个命令。为什么?(是不是因为陷阱中的变量仍然设置为历史文件的最后一行?如果是这样,如何补救?)

主要源链接表明,从 4.1 版开始,bash可以直接写入 syslog ......更改日志说:

“有一个新的配置选项(在 config-top.h 中)可以强制 bash 将所有历史条目转发到 syslog。”

  • 那么这里使用的trap函数是否仍然有用还是已经过时了?这样做是一种更现代/优雅的方式吗?> 4.1 选项是否在某处公开,或者您是否需要重新编译 bash 才能做到这一点?它是什么?
  • 除了 bash 原生的内置选项之外,我们是否可以期望为zsh? 或者,有没有更好、更综合的方法来做到这一点?
  • 将所有命令发送到日志是否会产生大量开销,并且在这方面 journald 和 syslog-ng 是否相等?

Daf*_*Duc 5

你有很多事情要做..... 我最好的答案是简单地解释一下我过去是如何看到会话日志记录的。希望这会给你一些探索的选择。

  1. 正如您已经提到的,bash history从用户帐户中提取。这仅在会话结束后有效。不是真正的最佳选择,但它简单可靠。
  2. 在 Linux 中使用virtual terminal诸如此类的screen命令。这不是很健壮,因为它在用户登录时开始,但是如果他们知道它正在被记录,您仍然可以终止该服务。这在最终用户场景中运行良好。无论如何,最终用户通常都被困在指定的区域内,并且没有解决这个问题的知识。
  3. Pam_tty_audit 模块 &aureport --tty这是一个工具,它允许您指定哪些用户被记录并允许您指定所述日志的存储位置......始终保持日志远离主机服务器。我将 SFTP 服务器上的会话日志复制到中央日志服务器和本地 cronjob 将它们移动到非共享位置进行存档。

这是为 RedHat 和 Fedora 内置的,但是您可以在 Debian 和 Ubuntu 上安装它。我相信它是 auditd 软件包的一部分。下面是一些关于pam所需配置更改的文档(在 /etc/pam.d/system-auth 中),在此处指定单个用户(root):auditd

session required pam_tty_audit.so disable=* enable=root
Run Code Online (Sandbox Code Playgroud)

示例输出aureport --tty

TTY Report
===============================================
# date time event auid term sess comm data
===============================================
1. 1/29/2014 00:08:52 122249 0000 ? 4686960298 bash "ls -la",<ret> 
Run Code Online (Sandbox Code Playgroud)