前言

最近基于钉钉群机器人编写了一个Linux服务器登录通知脚本,主要通过bash脚本实时采集服务器基础信息、监控用户登录行为,在发生异常登录或暴力破解时立即向管理员推送告警通知,有效解决了传统防护方案中响应滞后、溯源困难、缺乏可视化报表等问题,为服务器安全提供了即时可靠的防护屏障。

脚本亮点

  • ✅ 实时推送登录信息到钉钉群组
  • ✅ 智能识别SSH/本地登录方式
  • ✅ 显示登录者IP地理位置
  • ✅ 支持Root用户操作预警
  • ✅ 自动获取服务器基础信息
  • ✅ 北京时间双重时间显示

快速食用

1. 前置准备

  • 准备Linux服务器(Debian/Ubuntu/Centos等系统,需要支持python3)
  • 下载钉钉,创建钉钉群组

2. 钉钉机器人配置

  1. 电脑端钉钉群组 > 设置 > 智能群助手
  2. 添加机器人 > 自定义服务
  3. 设置安全策略 > 选"关键词" > 添加"通知"关键字
  4. 记录Webhook地址中的access_token参数

3. 脚本安装步骤

  1. 打开/etc/profile.d文件夹,并创建/编写脚本文件

    # 进入/etc/profile.d
    cd /etc/profile.d/
    
    # 创建并打开dingtalk-login-alert.sh
    vi dingtalk-login-alert.sh
  2. 把下面代码复制 > 粘贴到dingtalk-login-alert.sh文件,在钉钉自定义机器人中,复制“Webhook”链接access_token=后缀内容,填写到代码的ACCESS_TOKEN中。

    #!/bin/bash
    #------------------------
    # @Author: 星语(G.E.N.G)
    # @Date: 2025-4-26 23:07:43
    # @Description: Linux登录提醒 - 钉钉机器人提醒
    # @Msg: 把这个脚本添加到/etc/profile.d中,即可实现登录提醒
    #------------------------
    
    # 钉钉机器人设置
    ## 1、【必填】电脑端钉钉群里添加自定义机器人获取,“Webhook”链接后缀
    ACCESS_TOKEN='YOU_ACCESS_TOKEN'
    
    ## 2、【必填】从钉钉机器人设置中获取,定义关键词
    CUSTOM_TEXT='服务器登录提醒'
    
    # 获取服务器基础信息
    USER=$(whoami)                                            # 用户
    HOSTNAME=$(hostname)                                      # 主机名
    OS=$(source /etc/os-release && echo "${NAME} ${VERSION}") # 系统
    DATE=$(date "+%Y-%m-%d %H:%M:%S")                         # 时间
    UPTIME=$(uptime -p | sed 's/up //')                       # 运行时间
    TIMEZONE=$(cat /etc/timezone)                             # 时区
    BJ_TIME=$(TZ='Asia/Shanghai' date +"%Y-%m-%d %H:%M:%S")   # 北京时间
    
    # 检测是否root登录
    [ "$(id -u)" -eq 0 ] && IS_ROOT="是(⚠️危险操作)" || IS_ROOT="否"
    
    # 登录类型检测
    if [ -n "$SSH_CONNECTION" ]; then
      LOGIN_TYPE="SSH(远程)"
      LOGIN_IP=$(echo "$SSH_CONNECTION" | awk '{print $1}')
      CLIENT_PORT=$(echo "$SSH_CONNECTION" | awk '{print $2}')
    elif [[ $(tty) =~ /dev/tty[0-9]+ ]]; then
      LOGIN_TYPE="本地控制台(tty)"
    elif [[ $(tty) =~ /dev/pts/[0-9]+ ]]; then
      LOGIN_TYPE="图形终端或本地伪终端(pts)"
    else
      LOGIN_TYPE="未知"
    fi
    
    # 获取IP地理位置信息(使用超时防止卡住)
    if [ -n "$LOGIN_IP" ] && command -v python3 &>/dev/null; then
      GEO_INFO=$(timeout 10s curl -s https://v2.xxapi.cn/api/ip?ip=${LOGIN_IP} | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['address'])")
      if [ $? -ne 0 ]; then
     GEO_INFO="地理位置查询超时"
      fi
    fi
    
    # 构造JSON消息
    MESSAGE=$(
      cat <<EOF
    {
      "msgtype": "markdown",
      "markdown": {
     "title": "⚠️ ${CUSTOM_TEXT}",
     "text": "## ⚠️ ${CUSTOM_TEXT}\n
     ▌基础信息\n
     ◆ 用户:\`${USER:-未知}\`(Root用户:${IS_ROOT})\n
     ◆ 主机:\`${HOSTNAME}\`\n
     ◆ 系统:${OS}\n
     ◆ 时区:${TIMEZONE}\n
     ◆ 运行时间:${UPTIME}\n
     ◆ 当前时间:${DATE}\n\n
     ▌登录信息\n
     ● 用户:\`${USER:-未知}\`\n
     ● 方式:${LOGIN_TYPE:-未知}\n
     ● 客户端IP:\`${LOGIN_IP:-未知}\`(端口:${CLIENT_PORT:-N/A})\n
     ● 地理位置:${GEO_INFO:-未知}\n
     ● 登录时间:${BJ_TIME}\n\n
     ▌温馨提醒\n
     ▶ 当前有用户登录,请核实是否为本人操作!\n
     ▶ 请注意登录安全,不要泄露密码!"
      }
    }
    EOF
    )
    
    # 发送到钉钉
    curl -s "https://oapi.dingtalk.com/robot/send?access_token=${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d "$MESSAGE" >/dev/null 2>&1

通知预览

Linux服务器登录钉钉机器人通知