Linux服务器快速排查有问题的ip请求

一页速查版(实战直接照抄)

复制代码
# ===== 1. 连接层初筛 =====
ss -nt | awk 'NR>1 {print $5}' | sed 's/\[//;s/\]//' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -rn | head -20
ss -nt | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# ===== 2. 找日志 =====
nginx -T 2>/dev/null | grep -i access_log
ls -l --time-style=full-iso /www/wwwlogs/*.log

# ===== 3. 日志 top IP(兼容 IPv4/IPv6)=====
tail -100000 /www/wwwlogs/xxx.access.log \
  | grep -oE '([0-9]{1,3}(\.[0-9]{1,3}){3}|[0-9a-fA-F:]{6,})"?$' \
  | tr -d '"' | sort | uniq -c | sort -rn | head -20

# ===== 4. 确认行为 =====
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $9}' | sort | uniq -c | sort -rn
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $4}' | cut -d: -f1-3 | sort | uniq -c | sort -rn | head

# ===== 5. 处置 =====
# Nginx: deny <IP>;
# iptables -I INPUT -s <IP> -j DROP

总流程概览

复制代码
报警 → 判断攻击类型 → 连接层初筛 → 日志层定位 → 确认行为 → 封禁/限流
         │                │              │
         │                │              └─ 不知道哪个日志 → 先定位日志文件
         │                └─ 日志为空/太大 → 用 ss/conntrack 兜底
         └─ CPU/带宽/连接数/磁盘 哪个先爆

第 0 步:先搞清楚"报警是什么"

不同报警查法不同:

报警内容 重点查
CPU 打满 慢请求、CC、PHP 进程
带宽打满 大文件、DDoS、盗链
连接数暴涨 CC、SYN Flood
磁盘写满 日志暴涨(本身就是攻击信号)
502/504 增多 PHP-FPM 打满、后端被压
后台被扫 403/404 暴涨

先看是什么报警,决定往哪个方向查。


第 1 步:连接层初筛(不依赖日志,最快)

不管你知不知道日志在哪,这一步都能做。

1.1 当前连接数最多的 IP

复制代码
ss -nt | awk 'NR>1 {print $5}' \
  | sed 's/\[//;s/\]//' | sed 's/:[0-9]*$//' \
  | sort | uniq -c | sort -rn | head -20

判断

  • 某个 IP 几百上千 → 高度可疑

  • 全是 172.68.x/104.x 等 CF 段 → 流量走 CDN,真实 IP 在日志 XFF 里

1.2 连接状态分布

复制代码
ss -nt | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

判断

  • ESTAB 正常

  • 大量 SYN-RECV → SYN Flood

  • 大量 TIME-WAIT → 短连接高频请求(CC 特征)

1.3 按端口看连接

复制代码
ss -nt | awk 'NR>1 {print $4}' | sed 's/.*://' | sort | uniq -c | sort -rn | head

判断:哪个端口连接最多,就是被攻击的服务(80/443/3306...)。

1.4 实时看新连接

复制代码
watch -n 1 "ss -nt | awk 'NR>1 {print \$5}' | sed 's/\[//;s/\]//' | sed 's/:[0-9]*\$//' | sort | uniq -c | sort -rn | head -10"

第 2 步:定位日志文件(不知道日志在哪时)

2.1 找 nginx 实际配的日志

复制代码
nginx -T 2>/dev/null | grep -i access_log

注意

  • access_log /dev/null; = 该站点日志被关

  • 路径可能不是 /var/log/nginx/,宝塔常在 /www/wwwlogs/

2.2 看哪些日志在实时写入

复制代码
ls -l --time-style=full-iso /www/wwwlogs/*.log

时间戳在更新的就是活跃日志。

2.3 看 nginx 进程打开了哪些日志

复制代码
lsof -p $(pgrep -d, nginx) 2>/dev/null | grep '\.log'

2.4 确认日志格式(关键,决定怎么切字段)

复制代码
head -1 /www/wwwlogs/xxx.access.log | cat -A

要确认三件事

  1. 第 1 列是不是真实 IP?

  2. 最后一列是不是 XFF?是 IPv4 还是 IPv6?

  3. 有没有被 CF/代理覆盖?


第 3 步:日志层定位 top IP

3.1 通用取真实 IP(兼容 IPv4/IPv6)

复制代码
tail -100000 /www/wwwlogs/xxx.access.log \
  | grep -oE '([0-9]{1,3}(\.[0-9]{1,3}){3}|[0-9a-fA-F:]{6,})"?$' \
  | tr -d '"' \
  | sort | uniq -c | sort -rn | head -20

为什么不直接 awk '{print $1}'

  • 有 CF 时 $1 是 CF 回源 IP,不是真实用户

  • 有 IPv6 时正则要兼容

  • 最后一段可能是空,$NF 会取错

3.2 如果知道第 1 列就是真实 IP

复制代码
tail -100000 /www/wwwlogs/xxx.access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

3.4 文件太大(GB 级)怎么办

不要直接 cat 全量,按顺序:

复制代码
# 先看最近 10 万行
tail -100000 xxx.log | ...

# 再按时间段
awk -v d="$(date '+%d/%b/%Y:%H')" '$0 ~ d' xxx.log | ...

# 最后才考虑全量

3.5 多个站点一起查

复制代码
for f in /www/wwwlogs/*.access.log; do
  echo "===== $f ====="
  tail -50000 "$f" 2>/dev/null \
    | grep -oE '([0-9]{1,3}(\.[0-9]{1,3}){3}|[0-9a-fA-F:]{6,})"?$' \
    | tr -d '"' | sort | uniq -c | sort -rn | head -10
done

第 4 步:确认可疑 IP 的行为(是不是攻击)

找到 top IP 后,不要急着封,先确认。

4.1 它请求了什么

复制代码
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

判断

  • 集中 /admin//login/api/ → 爆破/扫描

  • 集中同一个 URL → CC

  • 随机路径 → 目录扫描

4.2 状态码分布

复制代码
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $9}' | sort | uniq -c | sort -rn

判断

  • 大量 403/404 → 扫描被挡

  • 大量 200 → 可能已突破或正常业务

  • 大量 499/502 → 压后端

4.3 请求频率

复制代码
grep '<IP>' /www/wwwlogs/xxx.access.log | awk '{print $4}' | cut -d: -f1-3 | sort | uniq -c | sort -rn | head

判断:1 秒内多次、持续几分钟 → 脚本行为。

4.4 UA / Referer

复制代码
grep '<IP>' /www/wwwlogs/xxx.access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn | head
grep '<IP>' /www/wwwlogs/xxx.access.log | awk -F'"' '{print $4}' | sort | uniq -c | sort -rn | head

判断

  • Referer 空、UA 伪装/多变 → 可疑

  • UA 是 curl/python/scanner → 工具

4.5 综合判断表

特征 结论
高频 + /admin/ + 403 后台爆破/扫描
高频 + 同一 URL + 200 CC 攻击
高频 + 随机路径 + 404 目录扫描
多 IP 各来一点 DDoS
大量 SYN-RECV SYN Flood
单 IP 大量连接 CC/爬虫

第 5 步:其他辅助维度

5.1 PHP-FPM 日志(默认不记 IP)

复制代码
grep -r 'access.log' /etc/php-fpm.d/ /etc/php/*/fpm/pool.d/ 2>/dev/null

默认注释掉,开了才有。

5.2 应用日志

复制代码
grep '<IP>' /path/to/app/storage/logs/*.log

第 6 步:处置

6.1 确认是攻击后封禁

Nginx 层(推荐,精准):

复制代码
deny 103.252.19.100;

iptables(直连 IP 有效):

复制代码
iptables -I INPUT -s 103.252.19.120 -j DROP

6.2 限流(防未来)

复制代码
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_req zone=req_limit burst=20 nodelay;

6.3 封段(谨慎)

复制代码
iptables -I INPUT -s 103.252.19.0/24 -j DROP

核心原则

  1. 先连接层,再日志层------连接层不依赖日志,最快。

  2. 先定位日志文件,再统计------不要假设路径和格式。

  3. 先确认行为,再封禁------避免误封自己人/CDN。

  4. 注意 IPv4/IPv6 和 CF 回源 ------$1 不一定是真实 IP。

  5. 文件大先用 tail------GB 级日志全量扫会拖垮服务器。

相关推荐
开开心心就好1 小时前
低年级识字练笔顺工具,电脑和安卓端都能用
前端·javascript·网络·安全·scala·erlang·语音识别
xiaoqiMikko2 小时前
jackson-databind 又出 4 条,Dependabot 一条都不报:2.21.5 还差 3 条
java·安全
xiaoqiMikko2 小时前
Central 上的 Spring 5.3.41 不是官方发的:逐字节比对,官方修两条它少一条
java·安全
captain3762 小时前
网络原理(4)-TCP ▲▲▲
java·服务器·网络·网络协议·tcp/ip
溪语流沙2 小时前
【Python项目实战】部署上线:把博客发布到云服务器
服务器·开发语言·python
渡我白衣2 小时前
Util工具类功能设计与类设计
linux·服务器·网络·c++·人工智能·目标检测·机器学习
土星云SaturnCloud2 小时前
ResNet-50 图像分类算法在边缘微服务器上的部署与性能评测
服务器·人工智能·算法·边缘计算·resnet-50
workflower2 小时前
AI 转型正从工具部署转向生产关系重构
人工智能·安全·机器学习·机器人·无人机