18.1 什么是登录文件

登录文件 = 记录系统活动信息的文件,记录何时、何地(来源 IP)、何人(什么服务)、做了什么动作。即:系统在什么时候由哪个程序做了什么行为、发生了什么事件。

18.1.1 CentOS 7 登录文件简易说明

登录文件的重要性

用途说明
解决系统错误硬件侦测、服务无法启动 → 查登录文件找原因;SELinux 与登录文件关系尤其紧密
解决网络服务问题网络服务无法启动 → 查对应登录文件(如 postfix → /var/log/maillog
过往事件记录簿异常流量追踪、被入侵后的溯源取证

天助自助者:(1)看屏幕错误讯息 +(2)查登录文件 = 解决大部分 Linux 问题。

常见的登录文件

文件内容
/var/log/boot.log本次开机启动流程(只保留本次,前次不保留)
/var/log/croncrontab 执行记录——调度有没有执行、有没有报错
/var/log/dmesg开机时核心侦测硬件过程的信息(CentOS 默认不开机显示,写到这里)
/var/log/lastlog所有帐号最近一次登录的信息(lastlog 指令就是读这个文件)
/var/log/maillogpostfix (SMTP 发信) + dovecot (POP3 收信) 的邮件往来记录
/var/log/messages最重要的文件——几乎系统所有错误和重要信息都在这里
/var/log/secure涉及帐号密码的登录记录(login、gdm、su、sudo、ssh、telnet),无论成功与否
/var/log/wtmp正确登录者的帐号信息(last 指令读此文件)
/var/log/faillog错误登录时的帐号信息(lastb 指令读此文件)
/var/log/httpd/*Apache 自行管理的登录文件(access_log + error_log)
/var/log/samba/*Samba 自行管理的登录文件

除了 /var/log/messages 之外,不同 Linux distributions 的登录文件名可能不同。务必查阅 /etc/rsyslog.conf 确认。

登录文件所需的服务与程序

登录文件的产生有两种方式:

  1. 软件自行定义:如 Apache、Samba 自己写登录文件
  2. 统一管理服务:由 Linux distribution 提供的登录文件管理服务分类记录

CentOS 7 涉及日志管理的三个组件:

组件角色说明
systemd-journald.service讯息收受者systemd 自带,所有经由 systemd 启动的服务的讯息先到这里(内存)
rsyslog.service登录系统/网络服务讯息从 journald 接收讯息,按规则写入 /var/log/ 下各文件
logrotate登录文件轮替挂在 cron 下定期执行,旧文件更名→创建新文件→压缩→删除过旧文件

CentOS 7 数据流:systemd 启动服务 → systemd-journald.service(内存)→ rsyslog.service → /var/log/*

18.1.2 登录文件内容的一般格式

每条登录记录包含四个字段:

Aug 17 18:38:06 study login: ... Root LOGIN ON tty1
|--日期/时间---|--H--|-服务-|------讯息说明---------->
字段含义示例
日期与时间事件发生时间Aug 17 18:38:06
主机名称发生事件的主机study(支持远端日志服务器,所以需要标记主机名)
服务/指令名称产生讯息的程序loginsshd[18913]sudosuCROND
讯息内容实际数据Accepted password for dmtsai from 192.168.1.200

查日志的三步法(当服务启动失败时):

  1. 找到当前时间的登录信息(第一字段)
  2. 找到目标服务(第三字段)
  3. 仔细查阅第四字段信息 → 定位错误点

需要查日志的时机:系统不太正常、daemon 无法启动、用户无法登录、daemon 执行不顺畅。

18.2 rsyslog.service:记录登录文件的服务

systemctl status rsyslog.service   # 确认运行中 + 开机启动
# daemon 可执行文件名为 rsyslogd

18.2.1 rsyslog.service 的配置文件:/etc/rsyslog.conf

语法格式服务名称.[连结符号]讯息等级 记录设备/文件/主机

服务名称(syslog 规范,来自 syslog.h

序号服务类别说明
0kern (kernel)核心产生的讯息,硬件侦测、核心功能启用
1user使用者层级产生的信息(如 logger 指令)
2mail邮件收发相关
3daemon系统服务产生的信息(systemd 等)
4auth认证/授权相关(login, ssh, su 等需要帐号密码的)
5syslogrsyslogd 本身产生的信息
6lpr打印相关
7news新闻群组服务器
8uucpUnix to Unix Copy Protocol
9cron例行性工作调度 cron/at
10authpriv与 auth 类似,记录更多帐号私人信息(含 PAM 模块)
11ftpFTP 通讯协定
16~23local0 ~ local7保留给本机用户使用,常与终端机互动

软件通过调用 syslog 函数写入——例如 sendmail、postfix、dovecot 都会调用 mail 服务名称。

讯息等级(数值越小越严重)

等级数值等级名称说明
7debug除错信息
6info基本讯息说明
5notice正常但比 info 更需注意
4warning (warn)警示——可能有问题的信息,通常还不影响运行
3err (error)重大错误——如配置文件错误导致服务无法启动
2crit临界点错误,比 error 更严重
1alert很有问题的等级,比 crit 还要严重
0emerg (panic)系统几乎死机——通常硬件出问题导致核心无法运行

特殊等级:

  • debug:错误侦测等级(比 info 更详细)
  • none:不记录,用来排除特定服务

连结符号

符号含义示例
.大于等于该等级的都记录mail.info = mail 的 info 及以上等级
.=等于该等级才记录cron.=warn = 只记录 cron 的 warning 等级
.!不等于该等级mail.!info = 除了 info 之外都记录

记录目的地

目标写法说明
文件绝对路径/var/log/maillog最常用
打印机或设备/dev/lp0
使用者名称root显示给使用者
远端主机@192.168.1.100 (UDP) 或 @@192.168.1.100 (TCP)日志服务器
所有在线者*类似 wall 的效果

名称辨析

名称是什么
syslogLinux 核心提供的登录文件设计指引(规范),定义在 syslog.h
rsyslogd实际实现 syslog 功能的 daemon 程序
rsyslog.service为 systemd 控制而编写的启动服务脚本

CentOS 5.x 用 syslogd,CentOS 6/7 升级为 rsyslogd(“r” = reliable,支持 TCP 传输)。

CentOS 7.x 默认的 /etc/rsyslog.conf

# 1. 核心讯息送 console(RS232 等外部连接设备)
kern.*                                              /dev/console
 
# 2. 除 mail, authpriv, cron 外的所有 info+ 写入 messages
*.info;mail.none;authpriv.none;cron.none             /var/log/messages
 
# 3. 认证讯息 → secure
authpriv.*                                           /var/log/secure
 
# 4. 邮件讯息 → maillog(前面的 - 表示先写 buffer 再刷盘,性能更好但异常关机可能丢失)
mail.*                                              -/var/log/maillog
 
# 5. 例行调度 → cron
cron.*                                               /var/log/cron
 
# 6. 最严重等级 → 广播给所有在线用户
*.emerg                                              :omusrmsg:*
 
# 7. uucp/news 严重错误 → spooler
uucp,news.crit                                       /var/log/spooler
 
# 8. 本机开机讯息 → boot.log
local7.*                                             /var/log/boot.log

多服务可用 ;, 分隔

  • ;news.*;cron.*(每个都要写完整)
  • ,news,cron.none(等级只写最后一个)

⚠️ 不要用 vim 编辑登录文件后又 :wq 存盘!rsyslogd 会误判文件已被更动,停止写入。若不慎发生,systemctl restart rsyslog.service 即可恢复。

自行增加登录文件

# 1. 编辑配置文件
echo "*.info      /var/log/admin.log" >> /etc/rsyslog.conf
 
# 2. 重启服务
systemctl restart rsyslog.service

18.2.2 登录文件的安全性设置

防止登录文件被删/被误改:使用 chattr +a 设置隐藏属性。

属性效果
chattr +a只能新增,不能删除/修改(连 root 都不能删)
chattr +i完全不可动——连新增也不行(不适合登录文件)
chattr +a /var/log/admin.log       # 保护登录文件
lsattr /var/log/admin.log          # 查看属性
chattr -a /var/log/admin.log       # 解除保护(轮替前需要)

⚠️ 注意:如果已被 root 入侵,chattr -a 仍可被攻破。+a 的本质是防止误操作(如 vim :wq 不小心存了登录文件)。此外,+a 会使 logrotate 无法更名文件,需要在轮替脚本中先 chattr -achattr +a(见 18.3)。

18.2.3 登录文件服务器的设置

集中管理多台主机的登录文件,只需登陆一台即可查看所有服务器日志。使用 UDP 或 TCP port 514

服务器端 /etc/rsyslog.conf

# 启用 TCP 监听(去掉注释即可)
$ModLoad imtcp
$InputTCPServerRun 514
 
systemctl restart rsyslog.service
netstat -ltnp | grep syslog    # 确认监听

客户端 /etc/rsyslog.conf

# 所有讯息都发给日志服务器
*.*  @@192.168.1.100      # TCP: 两个 @
#*.*  @192.168.1.100      # UDP: 一个 @
 
systemctl restart rsyslog.service

UDP 快但不保证送达,TCP 稳定可靠——网络稳定用 UDP,需可靠性用 TCP。

18.3 登录文件的轮替(logrotate)

rsyslogd 是 daemon(持续运行),logrotate 则是 cron 调度执行/etc/cron.daily/logrotate):将旧文件更名 → 创建新的空文件 → 定期删除过旧文件。

messages → messages.1 → messages.2 → messages.3 → 删除

18.3.1 logrotate 的配置文件

文件用途
/etc/logrotate.conf主配置文件,全局默认值
/etc/logrotate.d/各服务独立的轮替配置,被 include 进主配置

语法

登录文件绝对路径 ... {
    个别参数设置
    sharedscripts
    prerotate
        轮替前执行的指令
    endscript
    postrotate
        轮替后执行的指令(如 kill -HUP 通知服务 reload)
    endscript
}

默认 /etc/logrotate.conf

weekly          # 每周轮替一次
rotate 4        # 保留 4 个备份
create          # 轮替后创建新的空文件
dateext         # 备份文件名加日期后缀
#compress       # 是否压缩备份(默认关闭)
include /etc/logrotate.d
 
/var/log/wtmp {
    monthly              # 每月一次
    create 0664 root utmp
    minsize 1M           # 文件大小必须超过 1M
    rotate 1             # 只保留一个
}

/etc/logrotate.d/syslog 示例

/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

sharedscripts:多个登录文件只执行一次 prerotate/postrotate(而不是每个文件执行一遍)。

如果登录文件加了 chattr +a,必须用 prerotate/postrotate 处理:

/var/log/messages {
    sharedscripts
    prerotate
        /usr/bin/chattr -a /var/log/messages    # 轮替前取消保护
    endscript
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /usr/bin/chattr +a /var/log/messages    # 轮替后恢复保护
    endscript
}

kill -HUP = 让 rsyslogd 重新读入配置文件(reload),因为旧的登录文件已被更名,必须通知 daemon 使用新文件。

常用 logrotate 参数

参数说明
daily / weekly / monthly轮替周期
rotate N保留 N 个归档
compress压缩归档(gzip)
dateext归档文件名加日期
size=N / minsize=N文件达 N 大小时轮替(如 size=10M
create MODE OWNER GROUP新建空文件的权限与归属
missingok文件不存在也不报错
notifempty空文件不轮替
sharedscripts多个文件只跑一次 pre/post 脚本
prerotate / postrotate轮替前/后执行的指令块
delaycompress延迟一个周期再压缩(保证总有一个未压缩的 .1

18.3.2 实际测试 logrotate 的动作

logrotate -v /etc/logrotate.conf      # 显示详细流程(不强制)
logrotate -vf /etc/logrotate.conf     # 强制执行(不管时间/大小条件)

测试配置是否正确时,用 -vf 强制执行并观察输出,然后用 ls -l /var/log/ 确认结果。

18.3.3 自订登录文件的轮替功能

需求示例:对 /var/log/admin.log(已加 +a 属性)设置轮替——每月一次或大于 10MB 时主动轮替,保留 5 份,压缩。

# /etc/logrotate.d/admin
/var/log/admin.log {
    monthly        # 每月轮替一次
    size=10M       # 或文件 >10MB 时立即轮替(此条件优先于 monthly)
    rotate 5       # 保留 5 份归档
    compress       # 压缩归档
    sharedscripts
    prerotate
        /usr/bin/chattr -a /var/log/admin.log
    endscript
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /usr/bin/chattr +a /var/log/admin.log
    endscript
}
logrotate -vf /etc/logrotate.d/admin   # 测试配置
lsattr /var/log/admin.log*             # 验证 +a 属性恢复

💡 logrotate/etc/rsyslog.conf 是配对组合:先在 rsyslog.conf 定义”写到哪里”,再到 logrotate 定义”怎么轮替”。

18.4 systemd-journald.service 简介

过去只有 rsyslogd 时,需要 klogd 来记录开机过程中的核心信息(因为 rsyslogd 还没启动)。现在 systemd 是核心唤醒的第一支程序,可直接调用 systemd-journald 记录开机过程中的所有信息(含服务启动失败)。

systemd-journald 与 rsyslogd 的分工

特性systemd-journaldrsyslogd
存储位置内存 (/run/log/)磁盘 (/var/log/)
重新开机后消失(除非配置 /var/log/journal持久保留
查询方式journalctl(精确到服务级别)vim/tail 直接读文件
适用场景查询本次开机的信息长期保存、历史分析

💡 建议:两者同时启用——journald 用于快速查询本次开机问题,rsyslogd 用于长期归档。

18.4.1 使用 journalctl 观察登录信息

journalctl [-nrpf] [--since TIME] [--until TIME] [_FILTER=VALUE]
参数说明
-n N显示最近 N 行(默认全部,从旧到新)
-r反向输出,从最新到最旧
-p LEVEL按等级过滤(err, warning, info 等)
-f类似 tail -f,实时追踪(Ctrl+C 退出)
--since "2015-08-18"只显示该时间之后的数据
--until "2015-08-19"只显示该时间之前的数据
_SYSTEMD_UNIT=crond.service只显示特定 unit 的日志
_COMM=su只显示特定指令的日志
_PID=N只显示特定 PID 的日志
_UID=N只显示特定 UID 的日志
SYSLOG_FACILITY=N按 syslog 服务序号过滤(如 4=auth, 10=authpriv)

常用示例

journalctl --since today                          # 今天的日志
journalctl --since yesterday --until today        # 昨天的日志
journalctl _SYSTEMD_UNIT=sshd.service -n 20       # sshd 最近 20 条
journalctl _COMM=su _COMM=login -n 10             # su 和 login 最近 10 条
journalctl -p err                                  # 只看错误及以上
journalctl SYSLOG_FACILITY=4 SYSLOG_FACILITY=10    # 认证相关(auth + authpriv)
journalctl -f                                      # 实时追踪(在两个终端测试最佳)

18.4.2 logger 指令的应用

将自定义讯息写入登录文件:

logger [-p 服务名称.等级] "讯息内容"
logger -p user.info "I will check logger command"
journalctl SYSLOG_FACILITY=1 -n 3   # FACILITY=1 即 user

实战:在备份脚本中记录日志

#!/bin/bash
# /backups/backup.sh
if [ "${1}" == "log" ]; then
    logger -p syslog.info "backup.sh is starting"
fi
 
source="/etc /home /root /var/lib /var/spool/{cron,at,mail}"
target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
[ ! -d /backups ] && mkdir /backups
tar -zcvf ${target} ${source} &> /backups/backup.log
 
if [ "${1}" == "log" ]; then
    logger -p syslog.info "backup.sh is finished"
fi

18.4.3 保存 journal 的方式

默认 journal 存于 /run/log/(内存),重新开机后消失。如需持久化:

mkdir /var/log/journal
chown root:systemd-journal /var/log/journal
chmod 2775 /var/log/journal
systemctl restart systemd-journald.service

💡 鸟哥建议:既然有 rsyslog 写入磁盘,就不必再保存 journal 到磁盘——让 journal 留在内存中存取更快。按需选择。

18.5 分析登录文件

18.5.1 CentOS 默认提供的 logwatch

logwatch 是登录文件分析工具,每天分析一次并以 email 寄送给 root(通过 /etc/cron.daily/0logwatch)。

yum install logwatch          # 安装(需 perl-Date-Manip 等依赖)
/etc/cron.daily/0logwatch     # 手动执行一次分析
mail                          # 查看分析报告(root 身份)

报告内容包括:pam_unix(登录/提权汇总)、Postfix(收发统计)、SSHD(登录来源)、Sudo(提权记录)、Disk Space(各分区当前用量)。

18.5.2 鸟哥自己写的登录文件分析工具

鸟哥写了一个 shell script 分析工具,基于 journalctl,每天 00:10 执行,输出包括:

  • 系统总览:Linux kernel 版本、CPU 信息、主机名、IP、运行时间
  • 文件系统用量:各分区类型、大小、使用率
  • 端口分析:对外部开放的端口(PID | owner | command)
  • 各服务单独分析:SSH 登录记录、Postfix 收发统计

下载地址:http://linux.vbird.org/linux_basic/0570syslog/logfile_centos7.tar.gz

tar -zxvf /logfile_centos7.tar.gz -C /
cat /etc/cron.d/vbirdlogfile                     # 查看 crontab 配置
sh /root/bin/logfile/logfile.sh                  # 手动执行
mail                                              # 查看分析结果

⚠️ 此脚本基于 journalctl,只适用于 CentOS 7.x,不兼容 CentOS 6 及更早版本。

命令速查表

命令用途
systemctl status rsyslog.service查看 rsyslog 服务状态
tail -f /var/log/messages实时追踪通用系统日志
tail -f /var/log/secure实时追踪认证日志
chattr +a /var/log/admin.log保护日志只能追加
lsattr /var/log/admin.log查看文件隐藏属性
logrotate -vf /etc/logrotate.conf强制执行日志轮替
journalctl -f实时追踪 journal 日志
journalctl -p err只看错误及以上等级
journalctl --since today查看今天的日志
journalctl _SYSTEMD_UNIT=sshd.service只看 sshd 服务日志
logger -p user.info "msg"手动写入日志
logwatch / /etc/cron.daily/0logwatch执行日志分析
last读取 wtmp 显示登录历史
lastb读取 faillog 显示登录失败记录
lastlog所有帐号最近一次登录时间
dmesg查看核心开机侦测信息
netstat -ltnp | grep syslog确认日志服务器是否监听