运维脚本: 实时监测登录

  • 运维脚本: 实时监测登录已关闭评论
  • 18 次浏览
  • A+
所属分类:.NET技术
摘要

脚本示例  

引言
  • 背景介绍:在服务器的运维管理中,及时监控系统的登录日志对保障系统的安全至关重要。通过实时监控登录日志,运维人员可以发现潜在的异常登录行为,防止系统被非法访问。
  • 问题引入:如何实现实时监控登录日志,并及时响应潜在的安全风险?
实时监控登录日志的意义
  • 安全性:通过监控登录日志,可以迅速发现恶意登录、暴力破解等异常行为。
  • 合规性:确保满足各种合规要求,记录所有用户的登录行为。
解决方案概述
  • 监控目标:关注登录日志中的关键信息,例如登录时间、IP 地址、用户名、登录方式等。
  • 技术选型:通过编写 Bash 脚本,结合inotifyawkgrep 等工具,来实现对日志文件的实时监控与分析。
脚本实现原理
  • 实时监控:利用 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')]: 33[31mERROR: 33[0m$@n"  10 }  11   12 log_info() {  13   printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: 33[32mINFO: 33[0m$@n"  14 }  15   16 log_warning() {  17   printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: 33[33mWARNING: 33[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