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 级日志全量扫会拖垮服务器。

相关推荐
2401_868534781 分钟前
软考网络规划设计师SSL协议知识点详解
服务器·网络
额额额对了3 小时前
嵌入式 Linux 实战:i.MX6ULL 上的 CAN 通信与摄像头采集
linux·运维·服务器
灯澜忆梦4 小时前
【Linux】#10 | Linux 终端实用快捷键 + 安装应用
linux·运维·服务器
码士集团小青5 小时前
面霸篇:高频 Java 基础问题(核心卷一)
linux·服务器·数据库·redis·缓存·1024程序员节
2601_967212726 小时前
高防护轨道式插座安全结构与工程适配技术说明
大数据·经验分享·安全
OnlyEasyCode6 小时前
IIS开放端口转发后端
运维·服务器
treesforest6 小时前
游戏账号安全风险分层方案:IP信号分层与人机复核实践
tcp/ip·安全·游戏·1024程序员节
救救孩子把7 小时前
RAG 还是 Fine-Tuning?从语义切分、QLoRA 到安全防护的企业级 LLM 优化实战
安全·llm·rag·fine-tuning·qlora
每天题库7 小时前
汽车维修工等级考试题库 理论实操核心考点一次梳理清
学习·安全·考试·题库·考证