首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
28
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
26
篇与
的结果
2023-08-30
Linux命令之grep
Linux命令之grep命令简介文本查找或搜索工具 。用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为 -,则grep会从标准输入设备读取数据。同样可以配合正则表达式来搜索文本,并将匹配的行打印输出,也可用于过滤与搜索特定字符串,使用十分灵活常用参数-a #不要忽略二进制数据-A #除了显示符合范本样式的那一行之外,并显示该行之后的内容-b #在显示符合范本样式的那一行之外,并显示该行之前的内容-B #除了显示符合样式的那一行之外,并显示该行之前的内容-c #计算符合范本样式的列数-C #除了显示符合范本样式的那一列之外,并显示该列之前后的内容-d #当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作-e #指定字符串作为查找文件内容的范本样式-E #将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式-f #指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式-F #将范本样式视为固定字符串的列表-G #将范本样式视为普通的表示法来使用-h #在显示符合范本样式的那一列之前,不标示该列所属的文件名称-H #在显示符合范本样式的那一列之前,标示该列的文件名称-i #忽略字符大小写的差别-l #列出文件内容符合指定的范本样式的文件名称-L #列出文件内容不符合指定的范本样式的文件名称-n #在显示符合范本样式的那一列之前,标示出该列的编号-q #不显示任何信息-R/-r #此参数的效果和指定“-d recurse”参数相同-s #不显示错误信息-v #反转查找-V #显示版本信息 -w #只显示全字符合的列-x #只显示全列符合的列-y #此参数效果跟“-i”相同-o #只输出文件中匹配到的部分正则表达式^ #匹配以XX开头的行$ #匹配以XX结尾的行常用实例1、在多个文件中查找:grep "file" file_1 file_2 file_32、输出除之外的所有行 -v 选项:grep -v "file" file_name3、标记匹配颜色 --color=auto 选项:grep "file" file_name --color=auto4、使用正则表达式 -E 选项:grep -E "[1-9]+" egrep "[1-9]+"5、只输出文件中匹配到的部分 -o 选项:echo this is a test line. | grep -o -E "[a-z]+." line. echo this is a test line. | egrep -o "[a-z]+." line.6、统计文件或者文本中包含匹配字符串的行数-c 选项:grep -c "text" file_name 27、输出包含匹配字符串的行数 -n 选项:grep "text" -n file_name 或 cat file_name | grep "text" -n8、多个文件grep "text" -n file_1 file_29、搜索多个文件并查找匹配文本在哪些文件中:grep -l "text" file1 file2 file3...10、grep递归搜索文件在多级目录中对文本进行递归搜索:grep "text" . -r -n11、忽略匹配样式中的字符大小写:echo "hello world" | grep -i "HELLO" hello12、选项 -e 指定多个匹配样式:echo this is a text line | grep -e "is" -e "line" -o is line13、也可以使用 -f 选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。cat patfile aaa bbb echo aaa bbb ccc ddd eee | grep -f patfile -o14、在grep搜索结果中包括或者排除指定文件:只在目录中所有的.php和.html文件中递归搜索字符"main()"grep "main()" . -r --include *.{php,html}15、在搜索结果中排除所有README文件grep "main()" . -r --exclude "README"16、在搜索结果中排除filelist文件列表里的文件grep "main()" . -r --exclude-from filelist实例grep "San" testfile #过滤有San的行 grep '^J' testfile #显示以J开头的行 grep '70$' testfile #显示以70结尾的行 grep -v "834" testfile #显示所有不包括834的行 grep ':12/' testfile #显示:12/的行 grep ':498-' testfile #显示:498-的行 grep '[A-Z][a-z]{4}:[[:space:]][A-Z]' testfile #显示这样的行,一个大写字母+四个小写字母+空格+一个大写字母 grep '[a-z]{1,}[[:space:]][Kk]' testfile #显示包括K k的行 grep -n '[0-9]{6,}$' testfile #显示6位数字的行,并打印行号 grep -i "lincoln" testfile #显示有lincoln的行,不区分大小写
2023年08月30日
17 阅读
0 评论
0 点赞
2023-08-30
Linux 命令之systemd
Linux 命令之systemdsystemd介绍systemd是目前Linux系统上主要的系统守护进程管理工具,由于init一方面对于进程的管理是串行化的,容易出现阻塞情况,另一方面init也仅仅是执行启动脚本,并不能对服务本身进行更多的管理。所以从CentOS 7开始也由systemd取代了init作为默认的系统进程管理工具。systemd所管理的所有系统资源都称作Unit,通过systemd命令集可以方便的对这些Unit进行管理。比如systemctl、hostnamectl、timedatectl、localctl等命令,这些命令虽然改写了init时代用户的命令使用习惯(不再使用chkconfig、service等命令),但确实也提供了很大的便捷性。systemd特点1.最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15...)2.CentOS7 支持开机并行启动服务,显著提高开机启动效率3.CentOS7关机只关闭正在运行的服务,而CentOS6,全部都关闭一次。4.CentOS7服务的启动与停止不再使用脚本进行管理,也就是/etc/init.d下不在有脚本。5.CentOS7使用systemd解决原有模式缺陷,比如原有service不会关闭程序产生的子进程。systemd语法systemctl [command] [unit](配置的应用名称) command可选项 · start:启动指定的unit systemctl start nginx · stop:关闭指定的unit systemctl stop nginx · restart:重启指定unit systemctl restart nginx · reload:重载指定unit systemctl reload nginx · enable:系统开机时自动启动指定unit,前提是配置文件中有相关配置 systemctl enable nginx · disable:开机时不自动运行指定unit systemctl disable nginx · status:查看指定unit当前运行状态 systemctl status nginxsystemd配置文件说明每一个Unit都需要有一个配置文件用于告知systemd对于服务的管理方式配置文件存放于/usr/lib/systemd/system/,设置开机启动后会在/etc/systemd/system目录建立软链接文件每个Unit的配置文件配置默认后缀名为.service在/usr/lib/systemd/system/目录中分为system和user两个目录,一般将开机不登陆就能运行的程序存在系统服务里,也就是/usr/lib/systemd/system配置文件使用方括号分成了多个部分,并且区分大小写systemd相关文件实战一、源码编译安装nginx 实现systemd管理控制安装nginx编译环境yum -y install gcc gcc-c++ openssl-devel pcre-devel gd-devel iproute net-tools telnet wget curl wget http://nginx.org/download/nginx-1.15.5.tar.gz tar zxf nginx-1.15.5.tar.gz && cd nginx-1.15.5 ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module make -j 4 && make install通用方式启动nginx/usr/local/nginx/sbin/nginx #启动 /usr/local/nginx/sbin/nginx -s reload #重启 /usr/local/nginx/sbin/nginx -s quit #关闭nginxsystemd 管理控制启动模式vim /usr/lib/systemd/system/nginx.service[Unit] Description=nginx After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target参数详解systemctl restart nginx systemctl enable nginx systemctl stop nginx如图所示实现了systemd 管理控制nginx服务实战二、二进制安装tomcat 实现systemd管理控制安装java环境我已经将安装包打包到我的服务器上,也可以去官网下载wget 120.78.77.38/file/jdk-8u231-linux-x64.rpm wget 120.78.77.38/file/apache-tomcat-9.0.27.tar.gzrpm -ivh jdk-8u231-linux-x64.rpm #rpm直接安装jdk配置环境变量export JAVA_HOME=/usr/java/jdk1.8.0_231-amd64 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin export PATH=${JAVA_HOME}/bin:$PATH 安装tomcattar -xf apache-tomcat-9.0.27 mv apache-tomcat-9.0.27 /usr/local/tomcat启动tomcatsh /usr/local/tomcat/bin/startup.sh #启动 sh /usr/local/tomcat/bin/shutdown.sh #关闭systemd管理控制启动[Unit] Description=tomcat server Wants=network-online.target After=network.target [Service] Type=forking WorkingDirectory=/home/dingding/service/tomcat/bin Environment="JAVA_HOME=/usr/java/jdk1.8.0_231-amd64" Environment="PATH=$JAVA_HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin" Environment="CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar" ExecStart=/usr/local/tomcat/bin/startup.sh ExecStop=/usr/local/tomcat/bin/shutdown.sh Restart=on-failure [Install] WantedBy=multi-user.targetubuntu系统tomcat配置[Unit] Description=tomcat server Wants=network-online.target After=network.target [Service] Type=forking WorkingDirectory=/home/dingding/service/tomcat/bin UMask=0007 Environment="JAVA_HOME=/usr/local/jdk/jre" Environment=CATALINA_PID=/home/dingding/service/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/home/dingding/service/tomcat Environment=CATALINE_BASE=/home/dingding/service/tomcat ExecStart=/home/dingding/service/tomcat/bin/startup.sh ExecStop=/home/dingding/service/tomcat/bin/shutdown.sh User=dingding Group=dingding [Install] WantedBy=default.targetsystemctl restart tomcat #启动 systemctl enable tomcat #配置自启 systemctl stop tomcat #停止服务 systemctl status tomcat #检测状态 systemctl daemon-reload 重新加载配置以上两个实战nginx和tomcat程序中自带了启动停止脚本,如果启动得程序没有自带脚本则需要自己编写一个类似得启动停止脚本实战三、部署jar程序 实现systemd管理控制实际得项目中会有一些jar程序需要启动 如果手动启动则需要输入一大串命令 停止则需要杀掉进程来停止,很麻烦举一个实际启动得例子切换到jar目录下java -jar decode.jar -Dconfig=/usr/local/abc/application.properties编写一个启动脚本vim demo.sh#!/bin/bash # source /etc/profile jarName="abc-web.jar" workDir="/usr/local/abc" start(){ cd ${workDir} && java -jar ${jarName} --spring.profiles.active=prod --server.port=9630 >uams.log 2>&1 & } stop(){ ps -ef | grep -qP "(?<=-jar)\s+${jarName}" && kill $(ps -ef | grep -P "(?<=-jar)\s+${jarName}" | awk '{print $2}') } case $1 in start) start ;; stop) stop ;; restart) stop start ;; esac编写 systemd配置文件vim /usr/lib/systemd/system/abc.service[Unit] Description=uams server Wants=network-online.target After=network.target [Service] Type=forking WorkingDirectory=/usr/local/abc/ ExecStart=/bin/bash uams.sh start ExecStop=/bin/bash uams.sh stop ExecReload=/bin/bash uams.sh restart Restart=on-failure [Install] WantedBy=multi-user.target启动abc服务systemctl restart abc #启动 systemctl enable abc #配置自启 systemctl stop abc #停止服务 systemctl status abc #检测状态高级写法还有一种更高级的写法,在service中直接定义环境变量和脚本cat /lib/systemd/system/yuxin-house.service[Unit] Description=yuxin house Wants=network-online.target After=network.target [Service] Type=simple WorkingDirectory=/home/dingding/yuxin-house UMask=0007 Environment=PATH=/usr/local/jdk-11/bin:/usr/local/jdk-11/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin Environment=JAVA_HOME=/usr/local/jdk-11 Environment=CLASSPATH=/usr/local/jdk-11/lib:/usr/local/jdk-11/jre/lib:/usr/local/jdk-11/lib/tools.jar:/usr/local/jdk/lib:/usr/local/jdk/jre/lib:/usr/local/jdk/lib/tools.jar:/usr/local/jdk-11/lib:/usr/local/jdk-11/jre/lib:/usr/local/jdk-11/lib/tools.jar ExecStart=/usr/local/jdk-11/bin/java -XX:+UseG1GC -XX:MaxGCPauseMillis=150 -Xms125M -Xmx512M -jar yuxin-house.jar --spring.profiles.active=test ExecStop=/bin/kill -9 $MAINPID Restart=on-failure StartLimitBurst=4 User=dingding Group=dingding [Install] WantedBy=multi-user.target
2023年08月30日
19 阅读
0 评论
0 点赞
2023-08-30
Linux 命令之scp
Linux 命令之scp
2023年08月30日
10 阅读
0 评论
0 点赞
2023-08-30
Linux 命令之crontab
Linux 命令之crontab命令简介在服务器安装好系统及相关服务之后,对于系统的配置、服务的配置、数据的管理以及服务器的操作权限管理就变的尤为重要。因为,涉及到服务器的各项安全(如:登录、操作)。crontab 命令用来打开 cron 表进行编辑。定时任务:顾名思义,就是定期执行某项操作或者某种行为。像Windows系统同样它也有定时任务服务。在Linux系统中,crond是Linux系统中用来定期执行命令、脚本或指定程序的一种服务。定时任务一般有以下两种用途:1、系统自身定期执行的操作或任务(如:日志轮询)。2、用户定期执行的操作或任务(如:定时更新同步数据、重要数据备份等)。Linux下的任务调度分为两类:系统任务调度和用户任务调度系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc/目录下有一个crontab文件,这个就是系统任务调度的配置文件。/etc/crontab 文件内容如下[root@centos7 ~]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed从上机的配置文件,可以看出系统定时任务格式/etc/crontab分为6段,以空格分隔。前5段为时间格式,第6段是所需执行的命令。详细的说明:minute #分钟,可以是从0到59之间的任何整数hour #小时,可以是从0到23之间的任何整数day #日期,可以是从1到31之间的任何整数month #月份,可以是从1到12之间的任何整数week #星期,可以是从0到7之间的任何整数,这里的0或7代表星期日command #执行的命令,可以是系统命令,也可以是自己编写的脚本文件在上述的配置字段中,还会使用到下面的特殊字符*(星号) #表示所有值。比如在第一段中如果使用*,则表示在满足其他条件的同时每分钟都执行后面的命令操作。,(逗号) #用逗号分隔的值表示指定的一个范围。比如在第四段使用1,3,5,7,则表示在第1,3,5,7月的含义。—(中杠) #表示一个范围。比如在第二段使用0-8,则表示0点到8点这一区间范围。/(正斜线) #表示一个时间的间隔频率。比如在第一段使用*/5,则表示每间隔5分钟的含义。语法格式crontab [-u user] file crontab [-u user] [-l | -r | -e] [-i] [-s]选项说明-e #编辑该用户的计时器-l #列出该用户的计时器-r #删除该用户的计时器-u<用户名称> #指定要设定计时器的用户名称-i:在删除定时任务列表时进行确认提示-s:显示该用户的下一个定时任务执行时间定时任务书写与配置书写定任务规范在日常实际生产、测试环境中,书写定时任务是需要遵守一定的规范、规则的。笔者根据自己实际生产环境书写经验,总结如下:1、书写定时任务时必须对每一行或一段加上注释信息。2、如里是以shell脚本执行的任务,在最前面加上解释/bin/sh。3、对于执行脚本的定时任务,需在其结尾加上>/dev/null 2>&1将一些不必要的输出信息重定向到空,也就是不输出不需要的信息。4、使用系统或服务命令要使用绝对路径,再写到脚本,最后将脚本写进定时任务中。5、规范使用目录(如定时任务执行的脚本目录设置成/server/cron_scripts)。2)定时任务配置实际生产、测试环境,对于定时任务的配置也是需要有一定操作规范的,具体如下:1、对于执行命令的形式的定时任务,需要先测试命令执行情况,确认无误后将执行的命令写进脚本。2、对于脚本形式的定时任务,首先就是需要调试脚本的整体执行情况,然后使用规范目录路径写进定时任务。3、对于生产环境的定时任务操作,必须在测试环境进行反复测试,确认无误后再应用到实际生产环境中,然后在定时任务执行后人工进行检查执行情况。对于定时任务的具体实例及各类操作,可参考官方文档说明。读者也可在自己的实验环境进行书写、配置,本章节就不做过多赘述。应用举例查看当前登录用户下的定时任务情况[root@centos7 ~]# crontab -l no crontab for root每小时的第5和第15分钟执行5,15 * * * * command_name在上午9点到11点的第5和第15分钟执行5,15 9-11 * * * command_name每隔3天的上午9点到11点的第5和第15分钟执行5,15 9-11 */3 * * command_name每个星期一的上午9点到11点的第5和第15分钟执行5,15 9-11 * * 1 command_name每月1、11、21日的14:45重启httpd45 14 1,11,21 * * /etc/init.d/httpd restart每周六、周日的1:10重启smb10 1 * * 6,0 /etc/init.d/httpd restart每小时执行/etc/scripts/test.sh这个脚本01 * * * * /etc/scripts/test.sh拓展在Linux中,设置定时任务的方法有多种。以下是常见的几种方法及其使用说明:使用crontab命令:使用crontab -e命令编辑当前用户的cron表。在打开的文件中,每一行代表一个定时任务,使用cron表达式来指定任务执行的时间。例如,以下示例将在每天的上午9点运行脚本/path/to/script.sh:0 9 * * * /path/to/script.sh保存并关闭文件后,cron会自动加载更新后的cron表。使用crontab -l命令查看当前用户的cron表。编辑系统级的/etc/crontab文件:使用文本编辑器打开/etc/crontab文件。每一行代表一个定时任务,使用cron表达式来指定任务执行的时间和要执行的命令。例如,以下示例将在每天的上午9点运行脚本/path/to/script.sh:0 9 * * * root /path/to/script.sh保存并关闭文件后,cron会自动加载更新后的cron表。使用crontab -l命令查看当前用户的cron表。使用/etc/cron.d/目录:在/etc/cron.d/目录中创建一个文件,文件名可以自定义,但不要包含.或/字符。文件内容格式与crontab相同,使用cron表达式来指定任务执行的时间和要执行的命令。例如,创建一个名为mytask的文件,内容如下:0 9 * * * root /path/to/script.sh保存文件后,cron会自动加载更新后的cron表。使用crontab -l命令查看当前用户的cron表。使用systemd的定时器:创建一个.timer文件,用于配置定时器的触发条件和要执行的任务。创建一个.service文件,用于定义要执行的任务的具体命令和其他设置。将这两个文件放置在/etc/systemd/system/目录中。运行systemctl daemon-reload命令,以重新加载systemd配置。使用systemctl start mytimer.timer命令启动定时器。使用systemctl enable mytimer.timer命令将定时器设置为开机启动。使用systemctl status mytimer.timer命令查看定时器的状态。这些方法之间的区别主要在于使用的工具和配置方式。crontab命令和/etc/crontab文件是传统的cron工具,适用于简单的定时任务。/etc/cron.d/目录允许将定时任务分散到多个文件中,更灵活。使用systemd的定时器提供了更精确的时间控制和更高级的功能,适用于需要更复杂任务调度的场景。选择最好的方法取决于您的具体需求和使用场景。如果只需要为当前用户设置定时任务,使用crontab命令是最简单和常见的方法。如果需要为整个系统或其他用户设置定时任务,可以选择编辑/etc/crontab文件或使用/etc/cron.d/目录。如果您使用的是systemd作为初始化系统,并且需要更高级的功能和集成,可以考虑使用systemd的定时器。请根据您的具体需求和系统配置选择最适合您的方式,并参考相关文档以获取更详细的使用说明。systemd进程管理工具详细教程请看这:Linux 命令之systemd
2023年08月30日
21 阅读
0 评论
0 点赞
2023-08-30
审计 Linux 系统的操作行为的 5 种方案对比
审计 Linux 系统的操作行为的 5 种方案对比概述很多时候我们为了安全审计或者故障跟踪排错,可能会记录分析主机系统的操作行为。比如在系统中新增了一个用户,修改了一个文件名,或者执行了一些命令等等,理论上记录的越详细, 越有利于审计和排错的目的。不过过剩的记录也会为分析带来不少麻烦, 尤其是将很多主机的记录行为发送到固定的远程主机中,数据越多,分析的成本便越大。实际上,绝大多数的系统行为都是重复多余的,比如 cron 任务计划,我们信任的程序等, 这些都会产生大量的记录,但很少用于审计分析。基于这个需求,我们在审计系统操作行为的时候,至少应该添加一些过滤规则,避免记录过多的无用信息,比如重复的 cron 任务操作,同时也要避免记录一些敏感信息,比如带密码的命令行操作。满足这些需求后,我们在审计系统操作行为的时候应该遵照以下准则:忽略 cron,daemon 产生的记录;忽略带密码的敏感命令行或脚本操作记录;忽略监控用户(比如 nagios,zabbix,promethus 等)产生的记录;忽略频繁产生日志的操作行为;第二点为可选项,在以明文方式传输到远程日志服务器的时候,我们建议忽略记录。第四点则需要着重强调,比如我们记录一台 web 主机中的所有 connect,accept 网络系统调用操作,虽然可以据此分析该主机所有的网络访问请求,达到安全或者故障定位的目的,但是这两个系统调用可能在短时间内产生大量的日志,对 kernel 和网络日志传输都会产生不小的压力,这种大海捞针似的审计方式我们不推荐直接在线上主机中使用,建议仅在需要定位问题的时候启用。5 种方案下面我们主要介绍有哪几种方式可以实现系统操作的审计:history 记录方式定制 bash 记录方式snoopy 记录方式auditd 记录方式eBPF 记录方式history 记录方式history 方式很传统也很简单,本质上是将历史的命令发送到 syslog 日志中,可以用来简单记录用户的命令操作历史。但是这种方式有几个重要的缺点,并不适合审计的目的:容易被修改,被绕过;记录太简单,没有上下文信息(比如 pid, uid, sid 等);无法记录 shell 脚本内的操作;无法记录非登录的操作;难以实现过滤规则;定制 bash 记录方式定制 bash 方式 比较冷门,本质上是为 bash 源程序增加审计日志的功能,开发者可以据此添加一些操作命令的上下文信息,不过很难记录子进程的信息,其缺点和上述的 history 方式类似:容易被绕过,用户可以使用 csh,zsh 等;无法记录 shell 脚本内的操作;过滤规则可能单一;可能需要不停的更新 bash 版本,工作量大,否则容易被发行版替换;snoopy 记录方式snoopy 方式相对新颖,本质上是封装了 execv,execve 系统调用,以系统预加载(preload)的方式实现记录所有的命令操作。更多介绍可以参考以前的文章 snoopy 如何记录系统执行过的命令。目前大部分系统执行命令时都通过 execv,execve 系统调用执行,这点就和会话无关,几乎所有的情况下,只要通过这两个系统调用执行命令,就会将操作行为记录下来,从目前的最新版本(2.4.8)来看,snoopy 有几个优点:难以绕过,只要设置了 PRELOAD,就肯定会记录;无论是否存在 tty 会话,都会记录 execv,execve 相关的命令行操作,包含详细的进程上下文信息;可以记录 shell 脚本内部的操作行为,脚本内的命令行操作大部分都会调用 execv,execve;可以记录操作行为的参数, 比如指定了用户名,密码等;过滤规则丰富,可以忽略指定 daemon,uid,也可以仅记录指定的 uid;如下日志示例:Oct 27 11:34:31 cz-t1 snoopy[24814]: [time_ms:778 login:cz uid:0 pid:24814 ppid:24676 sid:24579 tty:/dev/pts/0 cwd:/root filename:/bin/uptime username:root]: uptime -p上述日志显示 root 用户执行了uptime命令,参数包含 -p对应的进程上下文信息都比较全,不过 snoopy 的缺点 也比较明显,主要包含以下几点:仅支持 execv,execve 相关系统调用的操作;不设置规则可能产生的日志过多,对日志搜集系统造成很大的负担;暂不支持过滤敏感信息规则;在实际的使用中,snoopy 记录方式可以很详细的记录所有的命令操作信息,帮助我们定位很多疑难问题。不过我们也需要通过过滤规则来避免产生过多的信息,snoopy 的过滤规则可以满足以下需求:忽略 cron,daemon 产生的记录;忽略监控用户(比如 nagios,zabbix,promethus 等) 产生的记录;比如以下配置,即可忽略 crond,my-daemon 守护进程,忽略 zabbix 用户:# zabbix uid 为 992 filter_chain = exclude_uid:992;exclude_spawns_of:crond,my-daemon备注:过滤规则在(filtering.c - snoopy_filtering_check_chain)函数实现,由 log.c - snoopy_log_syscall_exec 函数调用,过滤规则为事后行为,即在打印日志的时候判断是否满足过滤规则,并非事前行为。另外,我们在 snoopy 的基础上增加了 exclude_comm 过滤规则,我们可以忽略记录指定的命令,比如以下:filter_chain = exclude_uid:992;exclude_comm:mysql,mongo,redis-cliexclude_comm 指定忽略以 mysql,mongo 和 redis-cli 工具执行的命令,很多管理员或者脚本在使用这些工具的时候常常会加上用户密码信息,这在明文环境中是很危险的行为,exclude_comm 规则简单的避免了常用工具泄漏敏感信息的隐患。auditd 记录方式auditd 记录方式 本身存在内核层面(kauditd 进程)的支持,它实现了一个大而全的框架,几乎能监控所有想监控的指标,不管是按照访问模式,系统调用还是事件类型触发,都能满足监控需求。因为其提供了内核层面的支持,所以本质上比起 snoopy(仅封装 execv,execve 系统调用)要更加强大和健全。生成的日志也容易查看,进程的上下文信息,参数信息都很全面,如下所示:type=SYSCALL msg=audit(1603800704.305:5304075): arch=c000003e syscall=59 success=yes exit=0 a0=1c79fd0 a1=1bf51a0 a2=1bd4450 a3=7ffe7270d320 items=2 ppid=95264 pid=99702 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=571973 comm="mysql" exe="/usr/bin/mysq l" key="command" type=EXECVE msg=audit(1603800704.305:5304075): argc=5 a0="/usr/bin/mysql" a1="-h" a2="127.0.0.1" a3="-P" a4="3301"auditd 整体上为分离的架构,auditctl 可以控制 kauditd 生成记录的策略,kauditd 生成的记录事件会发送到 auditd 守护程序,audisp 可以消费 auditd 的记录到其它地方。其主要的几个工具包含如下:auditd 的策略规则主要根据 -a 或 -w 参数设置,可以将策略规则保存到默认的 /etc/audit/rules.d/audit.rules 配置,也可以通过 auditctl 动态的调整。值得注意的是策略规则的加载是按照顺序生效的,我们在配置例外情况的时候就需要注意将例外情况添加到合适的位置,比如参考 auditd-best-practice 中给出的示例,如果需要忽略 mysql,mongo 等命令工具,就需要将以下策略加到合适的位置(-a always,exit 规则之前):### ignore common tools -a never,exit -F arch=b64 -F exe=/usr/bin/redis-cli -a never,exit -F arch=b64 -F exe=/usr/bin/mysql -a never,exit -F arch=b64 -F exe=/usr/bin/mongo .... ## Kernel module loading and unloading -a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod -k modules ....never 和 always 所能支持的 -F 过滤字段不尽相同, 如果要按照 exe 忽略指定的工具路径, 只能通过 never 实现, exe 为执行工具的路径, 需要设置其绝对值, 这点没有 snoopy 的 exclude_comm 方便.eBPF 记录方式eBPF 在较新版本的 Linux 内核中实现,提供了动态追踪的机制,可以阅读之前的文章 Linux 系统动态追踪技术介绍了解更多动态追踪相关的知识。bpftrace 和 bcc 是基于 eBPF 机制实现的工具,方便大家对系统的调试和排错,bcc 提供了很多工具集,从应用到内核,不同层面的工具应有尽有,比如 execsnoop 即可记录系统中所有的 execv,execve 相关的命令执行:# ./execsnoop PCOMM PID PPID RET ARGS bash 32647 32302 0 /bin/bash id 32649 32648 0 /usr/bin/id -un hostname 32651 32650 0 /usr/bin/hostname uptime 410 32744 0 /bin/uptime其它更细致的记录可以参考 bcc 工具说明。值得注意的是,eBPF 仅适用于 Linux 4.1+ 的版本,以 eBPF 开发的进度的来看,eBPF 在 kernel-4.10 之后的支持才相对全面,线上在使用的时候尽量选择较高内核版本的发行版(比如 Centos 8,Debian 10 等)。另外 Readhat/Centos 7 从 7.6(3.10.0-940.el7.x86_64)版本开始支持 eBPF 特性,不过内核版本较低,并没有支持所有的特性,其主要目的在于试用此技术:总结从上述介绍可以看到,审计系统的操作行为其实就是为了更方便的追溯和排查问题,审计所产生的日志记录本身也可以作为取证的材料。 一些对安全敏感的企业可以通过 auditd 方式来实现不同级别的审计标准。 在实际的使用中,我们建议通过 snoopy 或 auditd 来实现系统操作的审计需求,一些细致的记录追踪可以通过 eBPF 方式实现。 另外也可以将审计的日志发送到 ELK 等日志平台做一些策略方面的告警,不过在具体的实践中,我们需要做好详细的过滤规则避免产生大量重复且收效甚微的数据。
2023年08月30日
22 阅读
0 评论
0 点赞
1
...
4
5
6