引言
  • 背景介绍:在服务器的运维管理中,及时监控系统的登录日志对保障系统的安全至关重要。通过实时监控登录日志,运维人员可以发现潜在的异常登录行为,防止系统被非法访问。
  • 问题引入:如何实现实时监控登录日志,并及时响应潜在的安全风险?
实时监控登录日志的意义
  • 安全性
    :通过监控登录日志,可以迅速发现恶意登录、暴力破解等异常行为。
  • 合规性
    :确保满足各种合规要求,记录所有用户的登录行为。
解决方案概述
  • 监控目标
    :关注登录日志中的关键信息,例如登录时间、IP 地址、用户名、登录方式等。
  • 技术选型
    :通过编写 Bash 脚本,结合
    inotify

    awk

    grep
    等工具,来实现对日志文件的实时监控与分析。
脚本实现原理
  • 实时监控
    :利用
    inotify
    命令动态监控日志文件的变动,并结合
    sed
    命令实时提取和输出新增的登录日志。
  • 日志筛选
    :通过
    grep
    等工具过滤出登录失败、异常登录等相关信息。
  • 报警机制
    :脚本可以配置成在监控到异常行为时,自动发送通知邮件

脚本示例

1 #!/bin/bash2 # 作者: 阿杰3 # 用途: 实时检测登录日志,统计异常登录4 # 脚本名称: watch_secure.sh
5 # 用法: bash watch_seacure.sh
6 
7 # 日志记录8 log_err() {9   printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[31mERROR: \033[0m$@\n"
10 }11 
12 log_info() {13   printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[32mINFO: \033[0m$@\n"
14 }15 
16 log_warning() {17   printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[33mWARNING: \033[0m$@\n"
18 }19 
20 # 初始化Map21 declare -A secureMap22 
23 init() {24 # 行数记录文件25     line_file_name="conf/line_file.txt"    
26 # inode存储文件27     inode_file="conf/inode.txt"
28 # 认证失败文件记录29     ssh_auth_failed_file="conf/ssh_auth_failed.csv"
30 
31 # 文件列表32     file_array=("$line_file_name" "$inode_file" "$ssh_auth_failed_file")33 # inode 文件状态34     inode_file_status=0
35 # 控制是否进行写入 0为可写,1为不可写36     write_status=1
37 
38     oneSecureKey=""
39 
40 {41         if [ ! -d "conf" ];then
42             mkdirconf43         fi
44 # 检查文件是否存在45         for file in ${file_array[@]};do
46             check_file_exists $file
47         done
48         line=$(cat$line_file_name)49         if [ -z "$line" ];then
50             line=0
51         fi
52 # 认证失败文件第一次创建53         if [ $(wc -l < $ssh_auth_failed_file) -eq 0 ];then
54 # 时间以月天为单位(None为空账号或不存在账号)55             echo "登录认证失败时间,源IP地址,登录账号,连接认证失败次数" >$ssh_auth_failed_file56         fi
57 
58 }59 
60     file_name="/var/log/secure"
61     if [ -z "$(rpm -qa | grep 'inotify-tools')" ];then
62         yum install -y inotify-tools > /dev/null 2>&1
63         if [ $? -ne 0 ];then
64             log_err "[init] inotify-tools 安装失败!"
65         fi
66     fi
67 
68 
69 }70 # 检查文件是否存在,不存在则创建71 check_file_exists() {72     local file_name=$1
73     if [ ! -f "$file_name" ];then
74         touch$file_name75         if [ $? -ne 0 ];then
76             log_err "[check_file_exists] file: $file_name 文件创建失败!"
77         fi
78     fi
79 }80 
81 
82 
83 # 监听文件事件84 watch_file() {85     inotifywait -mrq --format '%e' --event create,delete,modify $file_name | while read event ;do
86         case "$event" in
87 MODIFY)88 start_read_file89 ;;90 # 文件被删除或重新创建91         CREATE|DELETE)92 # 重置文件行数93             line=0
94             >$line_file_name95 check96 ;;97         *)98             log_warning "[watch_file] watch file event: $event" 
99 ;;100         esac
101     done
102 }103 
104 # 只读一行105 read_line_file() {106     ((line++))107     echo $line >$line_file_name108 # 不是指定数据退出109     if [ $(sed -n "$line p" $file_name  | grep 'pam_unix(sshd:auth): authentication failure;' | wc -l ) -ne 1 ];then
110 return111     fi
112 # 控制是否进行写入113     write_status=0
114     oneSecureKey=$(sed -n "$line p" $file_name  |awk -v dateNow=$(date +"%Y") '{
115         split($0,rhost,"rhost=")116         split(rhost[2],rhost," ")117         split($0,user,"user=")118         if (length(user[2])==0) {119             user[2]="None"
120 }121         print dateNow":"$1":"$2","rhost[1]","user[2]122     }')
123     log_info "[read_line_file] line: $line data:[$oneSecureKey]"
124     
125 send_map $oneSecureKey126 }127 
128 # 往MAP中塞入数据129 send_map() {130     local key=$1
131     if [ -n ${secureMap[$key]} ];then
132         secureMap[$key]=`expr ${secureMap[$key]} + 1`133     else
134         secureMap[$key]=1
135     fi
136 }137 
138 wirte_all_secure() {139     for key in ${!secureMap[@]};do
140 write_one_secure $key141     done
142 }143 
144 write_one_secure() {145     local key="$@"
146     local data=$(grep -w -n "$key"$ssh_auth_failed_file)147     if [ -n "$data" ];then
148         local i=$(echo $data | awk -F: '{print $1}')149         local a=$(echo $data | awk -F, '{print $NF}')150         sed -i "${i} s#$a#${secureMap[$key]}#"$ssh_auth_failed_file151         if [ $? -ne 0 ];then
152             log_err "[write_secure] 写 $ssh_auth_failed_file 文件失败! data:[$key,${secureMap[$key]}]"
153         fi
154     else
155 # 新数据156         echo "$key,${secureMap[$key]}" >>$ssh_auth_failed_file157         if [ $? -ne 0 ];then
158             log_err "[write_secure] 写 $ssh_auth_failed_file 文件失败! data:[$key,${secureMap[$key]}]"
159         fi
160     fi
161     log_info "[write_secure] line: $line status: $write_status data:[$key,${secureMap[$key]}]"
162 }163 
164 
165 
166 # 启动前应先检查是否读取过167 check() {168 # 检查预存Inode是否一致169 check_secure_file_inode170 }171 
172 # 检查登录日志Inode是否一致173 check_secure_file_inode() {174     inode=$(ls -i $file_name | awk '{print $1}')175     inode_file_data="$(cat $inode_file)"
176     if [ -n "$inode_file_data" ]; then
177         if [ $inode -ne $inode_file_data ];then
178             log_warning "[check_secure_file_inode] secure file inode is inconsistency"
179 # inode不一致,重置180             echo "$inode" >$inode_file181             inode_file_status=1
182         else
183            inode_file_status=0
184         fi
185     else
186 # 第一次读取187         echo "$inode" >$inode_file188         inode_file_status=1
189     fi
190 }191 
192 # 开始读取文件193 start_read_file() {194 # 第一次读取195     if [ $inode_file_status -eq 1 ] ;then
196 # 使用循环将历史内容读取197         while true;do
198             if [ $line -eq $(wc -l < $file_name) ];then
199 break200             fi
201 read_line_file202         done
203 wirte_all_secure204     elif [  $line -ne $(wc -l < $file_name) ];then
205 # 使用循环将行数对齐206         while true;do
207             if [ $line -eq $(wc -l < $file_name) ];then
208 break209             fi
210 read_line_file211             if [ $write_status -eq 0 ];then
212 write_one_secure $oneSecureKey213             fi
214 # 状态设置为1215             write_status=1
216         done        
217     # else
218 #     read_line_file219     #     if [ $write_status -eq 0 ];then
220 #         write_one_secure $oneSecureKey221     #     fi
222 #     # 状态设置为1223     #     write_status=1
224     fi
225 }226 
227 test_main() {228 init229 check_secure_file_inode230 
231 }232 
233 main() {234 # 初始化235 init236 # 内容检查237 check238 start_read_file239     log_info "[main] watch secure startd"
240 watch_file241 }242 
243 main

标签: none

添加新评论