上午写了一个帖子,发错地方了,正好发先原脚本没有配置check进程,打个补丁顺便再发一个。
两个脚本都要给执行权限。
守护进程-crontab
#!/bin/bash
# 要检查的脚本路径
SCRIPT_PATH="/home/admin/login_monitor/login_monitor.sh"
LOG_PATH="/home/admin/login_monitor/login_monitor.log"
# 判断进程是否存在
if ! pgrep -f "$SCRIPT_PATH" > /dev/null 2>&1; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - login_monitor.sh not running, starting..." >> "$LOG_PATH"
nohup "$SCRIPT_PATH" >> "$LOG_PATH" 2>&1 &
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - login_monitor.sh is running" >> "$LOG_PATH"
fi
主进程
#!/bin/bash
# --- 用户配置区 (请根据你的实际情况修改) ---
# 1. 你的 Nginx 访问日志文件完整路径
NGINX_LOG_FILE="/usr/trim/nginx/logs/access.log"
# 2. 【新】在这里定义所有你关心的日志特征(每行一个)
# 只要日志中出现下面列表中的任意一条,就会触发通知。
LOGIN_PATTERNS=(
# --- 在下面添加或修改你的特征 ---
"/static/app/icons/trim.download-center/icon.png"
"POST /v1/accountapi/check"
# --- 到此为止 ---
)
# 3. 你真实的飞书机器人 Webhook 地址!!!!!!
FEISHU_WEBHOOK_URL="飞书机器人 Webhook 地址"
# --- 脚本核心逻辑 (一般无需修改) ---
# 定义一个带时间戳的日志输出函数
log_with_time() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1"
}
# 【新】将数组格式的特征列表,合并成一个用 "|" 分隔的字符串,以供 grep 使用
# 例如,将 ("a" "b" "c") 变为 "a|b|c"
IFS='|'
GREP_PATTERN="${LOGIN_PATTERNS[*]}"
IFS=$' \t\n' # 恢复默认的 IFS
# 检查模式列表是否为空
if [ -z "${GREP_PATTERN}" ]; then
log_with_time "错误:监控的日志特征列表 (LOGIN_PATTERNS) 为空,请至少添加一个特征。"
exit 1
fi
log_with_time "开始监控日志文件: ${NGINX_LOG_FILE}"
log_with_time "正在查找以下任一特征: ${GREP_PATTERN}"
# 使用 tail -F 实时监控日志文件的新增内容
# -F 参数可以应对日志文件的轮转 (log rotation)
tail -n 0 -F "${NGINX_LOG_FILE}" | while read -r line; do
# 检查当前行是否包含我们定义的“登录成功”特征
if echo "${line}" | grep -qE "${GREP_PATTERN}"; then
# 从日志行中提取 IP 地址 (默认是第一个字段)
IP_ADDRESS=$(echo "${line}" | awk '{print $1}')
# 获取当前时间
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
# 准备要发送到飞书的消息内容
MESSAGE_TEXT="【登录提醒🔔】\n\n- 时间: ${TIMESTAMP}\n- 登录IP: ${IP_ADDRESS}"
log_with_time "检测到登录行为,来源 IP: ${IP_ADDRESS}。正在发送飞书通知..."
# 使用 curl 命令将消息发送到飞书
curl -s -X POST -H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"'"${MESSAGE_TEXT}"'"}}' \
"${FEISHU_WEBHOOK_URL}" > /dev/null
# 在终端输出一个换行,方便查看
echo ""
fi
done