12.7. 配置系统日志

生成和阅读系统日志是系统管理的一个重要内容。系统日志中的信息可以用来检测硬件和软件问题,以及应用程序和系统配置错误。这些信息在安全审计和事件响应中也起着重要作用。大多数系统守护程序和应用程序都会产生日志。

FreeBSD 提供了一个系统日志记录器 syslogd 来管理日志记录。默认情况下,syslogd 在系统启动时被启动。这是由 /etc/rc.conf 中的变量 syslogd_enable 控制的。有许多应用参数可以使用 /etc/rc.conf 中的 syslogd_flags 来设置。关于可用参数的更多信息,请参考 syslogd(8) 的手册页面。

这一节描述了如何为本地和远程 FreeBSD 系统配置日志,以及如何进行日志轮换和日志管理。

12.7.1. 配置本地日志

配置文件 /etc/syslog.conf,可控制 syslogd 在收到日志条目时的处理方式。有几个参数可以控制对传入事件的处理。设施描述了哪个子系统产生了消息,如内核或守护进程,级别描述了所发生事件的严重程度。这使得我们可以根据设施和级别来配置是否和在哪里记录日志信息。也可以根据发送消息的应用程序采取相应的行动,在远程日志的情况下,还可以根据产生日志事件的机器的主机名采取行动。

这个配置文件包含每个行动的一行,每一行的语法是一个选择器字段,然后是一个行动字段。选择器字段的语法是 facility.level,它将匹配来自 level 级别或更高的设施的日志信息。也可以在级别前添加一个可选的比较标志,以更精确地指定记录的内容。多个选择器字段可以用于同一个动作,并以分号(;)分开。使用*将匹配所有的内容。动作字段表示要将日志信息发送到哪里,比如发送到文件或远程日志主机。作为一个例子,这里是 FreeBSD 的默认 syslog.conf

  1. # $FreeBSD$
  2. #
  3. # Spaces ARE valid field separators in this file. However,
  4. # other *nix-like systems still insist on using tabs as field
  5. # separators. If you are sharing this file between systems, you
  6. # may want to use only tabs as field separators here.
  7. # Consult the syslog.conf(5) manpage.
  8. *.err;kern.warning;auth.notice;mail.crit /dev/console
  9. *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err /var/log/messages
  10. security.* /var/log/security
  11. auth.info;authpriv.info /var/log/auth.log
  12. mail.info /var/log/maillog
  13. lpr.info /var/log/lpd-errs
  14. ftp.info /var/log/xferlog
  15. cron.* /var/log/cron
  16. !-devd
  17. *.=debug /var/log/debug.log
  18. *.emerg *
  19. # uncomment this to log all writes to /dev/console to /var/log/console.log
  20. #console.info /var/log/console.log
  21. # uncomment this to enable logging of all log messages to /var/log/all.log
  22. # touch /var/log/all.log and chmod it to mode 600 before it will work
  23. #*.* /var/log/all.log
  24. # uncomment this to enable logging to a remote loghost named loghost
  25. #*.* @loghost
  26. # uncomment these if you're running inn
  27. # news.crit /var/log/news/news.crit
  28. # news.err /var/log/news/news.err
  29. # news.notice /var/log/news/news.notice
  30. # Uncomment this if you wish to see messages produced by devd
  31. # !devd
  32. # *.>=info
  33. !ppp
  34. *.* /var/log/ppp.log
  35. !*

在这个例子中:

  • 第8行匹配所有级别为 err 或更高的消息,以及 kern.warningauth.noticemail.crit,并将这些日志消息发送到控制台(/dev/console )。
  • 第12行匹配来自邮件设施的所有信息,级别为 info 或以上,并将这些信息记录到 /var/log/maillog
  • 第17行使用一个比较标志(= ),只匹配 debug 级别的消息,并将它们记录到 /var/log/debug.log
  • 第33行是一个使用程序规范的例子。这使得它后面的规则只对指定的程序有效。在这种情况下,只有 ppp 产生的消息被记录到 /var/log/ppp.log 中。

可用的级别中,从最严重到最不严重的顺序是:emerg , alert , crit , err , warning , notice , info , 和 debug

设施(facilities),没有特别的顺序,是 auth, authpriv, console, cron, daemon, ftp, kern, lpr, mail, mark, news, security, syslog, user, uucp, 和 local0local7。请注意,其他操作系统可能有不同的设施。

要把所有通知级别及以上的内容记录到 /var/log/daemon.log,请添加以下条目:

  1. daemon.notice /var/log/daemon.log

更多关于不同级别和设施的信息,请参考 syslog(3)syslogd(8) 的命令手册。更多关于 /etc/syslog.conf 的信息、语法和高级使用示例,请参见 syslog.conf(5) 的命令手册。

12.7.2. 日志管理和轮换

日志文件会迅速增长,占用磁盘空间,使查找有用信息更加困难。日志管理试图缓解这种情况。在 FreeBSD 中,newsyslog 被用来管理日志文件。这个内置的程序周期性地旋转和压缩日志文件,并且可以选择创建缺失的日志文件,在日志文件被移动时向程序发出信号。日志文件可以由 syslogd 或任何其他生成日志文件的程序生成。虽然 newsyslog 通常从 cron(8) 运行,但它不是一个系统守护程序。在默认配置中,它每小时运行一次。

为了知道要采取哪些行动,newsyslog 会读取其配置文件 /etc/newsyslog.conf。该文件为 newsyslog 管理的每个日志文件包含一行。每一行都说明了文件的所有者、权限、何时轮换该文件、影响日志轮换的可选标志(如压缩)以及日志轮换时的信号程序。下面是 FreeBSD 中的默认配置:

  1. # configuration file for newsyslog
  2. # $FreeBSD$
  3. #
  4. # Entries which do not specify the '/pid_file' field will cause the
  5. # syslogd process to be signalled when that log file is rotated. This
  6. # action is only appropriate for log files which are written to by the
  7. # syslogd process (ie, files listed in /etc/syslog.conf). If there
  8. # is no process which needs to be signalled when a given log file is
  9. # rotated, then the entry for that file should include the 'N' flag.
  10. #
  11. # The 'flags' field is one or more of the letters: BCDGJNUXZ or a '-'.
  12. #
  13. # Note: some sites will want to select more restrictive protections than the
  14. # defaults. In particular, it may be desirable to switch many of the 644
  15. # entries to 640 or 600. For example, some sites will consider the
  16. # contents of maillog, messages, and lpd-errs to be confidential. In the
  17. # future, these defaults may change to more conservative ones.
  18. #
  19. # logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
  20. /var/log/all.log 600 7 * @T00 J
  21. /var/log/amd.log 644 7 100 * J
  22. /var/log/auth.log 600 7 100 @0101T JC
  23. /var/log/console.log 600 5 100 * J
  24. /var/log/cron 600 3 100 * JC
  25. /var/log/daily.log 640 7 * @T00 JN
  26. /var/log/debug.log 600 7 100 * JC
  27. /var/log/kerberos.log 600 7 100 * J
  28. /var/log/lpd-errs 644 7 100 * JC
  29. /var/log/maillog 640 7 * @T00 JC
  30. /var/log/messages 644 5 100 @0101T JC
  31. /var/log/monthly.log 640 12 * $M1D0 JN
  32. /var/log/pflog 600 3 100 * JB /var/run/pflogd.pid
  33. /var/log/ppp.log root:network 640 3 100 * JC
  34. /var/log/devd.log 644 3 100 * JC
  35. /var/log/security 600 10 100 * JC
  36. /var/log/sendmail.st 640 10 * 168 B
  37. /var/log/utx.log 644 3 * @01T05 B
  38. /var/log/weekly.log 640 5 1 $W6D0 JN
  39. /var/log/xferlog

每一行都以要轮换的日志名称开始,后面可以选择轮换的和新创建的文件的所有者和组。mode字段设置日志文件的权限,count表示应该保留多少个轮换的日志文件。sizewhen 字段告诉 newsyslog 何时轮换文件。当一个日志文件的大小大于 size 字段或 when 字段中的时间已过,它就会被轮换。一个星号(*)意味着这个字段被忽略。标志字段给出了进一步的指示,比如如何压缩旋转的文件,或者在缺少日志文件的情况下如何创建。最后两个字段是可选的,指定一个进程的进程 ID( PID)文件的名称,以及当文件被旋转时要发送给该进程的信号号。

关于所有字段、有效标志以及如何指定轮换时间的更多信息,请参考 newsyslog.conf(5)。由于 newsyslog 是从 cron(8) 中运行的,它不能比从 cron(8) 中运行的计划更频繁地轮换文件。

12.7.3. 配置远程日志

随着系统数量的增加,监控多个主机的日志文件可能会变得很麻烦。配置集中式日志可以减少日志文件管理的一些管理负担。

在 FreeBSD 中,可以使用 syslogdnewsyslog 来配置集中的日志文件聚合、合并和旋转。本节演示了一个配置的例子,主机 A,名为 logserv.example.com,将收集本地网络的日志信息。主机B,名为 logclient.example.com,将被配置为将日志信息传递给日志服务器。

12.7.3.1. 日志服务器的配置

日志服务器是一个已被配置为接受来自其他主机的日志信息的系统。在配置日志服务器之前,请检查以下内容。

  • 如果在日志服务器和任何日志客户端之间有防火墙,确保防火墙规则集允许客户端和服务器使用UDP 514 端口。

  • 记录服务器和所有客户机必须在本地 DNS 中拥有正向和反向条目。如果网络没有 DNS 服务器,请在每个系统的 /etc/hosts 中创建条目。正确的名称解析是必需的,这样日志条目才不会被日志服务器拒绝。

在日志服务器上,编辑 /etc/syslog.conf 以指定接收日志条目的客户端名称、要使用的日志设施、以及存储主机日志条目的日志名称。这个例子添加了B的主机名,记录了所有设施,并将日志条目存储在 /var/log/logclient.log 中。

实例1. 日志服务器配置的样例

  1. +logclient.example.com
  2. *.* /var/log/logclient.log

当添加多个日志客户端时,为每个客户端添加一个类似的双行条目。关于可用设施的更多信息可以在 syslog.conf(5) 中找到。

接下来配置 /etc/rc.conf

  1. syslogd_enable="YES"
  2. syslogd_flags="-a logclient.example.com -v -v"

第一个条目是在系统启动时启动 syslogd。第二个条目允许来自指定客户端的日志条目。-v -v增加了记录的消息的粗略程度。这对于调整设施是很有用的,因为管理员能够看到每个设施下记录的消息的类型。

可以指定多个 -a 选项以允许从多个客户端记录。IP 地址和整个网块也可以被指定。请参考 syslogd(8) 以获得可能的选项的完整列表。

最后,创建日志文件:

  1. # touch /var/log/logclient.log

在这一点上,应该重新启动syslogd并进行验证:

  1. # service syslogd restart
  2. # pgrep syslog

如果返回一个PID,说明服务器重启成功,可以开始客户端配置。如果服务器没有重启,请查阅 /var/log/messages 中的错误。

12.7.3.2. 日志客户端的配置

日志客户端将日志条目发送到网络上的一个日志服务器。客户端还保留一份自己的日志的本地副本。

配置了一个日志服务器后,就可以在日志客户端上编辑 /etc/rc.conf

  1. syslogd_enable="YES"
  2. syslogd_flags="-s -v -v"

第一个条目在开机时启用 syslogd。第二个条目防止该客户端接受来自其他主机的日志(-s),并增加了日志信息的粗略程度。

接下来,在客户端的 /etc/syslog.conf 中定义日志服务器。在这个例子中,所有记录的设施都被发送到一个远程系统,用 @ 符号表示,并指定了主机名。

  1. *.* @logserv.example.com

保存之后,重启 syslogd 来使其生效:

  1. # service syslogd restart

要测试日志信息是否在网络上被发送,请在客户端使用 logger(1)syslogd 发送一条信息:

  1. # logger "Test message from logclient"

这条信息现在应该同时存在于客户端的 /var/log/messages 和日志服务器的 /var/log/logclient.log

12.7.3.3. 调试日志客户端

如果在日志服务器上没有收到任何消息,那么原因很可能是网络连接问题、主机名解析问题或配置文件中的一个错字。为了隔离原因,确保日志服务器和日志客户端都能够使用它们的 /etc/rc.conf 中指定的主机名来 ping 对方。如果失败了,检查网络布线、防火墙规则集,以及日志服务器和客户端的 DNS 服务器或 /etc/hosts 中的主机名条目。重复进行,直到从两台主机上 ping 成功。

如果在两台主机上 ping 成功,但仍然没有收到日志信息,请暂时增加日志的粗略程度,以缩小配置问题。在下面的例子中,日志服务器上的 /var/log/logclient.log 是空的,而日志客户端上的 /var/log/messages 也没有指出失败的原因。为了增加调试输出,编辑日志服务器上的 syslogd_flags 条目,并发出重启信号:

  1. syslogd_flags="-d -a logclient.example.com -v -v"

重启后,类似以下的调试数据将立即在控制台出现:

  1. logmsg: pri 56, flags 4, from logserv.example.com, msg syslogd: restart
  2. syslogd: restarted
  3. logmsg: pri 6, flags 4, from logserv.example.com, msg syslogd: kernel boot file is /boot/kernel/kernel
  4. Logging to FILE /var/log/messages
  5. syslogd: kernel boot file is /boot/kernel/kernel
  6. cvthname(192.168.1.10)
  7. validate: dgram from IP 192.168.1.10, port 514, name logclient.example.com;
  8. rejected in rule 0 due to name mismatch.

在这个例子中,日志信息被拒绝是由于一个错字,导致主机名不匹配。客户端的主机名应该是 logclient ,而不是 logclien 。修正错别字,发出重启,并验证结果。

  1. # service syslogd restart
  2. logmsg: pri 56, flags 4, from logserv.example.com, msg syslogd: restart
  3. syslogd: restarted
  4. logmsg: pri 6, flags 4, from logserv.example.com, msg syslogd: kernel boot file is /boot/kernel/kernel
  5. syslogd: kernel boot file is /boot/kernel/kernel
  6. logmsg: pri 166, flags 17, from logserv.example.com,
  7. msg Dec 10 20:55:02 <syslog.err> logserv.example.com syslogd: exiting on signal 2
  8. cvthname(192.168.1.10)
  9. validate: dgram from IP 192.168.1.10, port 514, name logclient.example.com;
  10. accepted in rule 0.
  11. logmsg: pri 15, flags 0, from logclient.example.com, msg Dec 11 02:01:28 trhodes: Test message 2
  12. Logging to FILE /var/log/logclient.log
  13. Logging to FILE /var/log/messages

现在,信息被正确地接收并放在正确的文件中。

12.7.3.4. 出于安全的考虑

与任何网络服务一样,在实施日志服务器之前应考虑安全要求。日志文件可能包含关于本地主机上启用的服务、用户账户和配置数据的敏感数据。从客户端发送到服务器的网络数据将不会被加密或密码保护。如果存在加密的需要,考虑使用 安全/隧道(security/stunnel),它将通过加密的隧道传输日志数据。

本地安全也是一个问题。日志文件在使用过程中或在日志轮换后都没有加密。本地用户可能会访问日志文件,以获得对系统配置的额外洞察力。在日志文件上设置适当的权限是至关重要的。内置的日志轮换器,newsyslog,支持对新创建和轮换的日志文件设置权限。将日志文件设置为模式 600 应能防止本地用户的不必要的访问。请参阅 newsyslog.conf(5) 的手册以了解更多信息。