Linux 日志实时告警实战:Nginx 5xx 与 SSH 暴力破解监控

舞姬之光

舞姬之光

2026-05-13

588人浏览

原创

linux 运维中,有常见的两类风险:

  • Nginx 出现持续 5xx,业务异常但无人感知
  • SSH 被持续暴力破解,安全风险不断累积

很多人第一反应是上 ELK、Prometheus,但对中小规模场景来说,这往往成本过高。

其实,只用系统自带工具(tail + awk + curl),就可以实现一套稳定、实时、低成本的日志告警方案。

但要注意:绝大多数“网上脚本”都存在严重问题,例如

  • pipeline 子 shell 导致计数失效
  • 伪“1分钟窗口”(实际只是定时清零)
  • grep 缓冲导致告警延迟
  • 日志轮转后监控中断

Linux 日志实时告警实战:Nginx 5xx 与 SSH 暴力破解监控 - php中文网

一、设计原则

这套方案遵循以下原则:

1. 单进程状态管理(避免 shell 坑)

所有统计逻辑在 awk 内完成,避免:

  • 子进程变量隔离
  • 状态不一致

2. 真正的滑动时间窗口

采用:

  • systime() + 事件清理机制
  • 而不是简单“每分钟清零”

实现“近似实时滑动窗口”。

3. 不依赖日志格式细节

只依赖:

  • $1 → IP
  • $9 → HTTP 状态码

避免 fragile 正则。

Go语言(Golang)Linux版
Go语言(Golang)Linux版

Go语言(Golang)Linux版适合在 Linux 环境中部署 Go 编译工具链,支持服务端开发、微服务、网络程序、容器化项目和自动化工具开发。

下载

4. 低依赖

仅依赖:

  • tail
  • awk
  • curl

5. 安全优先

  • 不使用 eval
  • 支持白名单
  • webhook 校验严格

二、终极生产脚本

保存为:

36/usr/local/bin/log-alert.sh1.
#!/bin/bash# ================= 配置项 =================NGINX_LOG="/var/log/nginx/access.log"SSH_MODE="file"# file 或 journaldSSH_LOG="/var/log/secure"WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"NGINX_THRESHOLD=10SSH_THRESHOLD=5SILENT=300STATE_DIR="/dev/shm/log_alert"mkdir -p "$STATE_DIR"chmod 700 "$STATE_DIR"WHITELIST=("127.0.0.1""10.0.0.0/8""192.168.0.0/16")# ================= 工具检查 =================for cmd in tail awk curl; docommand -v $cmd >/dev/null || { echo"缺少依赖: $cmd"; exit 1; }done

# ================= webhook 校验 =================resp=$(curl -s --max-time 5 "$WEBHOOK")echo"$resp" | grep -q '"errcode":0' || {echo"Webhook 无效或不可用"exit 1}# ================= 告警函数 =================send_alert() {local title="$1"local content="$2"

    curl -s -o /dev/null -X POST "$WEBHOOK" \    -H "Content-Type: application/json" \    -d "{
        \"msgtype\": \"text\",
        \"text\": {\"content\": \"${title}\n${content}\"}
    }" &}# ================= 白名单判断 =================is_white() {local ip="$1"

    [[ "$ip" == "127.0.0.1" ]] && return 0for w in"${WHITELIST[@]}"; do
        [[ "$ip" == "$w" ]] && return 0donereturn 1}# ================= NGINX 监控 =================tail -F "$NGINX_LOG" | awk -v t="$NGINX_THRESHOLD" -v s="$SILENT"'{
    ip=$1
    code=$9
    now=systime()

    if (code !~ /^5[0-9][0-9]$/) next

    key=ip
    events[key][++cnt[key]]=now

    # 清理旧数据    for (i in events[key]) {
        if (now - events[key][i] > 60) delete events[key][i]
    }

    n=0
    for (i in events[key]) n++

    if (n >= t && now - last[key] > s) {
        last[key]=now
        print "NGINX|"ip"|"n        fflush()
    }}' | while IFS='|'read -r type ip count; do

    is_white "$ip" && continue

    send_alert "Nginx 5xx告警""IP: $ip\n1分钟: $count 次"done  ================= SSH 监控 =================if [[ "$SSH_MODE" == "journald" ]]; then    SRC="journalctl -f _COMM=sshd"else
    SRC="tail -F $SSH_LOG"fi

bash -c "$SRC" | grep "Failed password" | awk -v t="$SSH_THRESHOLD" -v s="$SILENT"'{
    for(i=1;i 60) delete events[key][i]
    }

    n=0
    for(i in events[key]) n++

    if(n >= t && now - last[key] > s){
        last[key]=now
        print "SSH|"ip"|"n        fflush()
    }}' | while IFS='|'read -r type ip count; do

    is_white "$ip" && continue

    send_alert "SSH暴力破解告警""IP: $ip\n失败次数: $count"done &wait -n
exit 11.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.102.103.104.105.106.107.108.109.110.111.112.113.114.115.116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.

三、systemd

[Unit]Description=Log Alert Service
After=network.target[Service]ExecStart=/bin/bash /usr/local/bin/log-alert.sh
Restart=always
RestartSec=3StandardOutput=journal
StandardError=journal

NoNewPrivileges=yes
ProtectSystem=full[Install]WantedBy=multi-user.target1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.

四、必须知道的几个关键点

1. 这是“近似滑动窗口”

不是精确时间序列系统,但对运维告警完全够用。

2. /dev/shm 是内存

重启后状态会丢失(正常)。

3. 默认只支持简单白名单

CIDR 未做完整实现(避免复杂度)。

4. 日志格式必须标准

否则需要改 $1 $9。

相关专题

更多
nginx 重启
nginx 重启

nginx重启对于网站的运维来说是非常重要的,根据不同的需求,可以选择简单重启、平滑重启或定时重启等方式。本专题为大家提供nginx重启的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.27

339

5

nginx 配置详解
nginx 配置详解

Nginx的配置是指设置和调整Nginx服务器的行为和功能的过程。通过配置文件,可以定义虚拟主机、HTTP请求处理、反向代理、缓存和负载均衡等功能。Nginx的配置语法简洁而强大,允许管理员根据自己的需要进行灵活的调整。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

1703

6

nginx配置详解
nginx配置详解

NGINX与其他服务类似,因为它具有以特定格式编写的基于文本的配置文件。本专题为大家提供nginx配置相关的文章,大家可以免费学习。

2023.08.04

2101

6

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

415

5

nginx报404怎么解决
nginx报404怎么解决

当访问 nginx 网页服务器时遇到 404 错误,表明服务器无法找到请求资源,可以通过以下步骤解决:1. 检查文件是否存在且路径正确;2. 检查文件权限并更改为 644 或 755;3. 检查 nginx 配置,确保根目录设置正确、没有冲突配置等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.07.09

1239

5

Nginx报404错误解决方法
Nginx报404错误解决方法

解决方法:只需要加上这段配置:try_files $uri $uri/ /index.html;即可。想了解更多Nginx的相关内容,可以阅读本专题下面的文章。

2024.08.07

3807

3

nginx部署php项目教程汇总
nginx部署php项目教程汇总

本专题整合了nginx部署php项目教程汇总,阅读专题下面的文章了解更多详细内容。

2026.01.13

102

12

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

2026.01.13

272

23

Nginx跨平台安装实操指南:Windows、macOS与Linux环境快速搭建
Nginx跨平台安装实操指南:Windows、macOS与Linux环境快速搭建

本指南详解Nginx在Windows、macOS及Linux系统的安装全流程。涵盖官方包解压、Homebrew一键部署、APT/YUM源配置及Docker容器化方案。无论新手或开发者,均可快速搭建运行环境,掌握跨平台核心指令,为后续配置与调优奠定坚实基础。

2026.03.16

107

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpMyAdmin 安装文档
phpMyAdmin 安装文档

共0课时 | 0人学习

Apifox下载与安装手册
Apifox下载与安装手册

共0课时 | 0人学习

安装 Xdebug 并配置 phpstorm
安装 Xdebug 并配置 phpstorm

共1课时 | 127人学习