|
引言
- 背景介绍:在服务器的运维管理中,及时监控系统的登录日志对保障系统的安全至关重要。通过实时监控登录日志,运维人员可以发现潜在的异常登录行为,防止系统被非法访问。
- 问题引入:如何实现实时监控登录日志,并及时响应潜在的安全风险?
实时监控登录日志的意义
- 安全性:通过监控登录日志,可以迅速发现恶意登录、暴力破解等异常行为。
- 合规性:确保满足各种合规要求,记录所有用户的登录行为。
解决方案概述
- 监控目标:关注登录日志中的关键信息,例如登录时间、IP 地址、用户名、登录方式等。
- 技术选型:通过编写 Bash 脚本,结合inotify、awk、grep 等工具,来实现对日志文件的实时监控与分析。
脚本实现原理
- 实时监控:利用 inotify 命令动态监控日志文件的变动,并结合 sed 命令实时提取和输出新增的登录日志。
- 日志筛选:通过 grep 等工具过滤出登录失败、异常登录等相关信息。
- 报警机制:脚本可以配置成在监控到异常行为时,自动发送通知邮件
脚本示例- 1 #!/bin/bash
- 2 # 作者: 阿杰
- 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 # 初始化Map
- 21 declare -A secureMap
- 22
- 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 mkdir conf
- 43 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_file
- 56 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_name
- 75 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_file
- 89 ;;
- 90 # 文件被删除或重新创建
- 91 CREATE|DELETE)
- 92 # 重置文件行数
- 93 line=0
- 94 > $line_file_name
- 95 check
- 96 ;;
- 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_name
- 108 # 不是指定数据退出
- 109 if [ $(sed -n "$line p" $file_name | grep 'pam_unix(sshd:auth): authentication failure;' | wc -l ) -ne 1 ];then
- 110 return
- 111 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 $oneSecureKey
- 126 }
- 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 $key
- 141 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_file
- 151 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_file
- 157 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_inode
- 170 }
- 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_file
- 181 inode_file_status=1
- 182 else
- 183 inode_file_status=0
- 184 fi
- 185 else
- 186 # 第一次读取
- 187 echo "$inode" > $inode_file
- 188 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 break
- 200 fi
- 201 read_line_file
- 202 done
- 203 wirte_all_secure
- 204 elif [ $line -ne $(wc -l < $file_name) ];then
- 205 # 使用循环将行数对齐
- 206 while true;do
- 207 if [ $line -eq $(wc -l < $file_name) ];then
- 208 break
- 209 fi
- 210 read_line_file
- 211 if [ $write_status -eq 0 ];then
- 212 write_one_secure $oneSecureKey
- 213 fi
- 214 # 状态设置为1
- 215 write_status=1
- 216 done
- 217 # else
- 218 # read_line_file
- 219 # if [ $write_status -eq 0 ];then
- 220 # write_one_secure $oneSecureKey
- 221 # fi
- 222 # # 状态设置为1
- 223 # write_status=1
- 224 fi
- 225 }
- 226
- 227 test_main() {
- 228 init
- 229 check_secure_file_inode
- 230
- 231 }
- 232
- 233 main() {
- 234 # 初始化
- 235 init
- 236 # 内容检查
- 237 check
- 238 start_read_file
- 239 log_info "[main] watch secure startd"
- 240 watch_file
- 241 }
- 242
- 243 main
复制代码
来源:https://www.cnblogs.com/chang157122/p/18574033
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|