Systemd

記錄在任何 shell 中鍵入的每個命令:輸出(從記錄器函式到 syslog-ng/journald)包含重複的命令條目?

  • April 6, 2019

我安裝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

然後,如鍊接文章中所述,您必須添加在 .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

原始文件中使用了一個長連字元(錯誤地?),後跟一個空格和 $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); };

值得注意的是來自 Arch wiki 的關於參考行為不當和禁止在啟動時載入 syslog-ng 的評論。unix-stream更改對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.

我在 /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  <---

或者,如果我使用 禁用 syslog-ng ,我會使用(或獲取詳細資訊)systemctl stop syslog-ng從日誌二進制日誌中獲得完全相同的輸出,因為在這種情況下 systemd “接管”了。重新啟動和/或其套接字會立即回收輸出並將其發送到其配置中指定的分類文件。journalctl -fjournalctl -f -o verbose``syslog-ng

問題

  • 無論我使用 syslog-ng 還是 journald,我都會在日誌中得到很多重複的行,而這些命令只執行一次。ls例如,當我使用許多終端視窗時,列出目錄的內容可能會在日誌中顯示2-3 次。特別是,在 CLI 中按 enter 似乎會回顯日誌中的最後一個命令。為什麼?(是不是因為trap中的變數仍然設置為歷史文件的最後一行?如果是這樣如何補救?)

主要來源連結表明,從 4.1 版開始,bash可以直接寫入 syslog …… changelog說:

“有一個新的配置選項(在 config-top.h 中)強制 bash 將所有歷史條目轉發到 syslog。”

  • 那麼這裡使用的陷阱功能仍然有用還是已經過時了?這樣做是一種更現代/優雅的方式嗎?>4.1 選項是否暴露在某處,或者您是否需要重新編譯 bash 才能做到這一點?它是什麼?
  • 除了 bash 原生的內置選項之外,我們是否可以期望為 bash 實現類似的解決方案zsh?或者,是否有更好、更綜合的方法來做到這一點?
  • 將所有命令發送到日誌是否會產生大量成本,並且在這方面日誌和 syslog-ng 是否相等?

你有很多事情要做…..我對此的最佳答案是簡單地解釋我過去是如何看到會話記錄的。希望這會給你一些探索的選擇。

  1. 正如您已經提到的,bash history從使用者帳戶中提取。這僅在會話結束後有效。不是最好的選擇,但它既簡單又可靠。
  2. 在 Linux 中使用virtual terminal諸如命令。screen這不是很健壯,因為它在使用者登錄時開始,但是如果他們知道它正在被記錄,您仍然可以終止該服務。這在最終使用者場景中效果很好。最終使用者通常無論如何都被困在一個特定的區域,並且沒有知識來解決這個問題。
  3. Pam_tty_audit 模組 &aureport --tty這是一個工具,允許您指定哪些使用者被記錄,並允許您指定所述日誌的儲存位置……一如既往地保持主機伺服器的日誌關閉。我將 SFTP 伺服器上的會話日誌複製到中央日誌伺服器和本地 cronjob 將它們移動到非共享位置進行存檔。

這是為 RedHat 和 Fedora 內置的,但是您可以在 Debian 和 Ubuntu 上安裝它。我相信它是 auditd 包的一部分。以下是關於pam 的一些文件auditd和所需的配置更改(在 /etc/pam.d/system-auth 中),在此處指定單個使用者(root):

session required pam_tty_audit.so disable=* enable=root

的範例輸出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> 

引用自:https://unix.stackexchange.com/questions/111460