一、sudo
sudo是允许普通用户执行一部分或全部root命令的一种工具。
配置文件位置:/etc/sudo.conf。文件格式如下:
user host=(runas) [TAG:]command # 授权user用户可以在host主机上以runas用户的身份执行command命令(TAG:可省略)
#可使用通配符
? #任意单个字符
* #任意长度字符
[abc] #匹配abc中任意一个字符
[!abc] #匹配任意一个除abc之外的字符
\x #转义
[[alpha]] #字母
#user 和 runnas
userName #用户名
#uid #用户ID
%groupName #组名
%#gid #组ID
User_Alias #user组名
Runas_Alias #runas别名
#host
ip #ip地址
hostname #主机名
network/netmask #网段/子网掩码
Host_Alias #别名
#command
cmmand #具体命令
directory/* #某个目录下的所有命令
sudoedit #sudoedit命令,有此命令就可以编辑sudo规则
Cmnd_Alias #命令别名
sudo规则配置文件示例:
njn 192.168.206.133=(root) /bin/ls /root/
njn 192.168.206.0/24=(root) /bin/touch /root/from-haha
njn 192.168.206.133=(tom) /bin/cat /home/tom/1.txt
切换到普通用户,输入 sudo ls /root/,输入密码后可以执行命令。
[root@rocky ~]# su - njn
[njn@rocky ~]$ sudo ls /root/
1.txt 20 5 anaconda-ks.cfg from-haha initial-setup-ks.cfg
可以执行 touch /root/from-haha
[njn@rocky ~]$ sudo touch /root/from-haha
[njn@rocky ~]$
[njn@rocky ~]$ sudo ls /root/
1.txt 20 5 anaconda-ks.cfg from-haha initial-setup-ks.cfg
以tom身份执行查看tom家目录下的1.txt文件:
[root@rocky ~]# cat /home/tom/1.txt
111
[root@rocky ~]# su - njn
[njn@rocky ~]$ sudo -u tom cat /home/tom/1.txt
111
二、时钟同步服务
当在多台服务器上执行对某些时刻的统一配置时,若不同服务器的时间不同步则会带来很多麻烦,基于时钟同步服务器可以实现多台服务器的时钟同步。
接下来演示在本地搭建时钟同步服务器,实现多台客户机的时钟同步功能。
环境搭建:
本地需要搭建三台机器,其中NTP服务器,两台客户端,IP地址如上图所示。
服务器配置:
[root@rocky ~]# vim /etc/chrony.conf
# 新增2条配置
[root@rocky ~]# tail -2 /etc/chrony.conf
allow 192.168.206.0/24 # 允许10.0.0网段的主机以本机作为时间同步服务器同步时间
local stratum 10 # 允许本机在不能与外地同步的情况下,提供服务
# 重启服务
[root@rocky ~]# systemctl restart chronyd
客户端配置:
[root@rocky ~]# vim /etc/chrony.conf
...
server 192.168.206.134 iburst
[root@rocky ~]# systemctl restart chronyd.service
# 查看时钟同步源的同步状态
[root@rocky ~]# chronyc -n sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 192.168.206.134 4 6 37 25 +101us[ +12ms] +/- 115ms
服务端查看:
[root@rocky ~]# chronyc clients
Hostname NTP Drop Int IntL Last Cmd Drop Int Last
===============================================================================
192.168.206.135 6 0 5 - 40 0 0 - -
192.168.206.133 5 0 4 - 36 0 0 - -
服务端修改时间:
[root@rocky ~]# date -s "-1 day"
Fri Sep 27 14:04:26 CST 2024
[root@rocky ~]# date
Fri Sep 27 14:04:27 CST 2024
客户端重启服务,查看时间:
[root@rocky ~]# systemctl restart chronyd.service
[root@rocky ~]# date
Fri Sep 27 14:05:16 CST 2024
三、日志管理
3.1 常见的日志服务
类似于日常生活的日记记录,在linux系统对服务工作过程中发生的事件采用日志记录,便于得知服务做了哪些事,排查问题。
sysklogd
centos5以及之前的发行版中,其采用的sysklogd服务来记录和管理系统日志。
sysklogd服务有2个模块:
- klogd: 用于记录 linux kernel 相关的日志
- syslogd: 用于记录用户空间应用日志
rsyslog
rsyslog 是 CentOS6 以后的版本中使用的日志管理程序,是一个默认安装的服务,并且默认开机启动。其拥有以下功能:
- 支持输出日志到各种数据库,如 MySQL,PostgreSQL,MongoDB ElasticSearch,实现使用第三方服务对日志进行存储和分析;
- 精细的输出格式控制以及对日志内容的强大过滤能力,可实现过滤记录日志信息中的指定部份;通过 RELP + TCP 实现数据的可靠传输
- 支持数据的加密和压缩传输等多线程
- 多线程
ELK
ELK 是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。在后续发展的过程中增加了一个 FileBeat,这几款软件通常在一起配合使用,各司其职。ELK 主要用于部署在企业架构中,收集多台设备上多个服务的日志信息,并将其统一整合后提供给用户。我们后面的课程中会有专门的章节讲解 ELK 服务。
rsyslog 主要用于单机日志管理,ELK 主要用于分布式集群环境中的日志管理。
3.2 常见的日志分类和优先级别
常见的日志分类:
LOG_AUTH #auth 安全和认证相关的日志
LOG_AUTHPRIV #authpriv 安全和认证相关的日志,私有
LOG_CRON #cron 系统定时任务 crontab 与 at 产生的相关日志
LOG_DAEMON #daemon 各守护进程产生的日志
LOG_FTP #ftp ftp守护进程产生的日志
LOG_KERN #kern 内核产生的日志
LOG_LOCAL0 -- LOG_LOCAL7 #local0-local7 自定义分类
LOG_LPR #lpr 打印服务日志
LOG_MAIL #mail 邮件服务日志
LOG_NEWS #news 网络新闻服务产生的日志
LOG_SYSLOG #syslog syslogd 服务自己的日志
LOG_USER #user 用户等级
LOG_UUCP #uucp uucp子系统的日志信息
* #通配符,代表所有分类
常见的日志优先级:
#syslog 内置优先级分类,从高到低,如果在记录日志时,设置了优先级,则只会记录设定的优先级和高于
设定优先级的日志
LOG_EMERG #emerg/panic 紧急,致命错误
LOG_ALERT #alert 告警,当前状态必须立即进行纠正
LOG_CRIT #crit 关键状态的警告,例如 硬件故障
LOG_ERR #err/error 其它错误
LOG_WARNING #warning/warn 警告级别的信息
LOG_NOTICE #notice 通知级别的信息
LOG_INFO #info 通告级别的信息
LOG_DEBUG #debug 调试程序时的信息
* #所有级别的日志
none #不需要任何日志
#panic,error,warn在新版中被弃,不建议使用
例如,sshd服务的日志分类是 AUTHPRIV:
[root@rocky ~]# cat /etc/ssh/sshd_config |grep SyslogFacility
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
AUTHPRIV的所有级别的日志都写入文件 /var/log/secure:
[root@rocky ~]# cat /etc/rsyslog.conf | grep -i AUTHPRIV
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
我们来测试验证下以上结论,首先,在另一台主机上登录和登出本机。
[root@rocky ~]# ssh 192.168.206.135
...
Last login: Sat Sep 28 13:46:06 2024 from 192.168.206.1
[root@rocky ~]# exit
logout
Connection to 192.168.206.135 closed.
日志文件/var/log/secure记录了用户登录与登出行为:
[root@rocky ~]# tail -f /var/log/secure
...
Sep 28 15:04:40 rocky sshd[5266]: Accepted password for root from 192.168.206.134 port 47900 ssh2
Sep 28 15:04:41 rocky sshd[5266]: pam_unix(sshd:session): session opened for user root by (uid=0)
Sep 28 15:04:51 rocky sshd[5270]: Received disconnect from 192.168.206.134 port 47900:11: disconnected by user
Sep 28 15:04:51 rocky sshd[5270]: Disconnected from user root 192.168.206.134 port 47900
Sep 28 15:04:51 rocky sshd[5266]: pam_unix(sshd:session): session closed for user root
3.3 常见日志文件
/var/log/messages #除了mail,authpriv,cron 之外都记录
/var/log/secure #安全认证相关日志
/var/log/maillog #邮件服务相关日志
/var/log/cron #定时任务相关日志
*.emerg :omusrmsg:* #所有致命错误信息,调用omusrmsg发给所有登录用户
/var/log/spooler #uucp,新闻相关日志
/var/log/boot.log #操作系统启动流程日志
/var/log/dmesg* #系统硬件相关体重
3.4 journal
在 systemd 为 1号进程的系统版本中,systemd 提供了一个集中的方式来处理所有来自进程,应用程序等的操作系统日志,所有这些日志事件都由 systemd 的 journald 守护进程来处理。journald 守护进程收集所有来自 Linux 操作系统的各种日志,并将其作为二进制数据存储在文件中。
以二进制数据集中记录事件、系统问题的好处有很多。例如,由于系统日志是以二进制而不是文本形式存储的,你可以以文本、JSON 对象等多种方式进行转译,以满足各种需求。另外,由于日志是按顺序存储的,通过对日志的日期/时间操作,超级容易追踪到单个事件。
查看所有日志:
[root@rocky dir1]# journalctl
-- Logs begin at Sat 2024-09-28 11:42:08 CST, end at Sat 2024-09-28 20:12:23 CST. --
Sep 28 11:42:08 rocky kernel: Linux version 4.18.0-372.9.1.el8.x86_64 (mockbuild@dal1-prod-builder001.bld.equ.rocky>
Sep 28 11:42:08 rocky kernel: Command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-372.9.1.el8.x86_64 root=/dev/map>
Sep 28 11:42:08 rocky kernel: x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
Sep 28 11:42:08 rocky kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
...
journal日志元数据:
[root@rocky dir1]# journalctl --header
File Path: /var/log/journal/81b007fa45f740bf89bfe92c1dfeca15/system.journal
File ID: da13fac2e5da436c9427648da40ce2f0
Machine ID: 81b007fa45f740bf89bfe92c1dfeca15
Boot ID: 8276a11a7d954f3692cce83dcfd56d37
Sequential Number ID: da13fac2e5da436c9427648da40ce2f0
查看日志分类:
[root@rocky dir1]# journalctl --list-catalog
0027229ca0644181a76c4e92458afa2e systemd: One or more messages could not be forwarded to syslog
0e4284a0caca4bfc81c0bb6786972673 systemd: Unit skipped
1675d7f172174098b1108bf8c7dc8f5d systemd: DNSSEC validation failed
1dee0369c7fc4736b7099b38ecb46ee7 systemd: Mount point is not empty
24d8d4452573402496068381a6312df2 systemd: A virtual machine or container has been started
查看指定分类日志:
[root@rocky dir1]# journalctl --list-catalog 7b05ebc668384222baa8881179cfda54
7b05ebc668384222baa8881179cfda54 systemd: Unit @UNIT@ has finished reloading its configuration
显示日志详细描述信息:
[root@rocky dir1]# journalctl --dump-catalog
-- 0027229ca0644181a76c4e92458afa2e
Subject: One or more messages could not be forwarded to syslog
Defined-By: systemd
Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
...
[root@rocky dir1]# journalctl --dump-catalog 1675d7f172174098b1108bf8c7dc8f5d
-- 1675d7f172174098b1108bf8c7dc8f5d
Subject: DNSSEC validation failed
Defined-By: systemd
Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
Documentation: man:systemd-resolved.service(8)
A DNS query or resource record set failed DNSSEC validation. This is usually
indication that the communication channel used was tampered with.
...
实时显示日志:
[root@rocky dir1]# journalctl -f
-- Logs begin at Sat 2024-09-28 11:42:08 CST. --
Sep 28 20:01:18 rocky1 systemd-journald[8814]: Journal started
Sep 28 20:01:18 rocky1 systemd-journald[8814]: System journal (/var/log/journal/81b007fa45f740bf89bfe92c1dfeca15) is 8.0M, max 4.0G, 3.9G free.
...
倒序显示:
[root@rocky dir1]# journalctl -r
-- Logs begin at Sat 2024-09-28 11:42:08 CST, end at Sat 2024-09-28 20:20:09 CST. --
Sep 28 20:20:09 rocky1 systemd[1]: Started system activity accounting tool.
Sep 28 20:20:09 rocky1 systemd[1]: sysstat-collect.service: Succeeded.
...
3.5 自定义日志配置案例
3.5.1 修改服务的日志分类和日志文件
目标是将sshd应用日志分类改成local6,日志打入文件 /var/log/ssh.log。
首先,配置sshd服务日志分类:
[root@rocky dir1]# vim /etc/ssh/sshd_config
#SyslogFacility AUTH
#SyslogFacility AUTHPRIV
#LogLevel INFO
SyslogFacility LOCAL6
rsyslog.conf 配置将分类authpriv的日志打入文件 /var/log/ssh.log:
# authpriv.* /var/log/secure
local6.* /var/log/ssh.log
测试登录和登出:
[root@rocky dir1]# ssh 127.1
[root@rocky ~]# exit
logout
Connection to 127.0.0.1 closed.
/var/log/ssh.log存在对应日志:
[root@rocky dir1]# tail /var/log/ssh.log
...
Sep 28 15:37:11 rocky sshd[5872]: Accepted password for root from 127.0.0.1 port 40042 ssh2
Sep 28 15:37:21 rocky sshd[5876]: Received disconnect from 127.0.0.1 port 40042:11: disconnected by user
Sep 28 15:37:21 rocky sshd[5876]: Disconnected from user root 127.0.0.1 port 40042
3.5.2 跨主机的日志服务
实现将A主机的sshd服务日志写入B主机的/var/log/all-ssh.log上。
在B主机上开启rsyslog的tcp和udp监听端口,并设置authpriv分类日志写入文件/var/log/all-ssh.log:
[root@rocky ~]# vim /etc/rsyslog.conf
# Provides UDP syslog reception
# for parameters see http://www.rsyslog.com/doc/imudp.html
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")
# Provides TCP syslog reception
# for parameters see http://www.rsyslog.com/doc/imtcp.html
module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514")
# The authpriv file has restricted access.
#authpriv.* /var/log/secure
authpriv.* /var/log/all-ssh.log
B主机上配置A主机的DNS映射:
[root@rocky ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.206.135 rocky1 #A主机的DNS映射
A主机的rsyslog.conf文件配置日志发送给B主机:
[root@rocky dir1]# vim /etc/rsyslog.conf
# The authpriv file has restricted access.
#authpriv.* /var/log/secure
*.info @192.168.206.134:514
A主机设置DNS域名映射,并修改hostname:
[root@rocky dir1]# cat /etc/hosts
#127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 rocky1
::1 rocky1
#::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@rocky dir1]# hostnamectl set-hostname rocky1
注意两台主机都要重启rsyslog服务:
systemctl restart rsyslog.service
我们来测试下,在A主机上生成日志:
[root@rocky dir1]# ssh 127.1
root@127.0.0.1's password:
B主机查看生成相应日志,测试成功:
[root@rocky log]# tail -f all-ssh.log
...
Sep 28 16:53:55 rocky1 sshd[6945]: Accepted password for root from 127.0.0.1 port 40044 ssh2
Sep 28 16:53:55 rocky1 sshd[6945]: pam_unix(sshd:session): session opened for user root by (uid=0)
Sep 28 16:54:01 rocky1 sshd[6952]: Received disconnect from 127.0.0.1 port 40044:11: disconnected by user
Sep 28 16:54:01 rocky1 sshd[6952]: Disconnected from user root 127.0.0.1 port 40044
Sep 28 16:54:01 rocky1 sshd[6945]: pam_unix(sshd:session): session closed for user root
3.5.3 日志存储到mysql数据库
接下来在上一小节的基础上,演示将日志存储到mysql数据库。增设一台C主机作为mysql服务器,目标是让A和B主机sshd服务生成的日志都写入C主机的mysql数据库。
首先,在B主机上安装rsyslog-mysql
[root@rocky ~]# yum install -y rsyslog-mysql
Last metadata expiration check: 2:07:57 ago on Sat 28 Sep 2024 06:53:12 PM CST.
Dependencies resolved.
查看服务文件
[root@rocky ~]# rpm -ql rsyslog-mysql
/usr/lib/.build-id
/usr/lib/.build-id/7e
/usr/lib/.build-id/7e/30458f368f71ec11b45c0445303b98fbc47a9c
/usr/lib64/rsyslog/ommysql.so
/usr/share/doc/rsyslog/mysql-createDB.sql # mysql数据库表文件
在C主机上安装mysql
[root@rocky ~]# yum -y install mysql
进入mysql创建数据库表:
# 进入mysql
[root@rocky ~]# mysql -u root -pnjn1916049
...
#创建数据库
mysql> create database rsyslog
-> ;
Query OK, 1 row affected (0.11 sec)
# 进入数据库
mysql> use rsyslog
Database changed
# 执行rsyslog-mysql服务的sql语句创建表
mysql> source /usr/share/doc/rsyslog/mysql-createDB.sql
Query OK, 1 row affected (0.01 sec)
Database changed
Query OK, 0 rows affected (0.17 sec)
Query OK, 0 rows affected (0.02 sec)
# 显示表
mysql> show tables
-> ;
+------------------------+
| Tables_in_Syslog |
+------------------------+
| SystemEvents |
| SystemEventsProperties |
+------------------------+
2 rows in set (0.00 sec)
#两张表皆为空
mysql> select * from SystemEvents;
Empty set (0.01 sec)
mysql> select * from SystemEventsProperties;
Empty set (0.00 sec)
# 创建用户并授权
mysql> create user 'rsysloger'@'192.168.206.*' identified by 'njn1916049';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on rsyslog.* to 'rsysloger'@'192.168.206.*';
Query OK, 0 rows affected (0.03 sec)
B主机rsyslog添加如下配置,开启rsyslog-mysql模块,将日志存储到mysql服务器:
[root@rocky ~]$ vim /etc/rsyslog.conf
module(load="ommysql")
*.* action(type="ommysql" server="192.168.206.136" db="Syslog" uid="rsysloger" pwd="123456")
A B主机输出log:
[root@rocky ~]# logger "lalaal"
C主机查看数据库存入了对应log:
mysql> select fromhost,message from SystemEvents order by id desc limit 2;
+----------+---------+
| fromhost | message |
+----------+---------+
| rocky2 | lalaal |
| rocky8 | lalaal |
+----------+---------+
2 rows in set (0.00 sec)
3.6 日志转储
logrotate 程序是一个日志文件管理工具。用来把旧的日志文件删除,并创建新的日志文件,称为日志转储或滚动。可以根据日志文件的大小,也可以根据其天数来转储,这个过程一般通过 cron程序来执行。
接下来实现nginx自定义日志转储规则,要求每天切割一次,要求大于不超过3M, 保存90天的日志,旧日志以时间为后缀,要求压缩。
首先,在本地安装nginx,nginx转储规则配置如下:
[root@rocky log]# vim /etc/logrotate.d/nginx
/var/log/nginx/*log {
create 0664 nginx root #创建新日志文件的属主属组权限
daily #每日转储一次
rotate 90 #保留90份的日志
size 3M #大小超过3M就转储
missingok #文件不存在不提示错误
dateext #转储文件以日期为后缀
notifempty #文件为空不转储
compress #压缩
sharedscripts #转储前脚本
postrotate #转储后脚本
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}
模拟生成大日志文件:
[root@rocky nginx]# dd if=/dev/zero of=./nginx.log bs=1M count=5
5+0 records in
5+0 records out
5242880 bytes (5.2 MB, 5.0 MiB) copied, 0.00191479 s, 2.7 GB/s
手动执行日志转储:
[root@rocky log]# logrotate /etc/logrotate.d/nginx
转储后 /var/log/nginx 目录下的文件:
[root@rocky nginx]# ll
total 8
-rw-rw-r-- 1 nginx root 0 Sep 29 10:21 nginx.log
-rw-r--r-- 1 root root 5115 Sep 29 10:21 nginx.log-20240929.gz