14.11 系统日志管理
本节介绍 FreeBSD 的系统日志管理。
14.11.1 配置本地日志记录
配置文件 /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.warning、auth.notice和mail.crit,并将这些日志消息发送到控制台(/dev/console)。sh# ls -al /dev/console crw------- 1 root wheel 0x8 May 16 10:09 /dev/console② 匹配来自
mail子系统的所有级别为info或更高的消息,并将日志记录到 /var/log/maillog 文件。③ 使用比较标志 (
=) 只匹配级别为debug的消息,并将其记录到 /var/log/debug.log 文件。④ 此示例演示了指定程序的用法:后续规则仅对指定程序生效。本例中,仅将 devd(8) 生成的消息记录到 /var/log/devd.log 文件。
14.11.2 日志记录设施
设施(facility)标识生成消息的子系统,用于将不同来源的消息分开,便于日志查阅。
表 syslog 设施
| 名称 | 说明 |
|---|---|
| auth | 授权系统:login(1)、su(1)、getty(8) 等。 |
| authpriv | 与 auth 相同,但日志记录到只有 root 可读的文件中。 |
| console | 由内核控制台输出驱动程序写入 /dev/console 的消息。 |
| cron | 由 cron(8) 守护进程写入的消息。 |
| daemon | 系统守护进程,例如 routed(8),此类进程没有专用的日志记录设施。 |
| kern | 由内核生成的消息。此类消息不能由任何用户进程生成。 |
| lpr | 打印机排队系统:lpr(1)、lpc(8)、lpd(8) 等。 |
| 邮件系统。 | |
| mark | 此设施每 20 分钟添加一条记录。 |
| news | 网络新闻系统。 |
| ntp | 网络时间协议系统。 |
| security | 安全子系统,例如 ipfw(4)。 |
| syslog | syslogd(8) 内部生成的消息。 |
| user | 随机用户进程生成的消息。这是未指定时的默认设施标识符。 |
| local0 至 local7 | 保留给本地使用。 |
14.11.3 日志记录级别
级别(level)表示消息的严重性,以下是按优先级从高到低的关键词列表:
表 syslog 级别
| 名称 | 说明 |
|---|---|
| emerg | 紧急条件。通常广播给所有用户。 |
| alert | 须立即修正的条件,例如损坏的系统数据库。 |
| crit | 严重条件,例如硬件设备错误。 |
| err | 错误。 |
| warning | 警告消息。 |
| notice | 非错误条件,但可能需要特别处理的条件。 |
| info | 信息性消息。 |
| debug | 调试程序时方可发挥作用的消息。 |
| none | 此特殊级别禁用特定设施。 |
14.11.4 阅读日志消息
FreeBSD 的 syslogd(8) 支持两种输出格式,通过 -O 选项切换:
- BSD/RFC 3164 格式(默认格式,
-O bsd或-O rfc3164):传统 BSD syslog 格式。 - Syslog/RFC 5424 格式(
-O syslog或-O rfc5424):较新的标准格式,采用 RFC 3339 时间戳(含微秒精度),并在每条消息中包含结构化的设施与严重级别字段。
RFC 3164 格式的日志通常使用以下语法:
日期 时间 主机名 程序[进程ID]: 信息以下是 /var/log/cron 文件的输出示例:
[此处省略其他输出]
May 15 15:30:00 ykla /usr/sbin/cron[1812]: (root) CMD (/usr/libexec/atrun)
May 15 15:33:00 ykla /usr/sbin/cron[1814]: (operator) CMD (/usr/libexec/save-entropy)
[此处省略其他输出]可以通过运行以下命令在 syslogd(8) 中启用详细日志记录,此时每条消息将附带设施和级别:
# sysrc syslogd_flags="-vv"启用此功能后,日志中将显示设施和级别,如下所示:
[此处省略其他输出]
May 17 18:55:00 <cron.info> ykla /usr/sbin/cron[1771]: (operator) CMD (/usr/libexec/save-entropy)
May 17 18:55:00 <cron.info> ykla /usr/sbin/cron[1772]: (root) CMD (/usr/libexec/atrun)
[此处省略其他输出]若要切换到 RFC 5424 格式,可以在 /etc/rc.conf 文件中配置:
# sysrc syslogd_flags="-O syslog"以下是 RFC 5424 格式下 /var/log/cron 文件的输出示例:
<78>1 2026-05-17T19:00:00.004642+08:00 ykla /usr/sbin/cron 1781 - - (root) CMD (newsyslog)
<78>1 2026-05-17T19:00:00.011902+08:00 ykla /usr/sbin/cron 1783 - - (operator) CMD (/usr/libexec/save-entropy)
<78>1 2026-05-17T19:00:00.017709+08:00 ykla /usr/sbin/cron 1785 - - (root) CMD (/usr/libexec/atrun)RFC 5424 格式下默认启用详细日志记录,无需选项 -vv。
<优先级>版本号 时间戳 主机名 程序名[进程ID] 消息ID [结构化数据] 日志信息14.11.5 日志管理与轮替
日志文件增长迅速,占用磁盘空间,且增加查找有效信息的难度。为此,FreeBSD 使用 newsyslog(8) 来管理日志文件。
newsyslog 定期轮替并压缩日志文件,可选择性地创建缺失的日志文件,并在日志文件移动时向程序发送信号。newsyslog 的默认配置源文件为 usr.sbin/newsyslog/newsyslog.conf。
# configuration file for newsyslog
#
# 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.
#
# 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/auth.log 600 7 1000 @0101T JC
/var/log/console.log 600 5 1000 * J
/var/log/cron 600 3 1000 * JC
/var/log/daemon.log 644 5 1000 @0101T JC
/var/log/daily.log 640 7 * @T00 JN
/var/log/debug.log 600 7 1000 * JC
/var/log/devd.log 644 3 1000 * JC
/var/log/init.log 644 3 1000 * J
/var/log/kerberos.log 600 7 1000 * J
/var/log/maillog 640 7 * @T00 JC
/var/log/messages 644 5 1000 @0101T JC
/var/log/monthly.log 640 12 * $M1D0 JN
/var/log/security 600 10 1000 * JC
/var/log/utx.log 644 3 * @01T05 B
/var/log/weekly.log 640 5 * $W6D0 JN
<include> /etc/newsyslog.conf.d/[!.]*.conf
<include> /usr/local/etc/newsyslog.conf.d/[!.]*.conf字段说明:
logfilename- 要归档的系统日志文件的名称。[owner:group]- 指定归档文件的所有者和组。mode- 指定日志文件和归档文件的文件模式。有效模式位为 0666,即可为归档日志指定所有者、组和其他用户的读写权限。count- 指定可存在的最大归档文件数。size- 日志文件的大小达到指定值(以 KB 为单位)时,将轮替日志文件。如果该字段包含星号(*),则不按大小轮替。when- 包含时间间隔、特定时间或两者。flags- 表示 newsyslog 接受的标志。[/pid_file]- 指定包含守护进程的进程 ID 的文件名,或查找组进程 ID。[sig_num]- 指定在轮替文件时将发送到守护进程的信号号。
技巧
最后两个字段
[/pid_file]、[sig_num]是可选的,指定进程的 PID 文件名以及在轮替文件时发送给该进程的信号编号。
14.11.5.1 手动轮替日志
虽然 newsyslog(8) 默认由 cron(8) 每小时调用一次,但也可以使用选项 -F 手动触发轮替:
# newsyslog -F强制轮替所有满足条件的日志文件。轮替后的文件示例如下:
/var/log/auth.log /var/log/devd.log /var/log/ppp.log
/var/log/auth.log.0.bz2 /var/log/devd.log.0.bz2 /var/log/ppp.log.0.bz2若要轮替特定文件,可指定文件路径:
# newsyslog -F /var/log/auth.log轮替结果如下:
auth.log.0.bz2
auth.log
auth.log.1.bz214.11.6 配置远程日志记录
系统数量增多后,监控多个主机的日志文件将增加管理负担。配置集中式日志记录可以减轻此负担。
在 FreeBSD 中,可以使用 syslogd 和 newsyslog 配置集中式日志文件聚合、合并和轮替。
本节的示例配置中,主机 A(192.168.5.18)作为日志客户端,命名为 logclient.example.com。
主机 A 将传递日志信息给日志服务器 B。
14.11.6.1 设置 DNS 解析
日志服务器和所有客户端主机必须在本地 DNS 中具有正向和反向条目。如果网络没有 DNS 服务器,请在每个系统的 /etc/hosts 中创建条目。名称解析必须正确,以确保日志条目不会被日志服务器拒绝。
分别在日志客户端 A 和日志服务器 B 中的 /etc/hosts 文件添加以下两行:
192.168.5.18 logclient.example.com
192.168.5.17 logserv.example.com其中主机 B 作为日志服务器(192.168.5.17),命名为 logserv.example.com,将收集本地网络的日志信息。
14.11.6.2 日志客户端配置
日志客户端将日志条目发送到网络上的日志服务器。客户端还会保留自己的日志副本。
在日志客户端 A 上执行以下命令,设置 syslogd 开机自启:
# service syslogd enable阻止此客户端接收来自其他主机的日志(-s),同时增加日志消息的详细程度:
# sysrc syslogd_flags="-s -v -v"然后,在客户端的 /etc/syslog.conf 文件中定义日志服务器。在此示例中,所有记录的设施都通过 @ 符号发送到指定的主机:
*.* @logserv.example.com保存编辑后,重新启动 syslogd 以使更改生效:
# service syslogd restart14.11.6.3 日志服务器配置
日志服务器是配置为接受来自其他主机日志信息的系统。
配置好日志客户端 A 后,在日志服务器 B 上,编辑 /etc/syslog.conf 文件:
+logclient.example.com
*.* /var/log/logclient.log以上示例在日志服务器的配置中,添加了日志客户端的主机名作为过滤条件。凡是来自主机 logclient.example.com 所有设施和级别的日志条目,都统一存储在服务器本地的 /var/log/logclient.log 文件中。
为每个客户端添加类似的两行条目便可添加多个日志客户端。
执行以下命令,设置 syslogd 开机自启:
# service syslogd enable允许来自指定客户端的日志条目:
# sysrc syslogd_flags="-a logclient.example.com -v -v"-v -v提高了日志消息的详细程度,有助于管理员查看每个设施下记录的消息类型。要允许来自多个客户端的日志记录,可以指定多个
-a选项。还可以指定 IP 地址和整个网段。
最后,创建日志文件 logclient.log:
# touch /var/log/logclient.log此时,应重新启动 syslogd 并进行验证:
# service syslogd restart
# pgrep syslogd如果返回 PID,则表示服务器已成功重新启动。
1958
1961
1962如果服务器未能重新启动,请通过 /var/log/messages 文件获取错误信息。
为了测试日志消息是否通过网络发送,可以在客户端使用 logger(1) 发送一条消息到 syslogd:
# logger "Test Message by logclient."此消息应同时存在于客户端的 /var/log/messages 文件和日志服务器的 /var/log/logclient.log 文件中。
May 17 21:58:08 <user.notice> logclient ykla[1881]: Test Message by logclient.14.11.6.4 调试日志服务器
如果日志服务器和日志客户端之间有防火墙,请确保防火墙规则集放行客户端和服务器之间的 UDP 端口 514。
# nc -uvz logserv.example.com 514
Connection to logserv.example.com 514 port [udp/syslog] succeeded!# nc -uvz logclient.example.com 514
Connection to logclient.example.com 514 port [udp/syslog] succeeded!如果日志服务器没有接收到任何消息,原因通常为网络连接问题、主机名解析问题或配置文件中的拼写错误。为排除故障,请确保日志服务器和日志客户端能够使用 /etc/rc.conf 文件中指定的主机名互相 ping。如果失败,请检查网络布线、防火墙规则集,以及日志服务器和客户端中的 DNS 服务器或 /etc/hosts 中的主机名条目。反复检查直至 ping 测试成功。
如果两个主机的 ping 都成功,但服务器仍未接收到日志消息,可临时提高日志详细度以缩小配置问题的范围。在以下示例中,日志服务器上的 /var/log/logclient.log 为空,而日志客户端上的 /var/log/messages 未显示失败原因。
为增加调试输出,编辑日志服务器上的 syslogd_flags 条目并执行重启:
# sysrc syslogd_flags="-d -a logclient.example.com -v -v"警告 请首先尝试使用 IP 地址代替域名进行测试。
调试成功后必须修改回原有设置,否则将影响系统正常开机。
# service syslogd restart重启后,调试数据将立即输出到控制台,类似于以下内容:
……省略部分输出……
logmsg: pri 56, flags 0, from logserv, msg restart
syslogd: restarted
logmsg: pri 6, flags 0, from logserv, msg kernel boot file is /boot/kernel/kernel
kernel boot file is /boot/kernel/kernel
received sa_len = 16
cvthname(2) len = 16
cvthname(192.168.5.18)
validate: dgram from IP 192.168.5.18, port 514, name logclient.example.com;
accepted in rule 1.
logmsg: pri 15, flags 0, from logclient, msg Test Message by logclient.
Logging to FILE /var/log/logclient.log
Logging to FILE /var/log/messages此时,消息已正确接收并写入正确的文件。
14.11.6.5 安全考量
与所有网络服务一样,在实施日志服务器之前应考虑安全需求。日志文件可能包含有关本地主机上启用的服务、用户账户和配置数据的敏感信息。
网络安全:
从客户端发送到服务器的网络数据未经加密或密码保护。如果需要加密传输,可考虑以下方案:
- 使用 security/stunnel 创建 SSL 加密隧道传输 syslog 数据。
- 在受信任的内部网络中部署日志服务器,配合防火墙限制访问。
接收端安全:
通过 UDP 接收日志消息等效于“未经认证的远程磁盘填充服务”。因此:
- 强烈建议使用
-a选项明确限制允许发送日志的主机,而非接受所有来源的日志。 - 如果不需要接收远程日志,应使用
-s参数启用安全模式。指定两次-ss将完全禁用网络套接字。 - 可在防火墙上限制 UDP 514 端口的访问来源。
本地安全:
日志文件在使用过程中或日志轮替后并未加密。本地用户可能通过访问日志文件获取系统配置的额外信息。因此,对日志文件设置适当的权限十分必要。newsyslog 支持对新创建的和已轮替的日志文件设置权限。将日志文件(如 auth.log)设置为模式 600 可防止本地用户的未经授权访问。
14.11.7 参考文献
- FreeBSD Project. syslog.conf(5)[EB/OL]. [2025-05-17]. https://man.freebsd.org/cgi/man.cgi?query=syslog.conf&sektion=5. syslog 配置文件手册页。
- FreeBSD Project. syslogd(8)[EB/OL]. [2025-05-17]. https://man.freebsd.org/cgi/man.cgi?query=syslogd&sektion=8. syslog 守护进程手册页。
- FreeBSD Project. newsyslog.conf(5)[EB/OL]. [2025-05-17]. https://man.freebsd.org/cgi/man.cgi?query=newsyslog.conf&sektion=5. newsyslog 配置文件手册页。
- FreeBSD Project. logger(1)[EB/OL]. [2025-05-17]. https://man.freebsd.org/cgi/man.cgi?query=logger&sektion=1. 命令行日志发送工具手册页。
14.11.8 课后习题
- 配置
syslog.conf将所有auth设施的日志单独记录到 /var/log/auth.log 文件中。 - 修改
newsyslog.conf配置,将 /var/log/messages 的保留备份数量从 5 增加到 10。 - 使用
grep命令搜索最近的 SSH 登录失败尝试记录。 - 手动触发
newsyslog轮替/var/log/auth.log文件,观察轮替结果。