인셔셔RSS 관심 있는 블로그, 뉴스, 기술 정보를 효율적으로 추적하고 읽으세요
원문 읽기 InertiaRSS에서 열기

추천 피드

V
V2EX
博客园 - 叶小钗
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
WordPress大学
WordPress大学
Blog — PlanetScale
Blog — PlanetScale
博客园 - Franky
G
Google Developers Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
V
Visual Studio Blog
M
MIT News - Artificial intelligence
Hugging Face - Blog
Hugging Face - Blog

蛋蛋之家

SUMIFS和LET函数——让 Excel 自己动起来 我用这个开源项目,把 AI 绘画提示词变成了"代码"——awesome-gpt-image-2 深度体验报告 群晖部署 LX Music Server:浏览器就是你的音乐播放器【详细版】 500道Word题库太痛苦?于是我写了个智能学习平台 别用一个人的奔跑,耗尽两个人的余生——《你凭什么认为我会一直喜欢你呢》 博客评论自动填充新方案:兼容 Vue/React 响应式绑定与跨架构填充逻辑 2026 生产级指南:Halo 2.x + PostgreSQL 自动化部署与性能优化手册 - 蛋蛋之家 从 Typecho 转向 Halo 2.x:全能型 Nginx 架构与 SEO 无损迁移指南 - 蛋蛋之家 Typecho 迁移 Halo 完整教程:数据库视图解决表前缀 + 自动提取封面图 + 去重检测 - 蛋蛋之家 我的 CodeBuddy 装备库:218个技能全公开 + 使用心得 - 蛋蛋之家 为博客添加自定义评论表情 - 蛋蛋之家 - 一枚蛋蛋的自留地 Comment2Bark:Typecho评论推送到Bark插件 又拍云插件 UpyunFile v1.2 更新:修复 Typecho 1.3.0 兼容性问题 - 蛋蛋之家 手把手修复RSS 403:从PHP警告到Cloudflare拦截的全链路排查 - 蛋蛋之家 - 一枚蛋蛋的自留地 网站被镜像怎么办?2026年反镜像攻防实战指南 - 蛋蛋之家 - 一枚蛋蛋的自留地 VLESS + Reality + Vision:2026 极致隐蔽节点搭建全解析 - 蛋蛋之家 给OpenList和Alist加上液态玻璃效果,颜值直接拉满! - 蛋蛋之家 - 一枚蛋蛋的自留地 网页截图瞬间“赛博飞升”?手把手教你根治 Windows HDR 截图发白 - 蛋蛋之家 群晖 NAS 影音终极方案:Docker Rclone + OpenList 完美挂载 Plex 全攻略 一个简洁高效的SVG图标库 - 蛋蛋之家 - 一枚蛋蛋的自留地 告别重复劳动!一键填充评论的神奇书签脚本 - 蛋蛋之家 - 一枚蛋蛋的自留地 解锁思源笔记的隐藏力量:siyuan-patch 深度体验与技术实现 - 蛋蛋之家 - 一枚蛋蛋的自留地 Oracle Cloud 自救指南:旧手机丢失后如何绕过 MFA 重新登录【更新2026年最新政策】 - 蛋蛋之家 本站已加入“萌国ICP备案”联萌!😄 - 蛋蛋之家 - 一枚蛋蛋的自留地 Excel 月报自动化指南:告别重复劳动,让数据主动为你服务 - 蛋蛋之家 - 一枚蛋蛋的自留地 梦呓:为异地女友准备的2周年惊喜礼物 - 蛋蛋之家 - 一枚蛋蛋的自留地 Typecho 多吉云插件优化:更灵活的存储目录配置 - 蛋蛋之家 - 一枚蛋蛋的自留地 甲骨文云硬盘扩容指南:从50G到200G的“免费午餐”怎么吃? ⏰ 时间同步:当你的服务器开始“穿越”时,如何优雅地把它拉回现实 Typecho 又拍云文件管理插件修改版使用指南:新增自定义目录结构功能 华为鸿蒙6.0回退4.2记录 最近小公主情绪不佳 劳动节的家乡景色 烟台山公园一游 群晖搭建ChatGPT Web 推荐脚本:ChatGPT - 提示选择器 Activation Method for JetBrains Products (English version) JetBrains 系列产品激活方法 疫情三年后再进校园 修复searchEngineJump在谷歌搜索页面不生效问题 事情既然发生了,可以是遗憾,不要去后悔。 侄女的试唱会比赛 新一代图片编码格式测试 省科技馆之行 Typora Windows版破解补丁及主题推荐 在Typora中使用PicList上传图片 域名ICP备案之变更网站 Ubuntu 系统如何使用 root 用户登录 中国联通——让一切自由连不通 如何选购适合的口罩?
Halo 블로그 저녁 카돈 수사기: '현학 카돈' 에서 '진범이 잡히다' 까지
吴蛋蛋 · 2026-05-22 · via 蛋蛋之家

서버: Oracle Cloud ARM| 응용 프로그램: Halo 2. x + PostgreSQL 15 + Nginx| 기록: 2026. 05. 21 - 22


挺玄学的头图,阴间版
아주 현학적인 머리도, 음간판

1) 문제의 이상한 부분

제 블로그(wuqishi.com)에는 이상한 문제가 하나 있어요.매일 저녁 20: 00 에서 23: 00 까지 정시 카드, 하지만 서버의 다른 사이트와 같은 똥은 없습니다.

서버는 Oracle Cloud 의 ARM 인스턴스이며 4 코어 24 G RAM 이 있으며 Docker Compose 를 실행합니다. Halo 외에도 몇 가지 Typecho 사이트와 순수한 정적 페이지가 있습니다.낮에는 모든 사이트가 빠르지만, 하로만 저녁에 도착하면 악과 같았습니다 - 페이지가 로드되고, 백그라운드에 들어갈 수 없으며, 때로는 오류를 직접보고합니다. ERR_CONNECTION_CLOSED

더 터무니없는 것은계속되는 카드가 아니라 간헐적 인 카드입니다.때로는 열 수 있고 두 번 누르면 또 막히고 때로는 완전히 연결되지 않고 몇 분 후에 다시 낫습니다.이런 "슈뢰딩거의 카튼" 은 법칙을 잡을 수 없기 때문에 가장 두통스럽다.

처음에는 Halo 2. x 가 Java (S pring Boot) 를 기반으로 하는 냄 비 라고 의심 했는데 , 결국 Java 는 메모 리를 먹는 것으로 유명 하며 Type cho 는 PHP 이며 사용 시 출시 됩니다 .그러나 Do ccker 구 성을 살펴 보면 J VM 힙 메모 리는 이미 5 G 를 제공 했으며 G 1 가 비 지 수집 기 도 켜 져 이론 적으로는 그렇지 않아 야합니다 .

💡

첫 번째 단계는 항상문제 범위를 확인합니다.。서버의 다른 사이트는 정상 → 글로벌 리소스 문제를 제외합니다; 응용 프로그램 카드 만 → 응용 프로그램 자체, 데이터베이스 또는 도메인 전용 트래픽에 문제가있을 가능성이 높습니다.


둘째, 조사의 첫 번째 단계: 로그를 뒤집고 층별로 아래로 파내십시오.

2.1 Nginx의 error.log 파일에 기록된 오류들

먼저, Nginx에 대해 살펴보겠습니다.error.log이러한 오류가 많이 발견되었습니다 :

2026/05/21 22:14:57 [error] 1234#1234: *45678 recv() failed (104: Connection reset by peer)
2026/05/21 22:14:57 [error] 1234#1234: *45678 upstream prematurely closed connection

모두 같은 경로를 가리키고 있습니다.

/apis/online-user.zyx2012.cn/v1alpha1/online-ws

이것은 내가 Halo 에 설치한 "온라인 인구 통계" 플러그인입니다. Nginx 가 Halo 로 요청을 전달한 후 Halo 는 응답 헤더를 반환하기 전에 연결을 끊는 것처럼 보입니다.더 무서운 것은, 이러한 오류는화면 브러시 레벨1 초에 10 개 정도 나올 수 있다.

2.2 dmesg 의 두 가지 주요 단서

그리고 동시에 나는 dmesg두 가지 현상이 발견되었습니다 :

첫째, Docker 컨테이너가 자주 재부팅됩니다.

vetha1b2c3d4: entered disabled state
vetha1b2c3d4: left promiscuous mode
docker0: port 2(vetha1b2c3d4) entered disabled state

가상 네트워크 카드가 끊임없이 파괴되고 재건되고 있습니다.즉, Halo 컨테이너가 충돌 → Docker 에 의해 자동으로 당겨진 후 다시 충돌하는 루프에 있음을 의미합니다.

둘째, UFW 방화벽은 스캔을 가로채고 있습니다.

[UFW BLOCK] IN=eth0 OUT= MAC=... SRC=185.191.171.12 DST=... DPT=5432
[UFW BLOCK] IN=eth0 OUT= MAC=... SRC=194.165.16.73 DST=... DPT=5432

화면이 가득하다. [UFW BLOCK]​,各种境外 IP 在扫我的端口:5432(PostgreSQL)、5985(WinRM)、3389(远程桌面)……

잠깐만요,5432?내 데이터베이스 포트가 어떻게 외부 네트워크에 노출되었습니까?

💡

많은 사람들이 응용 프로그램 로그만보고 커널 로그를 무시합니다. Docker 컨테이너의 빈번한 재부팅, 네트워크 카드 상태 변경, OOM 킬러 프로세스 죽이기 dmesg​ 안은 한눈에 분명하다.권장 사용 dmesg -T | grep -E "(UFW|veth|docker0)"​ 중요한 정보를 신속하게 필터링합니다.


셋째, 진짜 범인 1: 데이터베이스가 공개 인터넷에서 벌거벗고 뛰고 있다.

제가 열게요. docker-compose.yml 보시면 바보같아요 :

services:
  halodb:
    image: postgres:15-alpine
    ports:
      - "5432:5432"

당시 D Beaver 로 데이터베이스를 편리하게 연결하기 위해 호스트에 직접 매핑했습니다.그러나 나는 리눅스에있는 거대한 구멍을 잊었다 :UFW 방화벽을 우회하는 Docker

3.1 Docker 는 왜 UFW 를 우회합니까?

여기에 많은 사람들이 알지 못하는 세부 사항이 있습니다 :

UFW 는 본질적으로 iptables 패키지, 그것은 안에 있습니다. INPUT 체인에 규칙을 삽입합니다. Docker 는 컨테이너를 시작할 때 iptables​DOCKER 체 인 (속 nat 테이블 및 filter 자신의 규칙을 삽입하고,UFW 보다 높은 우선 순위 INPUT 체인

구체적으로, Docker 는 다음과 같은 DNAT 규칙을 만듭니다.

sudo iptables -t nat -L DOCKER -n --line-numbers | grep 5432

출력:

DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5432 to:172.18.0.2:5432

이 규칙의 의미는 호스트 5432 포트에 액세스하는 모든 트래픽이 Docker 컨테이너 내부의 172. 18. 0. 2: 5432 로 DNAT 됩니다.그것은 UFW 의 필터링 규칙 이전에 발생했습니다.그러나 UFW 는 그것을 막을 수 없습니다.

3.2데이터베이스 로그에서 폭력적인 해킹

데이터베이스 로그를 살펴보면, 그 상황이 더욱 충격적입니다.

2026-05-21 22:14:57.123 UTC [12345] FATAL: password authentication failed for user "postgres"
2026-05-21 22:14:57.123 UTC [12345] DETAIL: Role "postgres" does not exist.
2026-05-21 22:14:57.456 UTC [12346] FATAL: password authentication failed for user "postgres"
2026-05-21 22:14:57.789 UTC [12347] FATAL: password authentication failed for user "postgres"

해커가 기본 사용자 이름을 사용하고 있습니다. postgres 폭력적으로 내 데이터베이스를 해킹했다. Docker Compose 에서 데이터베이스 사용자 이름을 다른 이름으로 변경했기 때문에 시스템이 전혀 없습니다. postgres 이 사용자는, 그래서 매번 해킹은 FATAL 레벨에 오류가 보고되었습니다.

왜 밤에 특별한 카드?

저녁 은 전 세계 스 캐 너 의 피 크 시기 (유 럽 과 미국의 낮 근무 시간에 해당) 이기 때문에 초 당 수십 번의 악 성 연결 이 발생합니다 . Post gre SQL 의 기본 구성 에서는 연결 할 때마다 다음 을 수행 해야 합니다 .

  1. 포 크 백 엔 드 프로세 스 (약 5 - 10 MB 메모리)

  2. SSL 핸드셰이크 및 인증 계산

  3. 시스템 테이블 유효성 검사 사용자 이름 조회

  4. 실패 후 FATAL 로그 기록

이러한 정 크 요청 은 CPU 와 I / O 를 가득 채 웁 니다 .내 Halo 블로그 는 데이터 베이 스를 확인 하고 싶 습니까 ?줄을 서서 가 자 .

3.3수정 시나리오

포트를 로컬 루프에 바인딩하려면 다음과 같이 하십시오.

services:
  halodb:
    image: postgres:15-alpine
    ports:
      - "127.0.0.1:5432:5432"
    environment:
      - POSTGRES_USER=halo
      - POSTGRES_PASSWORD=your_strong_password
      - POSTGRES_DB=halo

재부팅을 완료하면 데이터베이스 로그가 순식간에 깨끗하고 FATAL 오류 메시지가 완전히 사라집니다.

💡 127.0.0.1:PORT:PORT

게으르지 말고 그냥 쓰기만 하면 된다. PORT:PORT그것은 공공 인터넷에서 벌거벗은 것과 같습니다. UFW 는 Docker 의 앞에서는 종이 호랑이입니다.외부 네트워크에서 데이터베이스에 연결해야하는 경우 포트를 직접 노출하는 대신 SSH 터널 또는 WireGuard 를 사용합니다.


넷째, 진짜 범인 2: Nginx 는 긴 연결을 열지 않았습니다.

데이터베이스는 조용하지만 웹 사이트는 여전히 가끔 카튼입니다.로그를 계속 보고 Nginx 를 발견하십시오. access.log 페이지가 로드될 때마다 메인 요청 외에도 더 많은 /apis/...​ API 요청.이러한 요청은 모두 다음과 같습니다 :

proxy_pass http://127.0.0.1:8090;

즉, 헤로에 직접 연결하고 업스트림으로 가지 않습니다.

문제는 여기에 있습니다 :나는 그럴 자격이 없다. upstream keepalive

4.1왜 짧은 연결이 당신을 끌어 당길 수 있습니까?

Nginx 는 역방향 프록시 때마다 새로운 TCP 연결을 만들고 사용되면 버립니다.밤에는 동시적으로 최고가 되고, 시스템에는 수만개가 쌓여 있다. TIME_WAIT 상태의 연결입니다.

당신은 그것을 사용할 수 있습니다. ss 명령 유효성 검사:

ss -tan state time-wait | wc -l

제가 정점에 이 숫자가 급증했습니다. 8000 +

TIME _ WA IT 는 TCP 의 4 번 흔들 림 의 정상적인 상태 입니다 (활 동 종료 당사 자는 마지막 AC K 가 상대 방 에 의해 수신 되었 는지 확인 하기 위해 2 MS L 을 기다 립니다), 하지만 너무 많은 경우 :

  • 임시 포트 사용หมดLinux: 기본 임시 포트 범위는 32768 - 60999 이며 약 28, 000 개입니다. 8000 + TIME _ WAIT 는 사용 가능한 포트가 급격히 감소하고 새로운 요청이 연결되지 않으며 "회전 ", " 화이트 화면 " 으로 나타납니다.

  • 메모리 사용량: 각 TIME_WAIT 커널에 연결된 TCP 제어 블록은 약 1 - 2 KB 를 차지합니다.

4.2수정 시나리오

Nginx의 설정 파일 상단에서 upstream을 정의합니다:

upstream halo_backend {
    server 127.0.0.1:8090;
    keepalive 64;
}

그리고 모든 것을 proxy_pass http://127.0.0.1:8090 로 바꾸다 proxy_pass http://halo_backend해당 위치에 추가합니다. Add the location:

proxy_http_version 1.1;
proxy_set_header Connection "";

따라서 Nginx 와 Halo 간에 64 개의 긴 연결이 다중화되어 있으며 더 이상 세 번의 핸드셰이크를 할 필요가 없습니다.

두 가지 세부 사항에 주목하십시오 :

  1. proxy_http_version 1.1 HTTP / 1. 0 은 기본적으로 kee pali ve 를 지원 하지 않기 때문에 필수 입니다 .

  2. proxy_set_header Connection ""​ NGinx 가 클라이언트를 Connection: close 백엔드로 전달되어 백엔드가 긴 연결을 자발적으로 끊습니다.

변경한 후 즉시 사용할 수 있습니다. ss 검증:

ss -tan state established '( dport = :8090 or sport = :8090 )' | wc -l

연결 수는 이전의 수백 개 에서 약 64 개 로 급 증 했으며 더 이상 성장 하지 않았습니다 . TIME _ WA IT 의 수는 또한 정상 수준 (수 십 에서 백 개) 으로 감소 했습니다 .

💡 ss 대체 netstat그것은 더 빠르고 정확합니다.

포트에 대한 연결 상태 분포를 보려면 다음을 수행합니다.

ss -tan state time-wait '( dport = :8090 )' | wc -l
ss -tan state established '( dport = :8090 )' | wc -l

만약 TIME_WAIT 5, 000 명 이상은 조심해야 한다.


V. 진짜 범인 3: WebSocket 플러그인의 재연결 폭풍

이제 그 "온라인 인구 통계" 플러그인으로 돌아가자.그 원리는 프런트 엔드가 WebSocket 긴 연결을 통해 실시간으로 온라인 상태를보고한다는 것입니다.

5.1 WebSocket 핸드셰이크는 왜 실패합니까?

WebSocket 은 일반적인 HTTP 요청이 아닙니다.그것의 설립 과정은 다음과 같습니다 :

  1. 클라이언트가 테이프를 전송합니다. Upgrade: websocket​Connection: Upgrade 헤더에 대한 HTTP 요청

  2. 서버 반환 101 Switching Protocols​연결이 HTTP 에서 WebSocket 전 이중 채널로 업그레이드됨

  3. 후 속 데이터는 프레 임을 통해 전송 되며 HTTP 요청 / 응답 모델 이 아닙니다 .

문제는 2 단계에 있습니다 :내 Nginx 가 제대로 전달되지 않습니다. Upgrade 머리

Nginx는 기본적으로 다음과 같은 방식으로 작동합니다.Upgrade 이러한 비 표 준 헤 더 는 필 터 링 (또는 일반 HTTP 요청 으로 처리) 되어 백 엔 드 Halo 가 Web So ccket 핸드 셰 이크 요청 이 아닌 일반 G ET 요청을 수신 하게 됩니다 .백 엔 드는 이것이 단지 일반적인 API 호출 일 뿐 이라고 생각 하며 처리 되면 연결 을 닫 습니다 .

프런트엔드 JS 가 WebSocket 연결 끊기를 감지하면자동 재연결그래서 형성되었습니다."연결 → 분리 → 재연결" 의 죽은 루프

5.2로그 속의 인형 현장

부터 access.log​ 이 과정을 명확하게 볼 수 있습니다 :

22:14:57 "GET /apis/online-user.../online-ws HTTP/1.1" 101 197
22:14:59 "GET /apis/online-user.../online-ws HTTP/1.1" 101 169  ← 同一个 IP,2 秒后重连
22:16:04 "GET /apis/online-user.../online-ws HTTP/1.1" 101 0    ← 传输 0 字节,空连接
22:16:48 "GET /apis/online-user.../online-ws HTTP/1.1" 101 143
22:16:56 "GET /apis/online-user.../online-ws HTTP/1.1" 101 143  ← 8 秒后又重连

한 방문 자는 짧은 시간 내에 3 ~ 4 번의 Web So ccket 핸드 셰 이크 를 시작할 수 있습니다 .저녁 에 수십 명의 방문 자가 있으며 다양한 크 롤 러 와 함께 Halo 의 스 레 드 풀 이 이러한 무 효 핸드 셰 이크 로 가득 차 있으며 정상적인 페이지 요청 은 시간 초 과 까지 대기 열 에 있을 수 있습니다 .

Nginxerror.log​ 안의 Connection reset by peerprematurely closed connection 그것이 바로 여기에 있습니다 - Halo 는 압도되었고 직접적으로 거칠게 연결을 닫았습니다.

5.3수정 시나리오

나는 긴 링크를 추가 한 후이 플러그인을 제거하지 않았기 때문에 지금은 문제가 없습니다, 여기에 기록 : Nginx 에서 WebSocket 을 올바르게 지원할 수 있습니다.해당 위치에 다음을 추가합니다. Add the following location:

location /apis/online-user.zyx2012.cn/ {
    proxy_pass http://halo_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
}

검증:

curl -i -N   -H "Connection: Upgrade"   -H "Upgrade: websocket"   -H "Host: wuqishi.com"   -H "Origin: https://wuqishi.com"   https://wuqishi.com/apis/online-user.zyx2012.cn/v1alpha1/online-ws

반환:

HTTP/2 101 Switching Protocols
upgrade: websocket
connection: upgrade

101 Switching Protocols 그것은 악수 성공, 긴 연결이 설정되었다는 것을 의미합니다.브라우저 F 12 의 네트워크 패널에서 웹소켓 연결 상태가 표시됩니다. (pending) 변하다. 101그 후 작은 녹색 점으로 변하고 더 이상 자주 재연결을 끊지 않습니다.

현재이 플러그인은 안정적으로 작동하고 있으며 온라인 인구 통계 기능은 완전히 정상적이며 이전 재연결 폭풍이 없습니다.

💡

curl 을 사용하여 핸드셰이크 요청을 직접 시뮬레이션하는 것이 가장 빠른 방법입니다.만약 반환하면 200 OK​ 대신, 101Nginx 또는 백엔드가 올바르게 처리되지 않습니다. Upgrade 머 리 .또한 , HTTP / 2 는 Web So cket 에 대한 지원 이 더 특별 하며 , Ng inx 는 1. 25. 1 부터 HTTP / 2 에서 Web So cket 을 지원 합니다 .


네 번째 위험 : 악의적 인 크롤러의 괴롭힘

조사 과정에서, nginx access.log 나를 웃게 만드는 또 다른 종류의 요청이 있습니다 :

185.191.171.12 "GET /wp-content/themes/begin/inc/go.php?url=..." 404
85.208.96.196 "GET /wp-content/themes/begin/inc/go.php?url=..." 404

Sem r ush 봇 (악 명 높은 SEO 크 롤 러) 은 미친 요청 에 내 사이트에 있습니다 .根本不存在的 WordPress 路径나는 일찍 돌아간다.Typecho그럼 이제 로 이동합니다.Halo가 다 .그것은 내가 여전히 WordPress 사이트 라고 생각 했고 , Beg in 테 마 의 리 디 렉 션 취약 점 (이 력 취약 점) 을 탐 지 하고 있었고 , 블랙 모 자 SEO 를 위한 발 판 으로 내 서버 를 사용 하려고 했습니다 .

이러한 요청은 모두 404 를 반환하지만 문제는 다음과 같습니다.모두 Halo 백엔드에 들어갑니다.

Nginx 는 물리적 파일과 일치하지 않습니다. @halo_proxy​Halo 는 각 404 요청에 대해 전체 페이지 렌더링을 초기화해야하며 404 페이지를 배출합니다. 1 초에 12 개 이상의 스레드 풀이 다시 낭비되었습니다.

6.1처리 방안

Nginx 수준에서 이러한 크롤러를 차단하는 대신 Cloudflare 에서 처리하기로 결정했습니다. Cloudflare 의 방화벽 규칙은 사용자 에이전트를 기반으로 SemrushBot, DotBot 및 기타 정크 크롤러를 직접 차단하여 내 서버의 리소스를 소비하지 않습니다.

이렇게 하는 것의 이점은 다음과 같습니다.

  • 정크 트래픽은 에지 노드에서 차단되어 내 서버에 도착하지 않습니다.

  • Nginx 에서 크롤러 블랙리스트를 유지할 필요가 없으며 Cloudflare 의 위협 인텔리전스 라이브러리가 자동으로 업데이트됩니다.

  • 내 Nginx 로그를 오염시키지 않으며 access. log 에는 실제 방문자만 있습니다.

💡

Cloudflare端自定义规则
Cloudflare 측 사용자 정의 규칙

표현식 코드:

(http.request.uri.path contains "/.env") or 
(http.request.uri.path contains "/.git") or 
(http.request.uri.path contains "/wp-") or 
(http.request.uri.path contains "/xmlrpc.php")

Cloudflare 의 방화벽 규칙, 봇 전투 모드 및 사용자 에이전트 차단은 소스 Nginx 에서 처리하는 것보다 더 효율적입니다.소스 스테이션의 리소스는 응답 크롤러에 낭비되기보다는 실제 사용자에게 남겨 두어야합니다.웹 사이트가 WordPress 가 아닌 경우 Cloudflare 에서 모든 콘텐츠를 차단할 수 있습니다. wp-contentwp-admin 404 요청은 반환되지 않습니다.


7. 기타 기타 기타 및 처리해야 할 사항

/ r ss . x ml 은 요청 할 때마다 115 KB 의 XML 을 동 적으로 생성 하며 여러 RSS 집 계 기 (F resh RSS , In ore ader , A stra Hub 등) 가 몇 분 마다 검색 합니다 .현재 는 잠시 정 적 캐 시를 하지 않고 먼저 놓 았다 .

💡

어떤 사람은 5 분마다, 어떤 사람은 30 분마다.당신은 그것을 통해 access.log 사용자 에이 전 트를 분석 하여 가장 빈 번 한 집 계 자를 찾아 캐 시 시간을 맞 게 설정 합니다 .또한 , Halo 의 RSS 생성 은 전체 기사 목록 이며 , 기 사가 많은 경우 (수 백 개), 매 번 생성 되는 것은 O (n) 의 통과 이며 CPU 를 매우 소비 합니다 . RSS 페이 징 을 고려 하거나 출 력의 수 를 제한 하는 것이 좋습니다 .

7.2 302 스톰에 대한 썸네일 에이전트

로그에서 많은 요청이 발견되었습니다 :

GET /apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https://cdn.ssslove.com/...&size=m HTTP/2.0" 302 0

Halo 의 축소판 서비스는 외부 체인 이미지에 대해 302 리디렉션을 수행했습니다.페이지에 사진이 많다면, 이것은 한 번 더 많은 불필요한 요청입니다.이후에는 이미지 링크를 CDN 의 매개 변수를 추가하는 직선 체인으로 직접 바꾸고 Halo 의 프록시 계층을 건너뛰는 것을 고려하십시오.

💡

외부 체 인 이미지 (예 : 클 라우 드 , O SS) 의 경우 프 런 트 엔 드 에서 직접 CD N 의 축 소 판 매 개 변 수를 사용하는 것이 좋습니다 (예 : !m 또는 ?x-oss-process=image/resize​Halo 의 프록시 계층을 건너뛰고 302 점프를 한 번 줄입니다.

7.3 HALO_EXTERNAL_URL의 문제점들

Docker Compose 에서 HALO _ EXTERNAL _ URL 이 __ JHSNS _ URL _ 0 __ 링크를 사용하여 잘못된 도메인 이름을 사용했습니다.

실제 도메인 이름으로 변경해야 합니다:

environment:
  - HALO_EXTERNAL_URL=https://wuqishi.com/

💡

그것은 또한 영향을 미칠 수 있습니다 :

  • Open Gra ph 탭 (We Chat , Twitter 에 공유 할 때 미리 보기 카드)

  • RSS 에서 <링크>와 [atom:link] 요소들

  • 일부 플러그인의 OAuth 콜백 주소

  • 메일 알림의 링크

잘못된 연결으로 인해 공유되는 게시물 링크는 __ JHSNS _ URL _ 0 __ 입니다.나는 현재로서는 수정하지 않았다.


제 8 장 : 나의 방법론

이 조사에서 나는 몇 가지 우회로를 갔지만 효과적인 방법론을 검증했습니다.

검사 순서

무엇을 했습니까?

뭘 발견했어?

주요 명령 / 도구

1.범위 확인

서버와 다른 사이트 비교

Halo 카드만 사용, 글로벌 리소스 문제 제외

htop, free -h, df -h

Nginx의 error.log 파일을 확인해보세요.

프런트 및 후면 단절 원인을 확인합니다.

대량 Connection reset by peer​

​tail -f /var/log/nginx/error.log

3. dmesg 보기

시스템 레벨 예외 확인

Docker 빈번한 재부팅 + UFW 대량 차단

​dmesg -T | grep -E "(UFW|veth|docker0)"​

4.데이터베이스 로그 보기

DB 압력 확인

공중넷 폭력 해킹, FATAL 화면 닦기

​docker logs halodb​

5. Nginx access. log 을 참조하십시오.

요청 분포 분석

악성 크롤러 + WebSocket 고주파 재연결

awk '{print $6, $7}' access.log | sort | uniq -c | sort -rn​

6.브라우저 F 12

프 런 트 엔 드 / 백 엔 드 속도 구분

높은 TTFB, 백엔드 응답이 느린 확인

Chrome DevTools → 네트워크 → 타이밍

7.연결 상태 확인

TCP 리소스가 고갈되었음을 확인합니다.

TIME _ WAIT 8000 +

​ss -tan state time-wait | wc -l​

8. WebSocket 핸드셰이크 시뮬레이션

업그레이드 헤더 전달 확인

101 이 아닌 200 을 반환합니다.

curl -H "Upgrade: websocket" ...​

핵심 원칙: 외부에서 내부로, 먼저 쓰레기 흐름을 차단하고 내부 구성을 수리합니다.

처음부터 JVM 매개 변수를 조정하고 데이터베이스 인덱스를 추가하면 범인을 결코 찾을 수 없습니다.왜냐하면 뿌리는 성능이 부족한 것이 아니라쓰레기 요청에 자원 낭비


9 현재 상태

구성을 변경하고 서비스를 다시 시작한 후, 오늘까지 30 분 동안 로그를 응시했습니다.

  • 데이터베이스 로그: 조용하고 가끔은 정상적인 쿼리 상호 작용

  • Nginx 오류 로그: 0 오류

  • Nginx access. log클라우드 플레어는 대부분의 쓰레기 크롤러를 차단했습니다.

  • WebSocket 플러그인: 손잡이 돌아가기 101 Switching Protocols긴 연결은 안정적이며 더 이상 자주 재연결되지 않으며 온라인 인구 통계 기능이 정상적으로 작동합니다.

  • 페이지 로드: iPad, Mac, 휴대 전화 4 G 테스트, 정상적으로 켜져 있습니다.

저녁 22 시 30 분부터 23 시까지 가장 막았던 시간이 이제는 낮처럼 부드럽습니다.(오늘밤에 다시 한번 살펴볼게요.


반성 : 간과되기 쉬운 6 개의 구덩이

Pit 1: Docker 포트 매핑은 기본적으로 공개 네트워크, UFW 를 막을 수 없습니다.

데이터베이스, Redis, MQ 와 같은 민감한 서비스는 반드시 연결되어야 합니다. 127.0.0.1UFW를 믿지 마세요. 대신…iptables -t nat -L DOCKER

Pit 2: Nginx Anti - Agent 기본값은 짧은 연결입니다.

높은 동시 시나리오는 켜야 합니다. keepalive그렇지 않으면 TIME_WAIT 그것은 당신을 끌어당길 것입니다.ss -tan state time-wait | wc -l​ 5, 000 명 이상은 조심해야 한다.

구덩이 3: WebSocket 은 "배치하면 된다" 는 것이 아닙니다.

Upgrade​Connection 머리가 없어서는 안 된다.사용할 수 있습니다. curl​ 시뮬레이션 핸드셰이크 빠른 검증, 반환 101 성공 이 될 수 있다 .또한 Ng inx 버전 , HTTP / 2 의 Web So cket 에 대한 필요 에 유 의 하십시오 . Nginx의 버전은 1.25.1 이상이어야 합니다.

Pit 4 : 타사 플러그인은 신중하지만 한 가지 크기가 맞을 필요는 없습니다.

이 온라인 플 러 그 인의 문제의 근 원은 플 러 그 인 자체가 아니라 Ng inx 구성 에서 누 락 되었습니다 .수정 후 플 러 그 인은 안정 적으로 작동 하고 완전히 작동 합니다 .따라서 플 러 그 인 관련 문제가 발생 하면 인 프 라 (N gin x , 역 방 향 에이 전 트 , 방 화 벽) 를 확인 하고 제거 를 서 두 르지 마십시오 .

Pit 5 : 로그는 최고의 디버거입니다.

이번 검사에는 Java 코드 한 줄도 변경되지 않았으며 모든 문제는 로그에서 꺼져 있습니다.로그를 읽는 습관을 키우는 것은 맹목적으로 참조를 조정하는 것보다 훨씬 중요합니다.

이 두 필드를 Nginx 로그에 추가하여 프런트엔드가 느린지 백엔드가 느린지 한눈에 알 수 있도록하는 것이 좋습니다.

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" '
                'rt=$request_time urt=$upstream_response_time';
  • ​rt(re quest _ time): 클 라이언 트 뷰 에 대한 총 소요 시간

  • ​urt​(up stream _ response _ time): 백 엔 드 처리 시간

만약 rt 아주 크지만 urt아주 작다 → 문제는 네트워크나 Nginx에 있습니다. 만약 그렇다면…urt 문제는 뒷면에 있습니다.

Pit 6 : 파충류의 영향을 무시하지 마십시오.

SemrushBot, DotBot 이 상업용 크롤러들은 매우 공격적이며, 그들은 당신의 행동을 따르지 않을 것입니다. robots.txt또한 WordPress 취약점 경로 스윕을 전문으로 선택합니다.사이트가 WP 가 아닌 경우 Cloudflare 또는 Nginx 계층에서 직접 차단하여 백엔드 리소스를 낭비하지 마십시오.


Halo 또는 유사한 Java 블로그 시스템을 사용하여 저녁 카톤을 경험하고 있다면이 기록이 몇 가지 아이디어를 제공하기를 바랍니다.때로는 문제가 코드의 복잡성이 아니라 구성 세부 사항, 플러그인 또는 공용 네트워크에 노출 된 포트입니다.

마지막으로, Semrush Bot 은 21: 00 에서 23: 00 까지 2 시간 동안 스윕을 중단하지 않고 Cloudflare 에 의해 수백 번 차단되었습니다.이러한 헌신적 인 정신은 올바른 길로 일찍 건축가가되었습니다.


2026 년 5 월 22 일 새벽에 작성되었으며, 일부 콘텐츠는 AI 조회에 의해 정리되었습니다.