14.5.配置系统日志

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

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

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

14.5.1.配置本地日志

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

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

# $FreeBSD$
#
#       Spaces ARE valid field separators in this file. However,
#       other *nix-like systems still insist on using tabs as field
#       separators. If you are sharing this file between systems, you
#       may want to use only tabs as field separators here.
#       Consult the syslog.conf(5) manpage.
*.err;kern.warning;auth.notice;mail.crit                /dev/console
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err   /var/log/messages
security.*                                      /var/log/security
auth.info;authpriv.info                         /var/log/auth.log
mail.info                                       /var/log/maillog
lpr.info                                        /var/log/lpd-errs
ftp.info                                        /var/log/xferlog
cron.*                                          /var/log/cron
!-devd
*.=debug                                        /var/log/debug.log
*.emerg                                         *
# uncomment this to log all writes to /dev/console to /var/log/console.log
#console.info                                   /var/log/console.log
# uncomment this to enable logging of all log messages to /var/log/all.log
# touch /var/log/all.log and chmod it to mode 600 before it will work
#*.*                                            /var/log/all.log
# uncomment this to enable logging to a remote loghost named loghost
#*.*                                            @loghost
# uncomment these if you're running inn
# news.crit                                     /var/log/news/news.crit
# news.err                                      /var/log/news/news.err
# news.notice                                   /var/log/news/news.notice
# Uncomment this if you wish to see messages produced by devd
# !devd
# *.>=info
!ppp
*.*                                             /var/log/ppp.log
!*

在这个例子中:

  • 第 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 , infodebug

设施无特定顺序,有 auth, authpriv, console, cron, daemon, ftp, kern, lpr, mail, mark, news, security, syslog, user, uucplocal0local7。请注意,其他操作系统可能有不同的设施。

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

daemon.notice                                        /var/log/daemon.log

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

14.5.2.日志管理和轮替

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

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

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

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

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

14.5.3.配置远程日志

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

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

14.5.3.1.日志服务器的配置

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

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

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

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

例 24. 日志服务器配置的示例

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

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

接下来配置 /etc/rc.conf

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

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

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

最后,创建日志文件:

# touch /var/log/logclient.log

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

# service syslogd restart
# pgrep syslog

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

14.5.3.2.日志客户端的配置

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

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

syslogd_enable="YES"
syslogd_flags="-s -v -v"

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

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

*.*     @logserv.example.com

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

# service syslogd restart

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

# logger "Test message from logclient"

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

14.5.3.3.调试日志客户端

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

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

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

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

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

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

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

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

14.5.3.4.安全事项

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

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