鸟哥的linux私房菜——第十八章学习(登录文件)
第十八章、登录文件
1.1)、什么是登录文件及其配置
登录文件:记录系统活动信息的几个文件, 例如:何时、何地 (来源 IP)、何人 (什么服务名称)、做了什么动作 (讯息登录啰)。 换句话说就是:记录系统在什么时候由哪个程序做了什么样的行为时,发生了何种的事件等等。
- 登录文件的重要性:
- 解决系统方面的错误;
- 解决网络服务的问题;
- 过往事件记录簿;
- Linux 常见的登录文件文件名
- /var/log/boot.log:本次开机启动的信息
- /var/log/cron:crontab调度过程
- /var/log/dmesg:开机时核心侦测过程所产生的各项信息
- /var/log/lastlog:系统上面所有的帐号最近一次登陆系统时的相关信息,lastlog指令
- /var/log/maillog 或 /var/log/mail/*:记录邮件的往来信息,其实主要是记录 postfix (SMTP 协定提供者) 与 dovecot (POP3 协定提供者) 所产生的讯息
- /var/log/messages:系统发生的错误讯息【极其重要】
- /var/log/secure:牵涉到“需要输入帐号密码”的软件,当登陆时 (不管登陆正确或错误) 都会被记录在此文件
- /var/log/wtmp, /var/log/faillog:记录正确登陆系统者的帐号信息 (wtmp) 与错误登陆时所使用的帐号信息 (faillog),对于追踪一般帐号者的使用行为很有帮助。
- /var/log/httpd/*, /var/log/samba/*:个别服务所制订的登录文件。
CentOS 提供 rsyslog.service 这个服务来统一管理登录文件。可以通过 logrotate (登录文件轮替) 这玩意儿来自动化处理登录文件容量与更新的问题。
logrotate 基本上,就是将旧的登录文件更改名称,然后创建一个空的登录文件,如此一来, 新的登录文件将重新开始记录,然后只要将旧的登录文件留下一阵子,嗯!那就可以达到将登录文件“轮转”的目的啦! 此外,如果旧的记录 (大概要保存几个月吧!) 保存了一段时间没有问题,那么就可以让系统自动的将他砍掉, 免得占掉很多宝贵的硬盘空间说!
总结一下,针对登录文件所需的功能,我们需要的服务与程序有:
-
- systemd-journald.service:最主要的讯息收受者,由 systemd 提供的;
- rsyslog.service:主要登录系统与网络等服务的讯息;
- logrotate:主要在进行登录文件的轮替功能。
当我老是无法成功的启动某个服务时,我会在最后一次启动该服务后,立即检查登录文件, 先
1)找到现在时间所登录的信息“第一字段”;
2)找到我想要查询的那个服务“第三字段”,
3)最后再仔细的查阅第四字段的信息,来借以找到错误点。
rsyslogd 针对各种服务与讯息记录在某些文件的配置文件就是 /etc/rsyslog.conf, 这个文件规定了“(1)什么服务 (2)的什么等级讯息 (3)需要被记录在哪里(设备或文件)”三个信息。
为了让不同的信息放置到不同的文件当中,好让我们分门别类的进行登录文件的管理,将各种类别的服务之登录文件,记录在不同的文件里面,就是我们 /etc/rsyslog.conf 所要作的规范。
讯息登记:从7--0问题程度越来越严重,
特别留意一下在讯息等级之前还有 [.=!] 的链接符号喔!他代表的意思是这样的:
-
- “.” :代表“比后面还要严重的等级 (含该等级) 都被记录下来”的意思,例如: mail.info 代表只要是 mail 的信息,而且该信息等级严重于info (含 info 本身)时,就会被记录下来的意思。
- “.=” :代表所需要的等级就是后面接的等级而已, 其他的不要!
- “.!” :代表不等于, 亦即是除了该等级外的其他等级都记录。
【举个例子】
例题1: 如果我要将我的 mail 相关的数据给他写入 /var/log/maillog 当中,那么在 /etc/rsyslog.conf 的语法如何设计? 答:基本的写法是这样的: mail.info /var/log/maillog 注意到上面喔,当我们的等级使用 info 时,那么“任何严重于 info 等级(含 info 这个等级)之上的讯息, 都会被写入到后面接的文件之中!”这样可以了解吗?也就是说,我们可以将所有 mail 的登录信息都记录在 /var/log/maillog 里面的意思啦! 例题2: 我要将新闻群组数据 (news) 及例行性工作调度 (cron) 的讯息都写入到一个称为 /var/log/cronnews 的文件中,但是这两个程序的警告讯息则额外的记录在 /var/log/cronnews.warn 中, 那该如何设置我的 rsyslog.conf 呢? 答:既然是两个程序,那么只好以分号来隔开了,此外,由于第二个指定文件中,我只要记录警告讯息, 因此设置上需要指定“.=”这个符号,所以语法成为了: news.*;cron.* /var/log/cronnews news.=warn;cron.=warn /var/log/cronnews.warn 上面那个“.=”就是在指定等级的意思啦!由于指定了等级,因此,只有这个等级的讯息才会被记录在这个文件里面呢!此外你也必须要注意,news 与 cron 的警告讯息也会写入 /var/log/cronnews 内喔! 例题3: 我的 messages 这个文件需要记录所有的信息,但是就是不想要记录 cron, mail 及 news 的信息,那么应该怎么写才好? 答:可以有两种写法,分别是: *.*;news,cron,mail.none /var/log/messages *.*;news.none;cron.none;mail.none /var/log/messages 使用“,”分隔时,那么等级只要接在最后一个即可,如果是以“;”来分的话, 那么就需要将服务与等级都写上去!
1.2)、登录文件的安全性设置
rsyslogd 的登录文件只要“被编辑过”就无法继续记录!
如果一不小心用:wq来退出vim编辑的rsystemd环境,那么你得要 (1)改变使用 vim 的习惯; (2)重新启动 rsyslog.service 让他再继续提供服务才行喔
我们就来处理一下隐藏属性,lsattr 与 chattr 这两个东西!如果将一个文件以 chattr 设置 i 这个属性时,那么该文件连 root 都不能杀掉!而且也不能新增数据,嗯!真安全!但是,如此一来登录文件的功能岂不是也就消失了? 因为没有办法写入呀!所以啰,我们要使用的是 a 这个属性!你的登录文件如果设置了这个属性的话,那么 他将只能被增加,而不能被删除!
[root@study ~]# chattr +a /var/log/admin.log [root@study ~]# lsattr /var/log/admin.log -----a---------- /var/log/admin.log
加入了这个属性之后,你的 /var/log/admin.log 登录文件从此就仅能被增加,而不能被删除,直到 root 以“ chattr -a /var/log/admin.log ”取消这个 a 的参数之后,才能被删除或移除。
不过,也因为这个 +a 的属性让该文件无法被删除与修改,所以啰,当我们进行登录文件轮替时 (logrotate) ,将会无法移动该登录文件的文件名呢!所以会造成很大的困扰。这个困扰虽然可以使用 logrotate 的配置文件来解决。
1.3)、登录文件服务器的设置
想像一个环境,你的办公室内有十部 Linux 主机,每一部负责一个网络服务, 你为了要了解每部主机的状态,因此,你常常需要登陆这十部主机去查阅你的登录文件。
这个时候我们可以让某一部主机当成“登录文件服务器”,用他来记录所有的十部 linux 主机的信息,嘿嘿!这样我就直接进入一部主机就可以了。
CentOS 7.x 默认的 rsyslogd 本身就已经具有这个登录文件服务器的功能。既然是登录文件服务器,那么我们的 Linux 主机当然会启动一个端口来监听了,那个默认的端口就是 UDP 或 TCP 的 port 514
服务器会启动监听的端口,用户端则将登录文件再转出一份送到服务器去。 而既然是登录文件“服务器”,所以当然有服务器与用户端 (client) 啰!这两者的设置分别是这样的:
# 1. Server 端:修改 rsyslogd 的启动配置文件,在 /etc/rsyslog.conf 内! [root@study ~]# vim /etc/rsyslog.conf # 找到下面这几行: # Provides UDP syslog reception #$ModLoad imudp #$UDPServerRun 514 # Provides TCP syslog reception #$ModLoad imtcp #$InputTCPServerRun 514 # 上面的是 UDP 端口,下面的是 TCP 端口!如果你的网络状态很稳定,就用 UDP 即可。 # 不过,如果你想要让数据比较稳定传输,那么建议使用 TCP 啰!所以修改下面两行即可! $ModLoad imtcp $InputTCPServerRun 514 # 2. 重新启动与观察 rsyslogd 喔! [root@study ~]# systemctl restart rsyslog.service [root@study ~]# netstat -ltnp | grep syslog Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN 2145/rsyslogd tcp6 0 0 :::514 :::* LISTEN 2145/rsyslogd
1.4)、登录文件的轮替(logrotate)
“rsyslogd 利用的是 daemon 的方式来启动的, 当有需求的时候立刻就会被执行的,但是 logrotate 却是在规定的时间到了之后才来进行登录文件的轮替, 所以这个 logrotate 程序当然就是挂在 cron 下面进行。
/etc/cron.daily/logrotate 就是记录了每天要进行的登录文件轮替的行为。
logrotate 的主要功能就是将旧的登录文件移动成旧文件, 并且重新创建一个新的空的文件来记录,
gjm@root:/etc/cron.daily$ cat logrotate #!/bin/sh # Clean non existent log file entries from status file cd /var/lib/logrotate test -e status || touch status head -1 status > status.clean sed 's/"//g' status | while read logfile date do [ -e "$logfile" ] && echo "\"$logfile\" $date" done >> status.clean mv status.clean status test -x /usr/sbin/logrotate || exit 0 /usr/sbin/logrotate /etc/logrotate.conf
当第一次执行完 rotate 之后,原本的 messages 会变成 messages.1 而且会制造一个空的messages 给系统来储存登录文件。而第二次执行之后,则 messages.1 会变成 messages.2 而 messages 会变成 messages.1 ,又造成一个空的 messages 来储存登录文件!那么如果我们仅设置保留三个登录文件而已的话,那么执行第四次时,则 messages.3 这个文件就会被删除,并由后面的较新的保存登录文件所取代!
logrotate的配置都记录在 logrotate.conf 里面
[root@study ~]# vim /etc/logrotate.conf # 下面的设置是 "logrotate 的默认设置值" ,如果个别的文件设置了其他的参数, # 则将以个别的文件设置为主,若该文件没有设置到的参数则以这个文件的内容为默认值! weekly <==默认每个礼拜对登录文件进行一次 rotate 的工作 rotate 4 <==保留几个登录文件呢?默认是保留四个! create <==由于登录文件被更名,因此创建一个新的来继续储存之意! dateext <==就是这个设置值!可以让被轮替的文件名称加上日期作为文件名喔! #compress <==被更动的登录文件是否需要压缩?如果登录文件太大则可考虑此参数启动 include /etc/logrotate.d # 将 /etc/logrotate.d/ 这个目录中的所有文件都读进来执行 rotate 的工作! /var/log/wtmp { <==仅针对 /var/log/wtmp 所设置的参数 monthly <==每个月一次,取代每周! create 0664 root utmp <==指定新建文件的权限与所属帐号/群组 minsize 1M <==文件大小一定要超过 1M 后才进行 rotate (略过时间参数) rotate 1 <==仅保留一个,亦即仅有 wtmp.1 保留而已。 } # 这个 wtmp 可记录登陆者与系统重新开机时的时间与来源主机及登陆期间的时间。 # 由于具有 minsize 的参数,因此不见得每个月一定会进行一次喔!要看文件大小。 # 由于仅保留一个登录文件而已,不满意的话可以将他改成 rotate 5 吧!
由这个文件的设置我们可以知道 /etc/logrotate.d 其实就是由 /etc/logrotate.conf 所规划出来的目录,所以,其实我们可以将所有的数据都给他写入 /etc/logrotate.conf 即可,但是这样一来这个文件就实在是太复杂了,尤其是当我们使用很多的服务在系统上面时, 每个服务都要去修改 /etc/logrotate.conf 的设置也似乎不太合理~ 所以,如果独立出来一个目录,那么每个以 RPM 打包方式所创建的服务的登录文件轮替设置, 就可以独自成为一个文件,并且放置到 /etc/logrotate.d/ 当中即可,真是方便又合理的做法。
- 【自定义登录文件的轮替功能】
假设你已经创建了 /var/log/admin.log 这个文件, 现在,你想要将该文件加上 +a 这个隐藏标签,而且设置下面的相关信息:
-
- 登录文件轮替一个月进行一次;
- 该登录文件若大于 10MB 时,则主动进行轮替,不需要考虑一个月的期限;
- 保存五个备份文件;
- 备份文件需要压缩。
# 1. 先创建 +a 这个属性啊! [root@study ~]# chattr +a /var/log/admin.log [root@study ~]# lsattr /var/log/admin.log -----a---------- /var/log/admin.log [root@study ~]# mv /var/log/admin.log /var/log/admin.log.1 mv: cannot move `/var/log/admin.log' to `/var/log/admin.log.1': Operation not permitted # 这里确定了加入 a 的隐藏属性!所以 root 无法移动此登录文件! # 2. 开始创建 logrotate 的配置文件,增加一个文件在 /etc/logrotate.d 内就对了! [root@study ~]# vim /etc/logrotate.d/admin # This configuration is from VBird 2015/08/19 /var/log/admin.log { monthly <==每个月进行一次 size=10M <==文件大小大于 10M 则开始处置 rotate 5 <==保留五个! compress <==进行压缩工作! sharedscripts prerotate /usr/bin/chattr -a /var/log/admin.log endscript sharedscripts 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 } # 3. 测试一下 logrotate 相关功能的信息显示: [root@study ~]# logrotate -v /etc/logrotate.conf ....(前面省略).... rotating pattern: /var/log/admin.log 10485760 Bytes (5 rotations) empty log files are rotated, old logs are removed considering log /var/log/admin.log log does not need rotating not running prerotate script, since no logs will be rotated not running postrotate script, since no logs were rotated ....(下面省略).... # 因为还不足一个月,文件也没有大于 10M,所以不需进行轮替! # 4. 测试一下强制 logrotate 与相关功能的信息显示: [root@study ~]# logrotate -vf /etc/logrotate.d/admin reading config file /etc/logrotate.d/admin reading config file /etc/logrotate.d/admin Handling 1 logs rotating pattern: /var/log/admin.log forced from command line (5 rotations) empty log files are rotated, old logs are removed considering log /var/log/admin.log log needs rotating rotating log /var/log/admin.log, log->rotateCount is 5 dateext suffix '-20150820' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' renaming /var/log/admin.log.5.gz to /var/log/admin.log.6.gz (rotatecount 5, logstart 1, i 5), old log /var/log/admin.log.5.gz does not exist renaming /var/log/admin.log.4.gz to /var/log/admin.log.5.gz (rotatecount 5, logstart 1, i 4), old log /var/log/admin.log.4.gz does not exist renaming /var/log/admin.log.3.gz to /var/log/admin.log.4.gz (rotatecount 5, logstart 1, i 3), old log /var/log/admin.log.3.gz does not exist renaming /var/log/admin.log.2.gz to /var/log/admin.log.3.gz (rotatecount 5, logstart 1, i 2), old log /var/log/admin.log.2.gz does not exist renaming /var/log/admin.log.1.gz to /var/log/admin.log.2.gz (rotatecount 5, logstart 1, i 1), old log /var/log/admin.log.1.gz does not exist renaming /var/log/admin.log.0.gz to /var/log/admin.log.1.gz (rotatecount 5, logstart 1, i 0), old log /var/log/admin.log.0.gz does not exist log /var/log/admin.log.6.gz doesn't exist -- won't try to dispose of it running prerotate script fscreate context set to system_u:object_r:var_log_t:s0 renaming /var/log/admin.log to /var/log/admin.log.1 running postrotate script compressing log with: /bin/gzip [root@study ~]# lsattr /var/log/admin.log* -----a---------- /var/log/admin.log ---------------- /var/log/admin.log.1.gz <==有压缩过喔!
要注意的, /etc/rsyslog.conf 与/etc/logrotate.d/* 文件常常要搭配起来,例如刚刚我们提到的两个案例中所创建的 /var/log/admin.log 就是一个很好的例子~
1.5)、journalctl观察登录信息
systemd-journald.service 的数据要如何叫出来查阅?
通过 journalctl 即可。
[root@study ~]# journalctl [-nrpf] [--since TIME] [--until TIME] _optional 选项与参数: 默认会秀出全部的 log 内容,从旧的输出到最新的讯息 -n :秀出最近的几行的意思~找最新的信息相当有用 -r :反向输出,从最新的输出到最旧的数据 -p :秀出后面所接的讯息重要性排序!请参考前一小节的 rsyslogd 信息 -f :类似 tail -f 的功能,持续显示 journal 日志的内容(实时监测时相当有帮助!) --since --until:设置开始与结束的时间,让在该期间的数据输出而已 _SYSTEMD_UNIT=unit.service :只输出 unit.service 的信息而已 _COMM=bash :只输出与 bash 有关的信息 _PID=pid :只输出 PID 号码的信息 _UID=uid :只输出 UID 为 uid 的信息 SYSLOG_FACILITY=[0-23] :使用 syslog.h 规范的服务相对序号来调用出正确的数据! 范例一:秀出目前系统中所有的 journal 日志数据 [root@study ~]# journalctl -- Logs begin at Mon 2015-08-17 18:37:52 CST, end at Wed 2015-08-19 00:01:01 CST. -- Aug 17 18:37:52 study.centos.vbird systemd-journal[105]: Runtime journal is using 8.0M (max 142.4M, leaving 213.6M of free 1.3G, current limit 142.4M). Aug 17 18:37:52 study.centos.vbird systemd-journal[105]: Runtime journal is using 8.0M (max 142.4M, leaving 213.6M of free 1.3G, current limit 142.4M). Aug 17 18:37:52 study.centos.vbird kernel: Initializing cgroup subsys cpuset Aug 17 18:37:52 study.centos.vbird kernel: Initializing cgroup subsys cpu .....(中间省略)..... Aug 19 00:01:01 study.centos.vbird run-parts(/etc/cron.hourly)[19268]: finished 0anacron Aug 19 00:01:01 study.centos.vbird run-parts(/etc/cron.hourly)[19270]: starting 0yum-hourly.cron Aug 19 00:01:01 study.centos.vbird run-parts(/etc/cron.hourly)[19274]: finished 0yum-hourly.cron # 从这次开机以来的所有数据都会显示出来!通过 less 一页页翻动给管理员查阅!数据量相当大! 范例二:(1)仅显示出 2015/08/18 整天以及(2)仅今天及(3)仅昨天的日志数据内容 [root@study ~]# journalctl --since "2015-08-18 00:00:00" --until "2015-08-19 00:00:00" [root@study ~]# journalctl --since today [root@study ~]# journalctl --since yesterday --until today 范例三:只找出 crond.service 的数据,同时只列出最新的 10 笔即可 [root@study ~]# journalctl _SYSTEMD_UNIT=crond.service -n 10 范例四:找出 su, login 执行的登录文件,同时只列出最新的 10 笔即可 [root@study ~]# journalctl _COMM=su _COMM=login -n 10 范例五:找出讯息严重等级为错误 (error) 的讯息! [root@study ~]# journalctl -p err 范例六:找出跟登录服务 (auth, authpriv) 有关的登录文件讯息 [root@study ~]# journalctl SYSLOG_FACILITY=4 SYSLOG_FACILITY=10 # 更多关于 syslog_facility 的数据,请参考 18.2.1 小节的内容啰!
那如果想要了解到登录文件的实时变化,那又该如何处置呢?
现在,请开两个终端机,让我们来处理处理!
# 第一号终端机,请使用下面的方式持续侦测系统! [root@study ~]# journalctl -f # 这时系统会好像卡住~其实不是卡住啦!是类似 tail -f 在持续的显示登录文件信息的! # 第二号终端机,使用下面的方式随便发一封 email 给系统上的帐号! [root@study ~]# echo "testing" | mail -s 'tset' dmtsai # 这时,你会发现到第一号终端机竟然一直输出一些讯息吧!没错!这就对了!
1.6)、logger指令的运用
上面谈到的是叫出登录文件给我们查阅,那换个角度想,“如果你想要让你的数据储存到登录文件当中”呢?那该如何是好? 这时就得要使用 logger 这个好用的家伙了!这个家伙可以传输很多信息。
[root@study ~]# logger [-p 服务名称.等级] "讯息" 选项与参数: 服务名称.等级 :这个项目请参考 rsyslogd 的本章后续小节的介绍; 范例一:指定一下,让 dmtsai 使用 logger 来传送数据到登录文件内 [root@study ~]# logger -p user.info "I will check logger command" [root@study ~]# journalctl SYSLOG_FACILITY=1 -n 3 -- Logs begin at Mon 2015-08-17 18:37:52 CST, end at Wed 2015-08-19 18:03:17 CST. -- Aug 19 18:01:01 study.centos.vbird run-parts(/etc/cron.hourly)[29710]: starting 0yum-hourly.cron Aug 19 18:01:01 study.centos.vbird run-parts(/etc/cron.hourly)[29714]: finished 0yum-hourly.cron Aug 19 18:03:17 study.centos.vbird dmtsai[29753]: I will check logger command
1.7)、保存 journal 的方式
再强调一次,这个 systemd-journald.servicd 的讯息是不会放到下一次开机后的,所以,重新开机后,那之前的记录通通会遗失。
如果想要保存你的journalctl 所读取的登录文件, 那么就得要创建一个 /var/log/journal 的目录,并且处理一下该目录的权限,那么未来重新启动 systemdjournald.service 之后, 日志登录文件就会主动的复制一份到 /var/log/journal 目录下。
# 1. 先处理所需要的目录与相关权限设置 [root@study ~]# mkdir /var/log/journal [root@study ~]# chown root:systemd-journal /var/log/journal [root@study ~]# chmod 2775 /var/log/journal # 2. 重新启动 systemd-journald 并且观察备份的日志数据! [root@study ~]# systemctl restart systemd-journald.service [root@study ~]# ll /var/log/journal/ drwxr-sr-x. 2 root systemd-journal 27 Aug 20 02:37 309eb890d09f440681f596543d95ec7a
1.7)、分析登录文件
CentOS 有提供 logwatch 这个登录文件分析程序,你可以借由该程序来了解登录文件信息。
而之前谈过的 last, lastlog, dmesg 等等指令,由于这些数据都非常的分散,如果想要一口气读取所有的登录信息, 其实有点困扰的。
【重点回顾】
① 登录文件可以记录一个事件的何时、何地、何人、何事等四大信息,故系统有问题时务必查询登录文件;
② 系统的登录文件默认都集中放置到 /var/log/ 目录内,其中又以 messages 记录的信息最多!
③ 登录文件记录的主要服务与程序为: systemd-journald.service, rsyslog.service, rsyslogd
④ rsyslogd 的配置文件在 /etc/rsyslog.conf ,内容语法为:“ 服务名称.等级 记载设备或文件”
⑤ 通过 linux 的 syslog 函数查询,了解上述服务名称有 kernel, user, mail...从 0 到 23 的服务序号
⑥ 承上,等级从不严重到严重依序有 info, notice, warning, error, critical, alert, emergency 等;
⑦ rsyslogd 本身有提供登录文件服务器的功能,通过修改 /etc/rsyslog.conf 内容即可达成;
⑧ logrotate 程序利用 crontab 来进行登录文件的轮替功能;
⑨ logrotate 的配置文件为 /etc/logrotate.conf ,而额外的设置则可写入 /etc/logrotate.d/* 内;
⑩ 新的 CentOS 7 由于内置 systemd-journald.service 的功能,可以使用 journalctl 直接从内存读出登录文件,查询性能较佳;
⑪ logwatch 为 CentOS 7 默认提供的一个登录文件分析软件。
Over......