For the complete documentation index, see llms.txt. This page is also available as Markdown.

18.6 系统日志管理

本节介绍 FreeBSD 的系统日志管理。

配置本地日志记录

配置文件 /etc/syslog.conf 定义了 syslogd 在接收到日志条目时的处理方式。此文件通过 设施 facility级别 level 两个参数控制日志行为:

  • 设施 facility 标识消息来源的子系统(如内核或守护进程)。

  • 级别 level 表示事件的严重性。

可按 设施 facility级别 level 决定日志消息的记录位置,也可按发送消息的应用程序筛选日志消息。在远程日志记录中,还可按生成日志事件的主机名过滤。

该配置文件每行定义一个操作,由选择器字段和操作字段组成。

  • 选择器字段的语法是 设施.级别,匹配来自 设施 facility 且级别为 级别 level 或更高的日志消息。

    • 也可以在级别之前添加可选的比较标志,以更精确地指定记录内容。

    • 多个选择器字段可以用于同一操作

      • 以分号 (;) 分隔。

      • 使用 * 匹配所有内容。

  • 操作字段指定日志消息的发送目标,如文件或远程日志主机。

以下是 FreeBSD 默认的 /etc/syslog.conf 文件示例,其源文件为 usr.sbin/syslogd/syslog.conf

#
#	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 #
cron.*						/var/log/cron
!-devd
*.=debug					/var/log/debug.log #
*.emerg						*
daemon.info					/var/log/daemon.log
# uncomment this to log all writes to /dev/console to /var/log/console.log
# touch /var/log/console.log and chmod it to mode 600 before it will work
#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
# *.>=notice					/var/log/devd.log # ④
!*
include						/etc/syslog.d
include						/usr/local/etc/syslog.d
  • ① 匹配所有级别为 err 及更高的消息,以及 kern.warningauth.noticemail.crit,并将这些日志消息发送到控制台(/dev/console)。

  • ② 匹配来自 mail 子系统的所有级别为 info 或更高的消息,并将日志记录到 /var/log/maillog 文件。

  • ③ 使用比较标志 (=) 只匹配级别为 debug 的消息,并将其记录到 /var/log/debug.log 文件。

  • ④ 此示例演示了指定程序的用法:后续规则仅对指定程序生效。本例中,仅将 devd(8) 生成的消息记录到 /var/log/devd.log 文件。

日志记录设施

设施(facility)标识生成消息的子系统,用于将不同来源的消息分开,便于日志查阅。

表 syslog 设施

名称
说明

auth

授权系统:login(1)、su(1)、getty(8) 等。

authpriv

与 auth 相同,但日志记录到只有 root 可读的文件中。

console

由内核控制台输出驱动程序写入 /dev/console 的消息。

cron

由 cron(8) 守护进程写入的消息。

daemon

系统守护进程,例如 routed(8),此类进程没有专用的日志记录设施。

ftp

FTP 守护进程。

kern

由内核生成的消息。此类消息不能由任何用户进程生成。

lpr

打印机排队系统:lpr(1)、lpc(8)、lpd(8) 等。

mail

邮件系统。

mark

此设施每 20 分钟添加一条记录。

news

网络新闻系统。

ntp

网络时间协议系统。

security

安全子系统,例如 ipfw(4)。

syslog

syslogd(8) 内部生成的消息。

user

随机用户进程生成的消息。这是未指定时的默认设施标识符

uucp

UUCP 子系统。

local0 至 local7

保留给本地使用。

日志记录级别

级别(level)表示消息的严重性,以下是按优先级从高到低的关键词列表:

表 syslog 级别

名称
说明

emerg

紧急条件。通常广播给所有用户。

alert

须立即修正的条件,例如损坏的系统数据库。

crit

严重条件,例如硬件设备错误。

err

错误。

warning

警告消息。

notice

非错误条件,但可能需要特别处理的条件。

info

信息性消息。

debug

调试程序时方可发挥作用的消息。

none

此特殊级别禁用特定设施。

阅读日志消息

FreeBSD 的 syslogd(8) 支持两种输出格式,通过 -O 选项切换:

  • BSD/RFC 3164 格式(默认格式,-O bsd-O rfc3164):传统 BSD syslog 格式。

  • Syslog/RFC 5424 格式-O syslog-O rfc5424):较新的标准格式,采用 RFC 3339 时间戳(含微秒精度),并在每条消息中包含结构化的设施与严重级别字段。

RFC 3164 格式 的日志通常使用以下语法:

以下是 /var/log/cron 文件的输出示例:

可以通过运行以下命令在 syslogd(8) 中启用详细日志记录,此时每条消息将附带设施和级别:

启用此功能后,日志中将显示设施和级别,如下所示:

若要切换到 RFC 5424 格式,可以在 /etc/rc.conf 文件中配置:

以下是 RFC 5424 格式下 /var/log/cron 文件的输出示例:

RFC 5424 格式下默认启用详细日志记录,无需选项 -vv

日志管理与轮替

日志文件增长迅速,占用磁盘空间,且增加查找有效信息的难度。为此,FreeBSD 使用 newsyslog(8) 来管理日志文件。

newsyslog 定期轮替并压缩日志文件,可选择性地创建缺失的日志文件,并在日志文件移动时向程序发送信号。newsyslog 的默认配置源文件为 usr.sbin/newsyslog/newsyslog.conf

字段说明:

  • logfilename - 要归档的系统日志文件的名称。

  • [owner:group] - 指定归档文件的所有者和组。

  • mode - 指定日志文件和归档文件的文件模式。有效模式位为 0666,即可为归档日志指定所有者、组和其他用户的读写权限。

  • count - 指定可存在的最大归档文件数。

  • size - 日志文件的大小达到指定值(以 KB 为单位)时,将轮替日志文件。如果该字段包含星号(*),则不按大小轮替。

  • when - 包含时间间隔、特定时间或两者。

  • flags - 表示 newsyslog 接受的标志。

  • [/pid_file] - 指定包含守护进程的进程 ID 的文件名,或查找组进程 ID。

  • [sig_num] - 指定在轮替文件时将发送到守护进程的信号号。

技巧

最后两个字段 [/pid_file][sig_num] 是可选的,指定进程的 PID 文件名以及在轮替文件时发送给该进程的信号编号。

手动轮替日志

虽然 newsyslog(8) 默认由 cron(8) 每小时调用一次,但也可以使用选项 -F 手动触发轮替:

强制轮替所有满足条件的日志文件。轮替后的文件示例如下:

若要轮替特定文件,可指定文件路径:

轮替结果如下:

配置远程日志记录

系统数量增多后,监控多个主机的日志文件将增加管理负担。配置集中式日志记录可以减轻此负担。

在 FreeBSD 中,可以使用 syslogd 和 newsyslog 配置集中式日志文件聚合、合并和轮替。

本节的示例配置中,主机 A192.168.5.18)作为日志客户端,命名为 logclient.example.com

主机 A 将传递日志信息给日志服务器 B

设置 DNS 解析

日志服务器和所有客户端主机必须在本地 DNS 中具有正向和反向条目。如果网络没有 DNS 服务器,请在每个系统的 /etc/hosts 中创建条目。名称解析必须正确,以确保日志条目不会被日志服务器拒绝。

分别在日志客户端 A 和日志服务器 B 中的 /etc/hosts 文件添加以下两行:

技巧

上述示例中的 192.168.5.18192.168.5.17logclient.example.comlogserv.example.com 为占位符,须替换为实际的值。

其中主机 B 作为日志服务器(192.168.5.17),命名为 logserv.example.com,将收集本地网络的日志信息。

日志客户端配置

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

在日志客户端 A 上执行以下命令,设置 syslogd 开机自启:

阻止此客户端接收来自其他主机的日志(-s),同时增加日志消息的详细程度:

此后,在客户端的 /etc/syslog.conf 文件中定义日志服务器。在此示例中,所有记录的设施都通过 @ 符号发送到指定的主机:

保存编辑后,重新启动 syslogd 以使更改生效:

日志服务器配置

日志服务器是配置为接受来自其他主机日志信息的系统。

配置好日志客户端 A 后,在日志服务器 B 上,编辑 /etc/syslog.conf 文件:

以上示例在日志服务器的配置中,添加了日志客户端的主机名作为过滤条件。凡是来自主机 logclient.example.com 所有设施和级别的日志条目,都统一存储在服务器本地的 /var/log/logclient.log 文件中。

为每个客户端添加类似的两行条目便可添加多个日志客户端。

执行以下命令,设置 syslogd 开机自启:

允许来自指定客户端的日志条目:

  • -v -v 提高了日志消息的详细程度,有助于管理员查看每个设施下记录的消息类型。

  • 要允许来自多个客户端的日志记录,可以指定多个 -a 选项。还可以指定 IP 地址和整个网段。

最后,创建日志文件 logclient.log

此时,应重新启动 syslogd 并验证:

如果返回 PID,则表示服务器已成功重新启动。

如果服务器未能重新启动,请通过 /var/log/messages 文件获取错误信息。

为了测试日志消息是否通过网络发送,可以在客户端使用 logger(1) 发送一条消息到 syslogd:

此消息应同时存在于客户端的 /var/log/messages 文件和日志服务器的 /var/log/logclient.log 文件中。

调试日志服务器

如果日志服务器和日志客户端之间有防火墙,请确保防火墙规则集放行客户端和服务器之间的 UDP 端口 514。

如果日志服务器没有接收到任何消息,原因通常为网络连接问题、主机名解析问题或配置文件中的拼写错误。为排除故障,请确保日志服务器和日志客户端能够使用 /etc/rc.conf 文件中指定的主机名互相 ping。如果失败,请检查网络布线、防火墙规则集,以及日志服务器和客户端中的 DNS 服务器或 /etc/hosts 中的主机名条目。反复检查直至 ping 测试成功。

如果两个主机的 ping 都成功,但服务器仍未接收到日志消息,可临时提高日志详细度以缩小配置问题的范围。在以下示例中,日志服务器上的 /var/log/logclient.log 为空,而日志客户端上的 /var/log/messages 未显示失败原因。

为增加调试输出,编辑日志服务器上的 syslogd_flags 条目并执行重启:

警告 请首先尝试使用 IP 地址代替域名测试。

调试成功后必须修改回原有设置,否则将影响系统正常开机。

重启后,调试数据将立即输出到控制台,类似于以下内容:

此时,消息已正确接收并写入正确的文件。

安全考量

与所有网络服务一样,在实施日志服务器之前应考虑安全需求。日志文件可能包含有关本地主机上启用的服务、用户账户和配置数据的敏感信息。

网络安全

从客户端发送到服务器的网络数据未经加密或密码保护。如果需要加密传输,可考虑以下方案:

  • 使用 security/stunnel 创建 SSL 加密隧道传输 syslog 数据。

  • 在受信任的内部网络中部署日志服务器,配合防火墙限制访问。

接收端安全

通过 UDP 接收日志消息等效于“未经认证的远程磁盘填充服务”。因此:

  • 强烈建议使用 -a 选项明确限制允许发送日志的主机,而非接受所有来源的日志。

  • 如果不需要接收远程日志,应使用 -s 参数启用安全模式。指定两次 -ss 将完全禁用网络套接字。

  • 可在防火墙上限制 UDP 514 端口的访问来源。

本地安全

日志文件在使用过程中或日志轮替后并未加密。本地用户可能通过访问日志文件获取系统配置的额外信息。因此,对日志文件设置适当的权限十分必要。newsyslog 支持对新创建的和已轮替的日志文件设置权限。将日志文件(如 auth.log)设置为模式 600 可防止本地用户的未经授权访问。

参考文献

课后习题

  1. 配置 syslog.conf 将所有 auth 设施的日志单独记录到 /var/log/auth.log 文件中。

  2. 修改 newsyslog.conf 配置,将 /var/log/messages 的保留备份数量从 5 增加到 10。

  3. 使用 grep 命令搜索最近的 SSH 登录失败尝试记录。

  4. 手动触发 newsyslog 轮替 /var/log/auth.log 文件,观察轮替结果。

最后更新于