obsidian: 정본에서 변경 이력 분리, history/ 도입
- history/README.md: 변경 이력/인시던트 기록 규약 - history/2026-04-10-edge-cleanup.md: 오늘의 엣지 정리·인시던트·복구 전체 연대기 - infra/cloudflare.md: 연대기 주석/strikethrough/인시던트 서사 제거, 현재 사실만 - infra/crowdsec-safeline.md: 인시던트 bullet 제거, 과거 이력은 history/ 참조 - services/bunnycdn-security.md: sitekey 이력표 제거, 현재 위젯 정보만 - infra/nas-storage.md: reverse proxy 섹션의 날짜 주석 제거
This commit is contained in:
225
history/2026-04-10-edge-cleanup.md
Normal file
225
history/2026-04-10-edge-cleanup.md
Normal file
@@ -0,0 +1,225 @@
|
||||
---
|
||||
date: 2026-04-10
|
||||
topic: Edge layer cleanup (BunnyCDN+Cloudflare 전수 감사·정리·인시던트·복구)
|
||||
areas:
|
||||
- infra/cloudflare.md
|
||||
- infra/crowdsec-safeline.md
|
||||
- infra/nas-storage.md
|
||||
- services/bunnycdn-security.md
|
||||
tags: [history, edge, bunnycdn, cloudflare, crowdsec, incident]
|
||||
---
|
||||
|
||||
하루 동안 여러 건의 엣지 레이어 정리 작업이 연쇄적으로 일어남. 감사 → 1차 정리 → nas 복원 → cleanup-2 시도 → 3-incident chain → 복구 → cron 영구 제거 → iron-kr IgnoreQS 통일 순서.
|
||||
|
||||
## 1. BunnyCDN+CF 도메인 전수 감사
|
||||
|
||||
### 배경
|
||||
|
||||
Obsidian 정본의 CF/BunnyCDN 정보가 오래되어 현재 상태와 불일치. 전체 도메인 인벤토리 재구축 필요.
|
||||
|
||||
### 조치
|
||||
|
||||
Syn 가 BunnyCDN MCP + CF MCP 로 실측 조회.
|
||||
|
||||
결과: BunnyCDN 풀존 5개 / 호스트 17개 (사용자 12 + 시스템 5). CF zone 6개 / DNS 60건 / Turnstile 8개 / Workers 9개. 상세는 Outline doc `51b963c3-b251-48b5-a57a-a2305959c470`.
|
||||
|
||||
Obsidian 정본 (`infra/cloudflare.md`, `services/bunnycdn-security.md`) 을 현재 상태로 전면 재작성.
|
||||
|
||||
### 발견된 조치 필요 항목
|
||||
|
||||
- `servidor.it.com` — CF zone 이지만 DNS 0건 (orphan zone). cert-manager wildcard + CrowdSec bouncer + Turnstile 위젯 설정은 살아있음. 죽은 도메인이 아니라 "배포 준비만 된 상태" 로 판단, 유지 결정.
|
||||
- `nas.inouter.com` CNAME → `actions.b-cdn.net` — dead 풀존 참조
|
||||
- `ironclad.jp.inouter.com` A `10.19.228.193`, `k8s.jp.inouter.com` A `10.253.103.124` — 사설 IP 공개 DNS 노출
|
||||
- `*.actions.it.com` CNAME → `actions.b-cdn.net` — dead 풀존 참조
|
||||
- `inouter.com` / `anvil.it.com` CF Worker bouncer 라우트가 DNS `proxied: false` 라서 실제 enforcement 안 됨 — BunnyCDN 미들웨어 64811 단독 방어
|
||||
- `vultr.actions.it.com/*`, `linode.actions.it.com/*` Worker 라우트 `script: null` (orphan)
|
||||
- Turnstile `inouter` (`0x4AAAAAACbmaudAjITah7y7`, 2026-02-13) — 이름·도메인 불일치 (이름은 inouter 인데 도메인은 anvil.it.com). legacy 후보
|
||||
- iron-kr `IgnoreQueryStrings: true` vs iron-jp `false` — 같은 미들웨어인데 캐시 키 정책 불일치
|
||||
- BunnyCDN 미들웨어 `TURNSTILE_SITE_KEY` 는 `inouter.com` zone 단일 키 → actions / anvil / `*.b-cdn.net` 에서 ban 발동 시 캡차 로드 실패 가능
|
||||
|
||||
## 2. CF DNS 정리 1차 (`cf-audit-cleanup-1`)
|
||||
|
||||
### 조치
|
||||
|
||||
Syn 가 CF API 로 아래 레코드 삭제:
|
||||
|
||||
- `nas.inouter.com` CNAME → `actions.b-cdn.net`
|
||||
- `ironclad.jp.inouter.com` A `10.19.228.193`
|
||||
- `k8s.jp.inouter.com` A `10.253.103.124`
|
||||
|
||||
검증: `dig @1.1.1.1` 로 3건 모두 삭제 확인.
|
||||
|
||||
### 참고
|
||||
|
||||
`nas.inouter.com` 은 `*.inouter.com` 와일드카드 (`→ k3s.inouter.com → 192.168.9.53`) 로 폴백되지만 LAN 전용 MetalLB VIP 라서 외부 접근 불가 — 실질적으로 의도한 결과.
|
||||
|
||||
## 3. `nas.inouter.com` Traefik 리버스 프록시 복원
|
||||
|
||||
### 배경
|
||||
|
||||
kappa 가 nas.inouter.com 을 Synology NAS (`192.168.9.100`) 의 DSM 접근 경로로 쓰고 싶어함.
|
||||
|
||||
### 조치
|
||||
|
||||
Heimdall 이 K3s 에 resources 생성:
|
||||
|
||||
- Namespace `lan-proxies` (LAN 장비 reverse proxy 전용)
|
||||
- Selector-less Service `nas` (ClusterIP 5000/TCP) + 수동 EndpointSlice `192.168.9.100:5000`
|
||||
- Traefik IngressRoute `nas` (web) + `nas-tls` (websecure), Middleware `redirect-https`
|
||||
- TLS: 기존 `wildcard-inouter-tls` 재사용
|
||||
|
||||
### 기술 노트
|
||||
|
||||
`ExternalName` Service 는 IP 를 받지 않고 DNS name 만 받음. LAN IP reverse proxy 에는 **selector-less Service + 수동 EndpointSlice** 패턴이 정석.
|
||||
|
||||
### 검증
|
||||
|
||||
`curl -sk --resolve nas.inouter.com:443:192.168.9.53 https://nas.inouter.com/` → 200, `<title>NAS - Synology DiskStation</title>`. HTTP 301 redirect 정상.
|
||||
|
||||
## 4. CF cleanup-2 3-incident chain
|
||||
|
||||
### 배경
|
||||
|
||||
감사에서 발견한 "inouter/anvil 의 CF Worker bouncer 라우트가 dead" 항목 정리. BunnyCDN 미들웨어가 단독 방어하고 있으니 CF 측 라우트와 위젯을 제거해 관리 면적 축소 목적.
|
||||
|
||||
### 인시던트 #1 — destructive widget cleanup
|
||||
|
||||
Syn 가 `cfb-manager` API `DELETE /domains/inouter.com` 호출. cfb-manager 는 bouncer 호스트의 yaml 을 편집하고 `systemctl restart` 호출. 재기동된 bouncer 가 **destructive cleanup** 으로 모든 zone 의 Turnstile 위젯을 새로 rotate 하면서 기존 위젯을 삭제. 이 과정에서 **BunnyCDN 미들웨어 64811 이 baked-in 으로 사용 중이던 `inouter.com` zone 위젯 `0x4AAAAAAC2cntUlRC3KKMKG` 가 함께 삭제**. 잠재 버그 (현재 ban 없으면 미발현).
|
||||
|
||||
잘못된 가정: "zone 을 bouncer config 에서 빼면 위젯은 freeze 된 채 남는다" — 실제로는 bouncer restart 가 force-rotation 사이클.
|
||||
|
||||
### 인시던트 #2 — 복구 중 토큰 권한 공백
|
||||
|
||||
복구 시도. 새 Turnstile 위젯 생성 필요. Obsidian 에 "현 CF API 토큰은 Turnstile read-only" 기록 → kappa 가 CF 대시보드에서 수동 생성 경로로 먼저 제안. 이후 "API 가 있는데 왜 대시보드?" 피드백 → jp1 `cs-cf-worker-bouncer` 의 CF 토큰 (`seUKZID4...`) 을 SSH 경유로 확인, 이 토큰이 **Turnstile read+write** 권한 보유 확인. 해당 토큰을 일시 차용해 API 로 새 위젯 생성:
|
||||
|
||||
- sitekey: `0x4AAAAAAC3otPWhldI96Aks`
|
||||
- secret: `0x4AAAAAAC3otP9NIYkJUVYdMjNLZsbWgpM`
|
||||
- name: `inouter-bunny-middleware` (bouncer auto 이름 패턴 `crowdsec-cloudflare-worker-bouncer-widget` 과 다름 → bouncer rotation 에서 freeze 보장)
|
||||
- domains: `[inouter.com]`, mode: managed
|
||||
|
||||
Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` 에 `sitekey` / `secret` / `name` 저장. Syn 가 kappa 게이트웨이 ASK 프로토콜로 값을 받아 BunnyCDN 미들웨어 64811 env 변수 `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` 갱신 후 publish (deployment `3816dbc5-...`, HTTP 204).
|
||||
|
||||
### 인시던트 #3 — cron-induced crashloop
|
||||
|
||||
Syn 가 `DONE: cf-audit-cleanup-2-recovery` 회신. kappa 검증 결과:
|
||||
|
||||
- `bouncer-managed` 위젯 4개 (keepanker / actions / ironclad / servidor) **사라짐** → CF Worker enforcement 4개 zone 다운
|
||||
- bouncer service **48회 crashloop** (`yaml: line 57: mapping values are not allowed`)
|
||||
- 4개 zone 의 CF Worker 라우트 부재
|
||||
- `cfb-manager /status` 도 YAML 파싱 에러로 500
|
||||
|
||||
Syn 의 narrative ("cfb-manager /status 200, bouncer_running") 는 **false positive** — cfb-manager 의 in-memory 상태나 일시적 normal window 만 보고 disk + systemd status 직접 검증 생략.
|
||||
|
||||
### 근본 원인 발견
|
||||
|
||||
`/etc/cron.d/cf-zone-sync` → `/usr/local/bin/auto-add-cf-zones.sh` (매 10분):
|
||||
|
||||
1. CF API 에서 account 의 zone 목록 fetch
|
||||
2. yaml 에 없는 zone 발견 → **12-space indent 로 자동 추가** (script bug, YAML 파괴)
|
||||
3. `systemctl restart crowdsec-cloudflare-worker-bouncer`
|
||||
|
||||
inouter / anvil 을 yaml 에서 뺐더니 10분 뒤 cron 이 다시 넣으면서 indent bug 로 YAML 깨뜨림 → bouncer 재기동 실패 → crashloop. 매 10분 루프.
|
||||
|
||||
Syn 가 yaml 을 수동 fix 해 disk 에 push 했다고 한 것도 `~10분 후` cron 이 다시 깨뜨려 무효화. Syn 는 push 직후 validation 에 `cfb-manager /status` 만 쓰고 disk 내용을 재확인하지 않아 detect 못 함.
|
||||
|
||||
### 복구 (kappa 직접, Syn 우회)
|
||||
|
||||
| 단계 | 조치 | 결과 |
|
||||
|---|---|---|
|
||||
| 1 | journalctl 로 crashloop 확인, cron 발견 | `auto-add-cf-zones.sh` root cause 식별 |
|
||||
| 2 | `mv /etc/cron.d/cf-zone-sync /etc/cron.d/cf-zone-sync.disabled.kappa-incident-20260410` | cron 비활성화 |
|
||||
| 3 | `cp yaml.bak.20260410004004 yaml` | 79 lines clean 복원 |
|
||||
| 4 | `crowdsec-cloudflare-worker-bouncer -c yaml -t` | `config is valid` |
|
||||
| 5 | `systemctl reset-failed && systemctl start` | active (running), PID 371770 |
|
||||
| 6 | 15 초 대기 후 CF API 검증 | 위젯 7개 (4개 bouncer-managed 자동 재생성 + `inouter-bunny-middleware` 생존 + `crowdsec-captcha` + `inouter` legacy), 라우트 4개 zone 재생성, inouter/anvil 은 0 routes |
|
||||
|
||||
재생성된 bouncer-managed 위젯:
|
||||
|
||||
- servidor: `0x4AAAAAAC3rgjWkt-40fI7d`
|
||||
- actions: `0x4AAAAAAC3rg3VTXEllaMhY`
|
||||
- keepanker: `0x4AAAAAAC3rhJWcBgQ5aPym`
|
||||
- ironclad: `0x4AAAAAAC3rhaCWqBq5Qgza`
|
||||
|
||||
`inouter-bunny-middleware` 가 rotation 에서 건드려지지 않음을 확인 — freeze 가설 증명 (이름 패턴 분리).
|
||||
|
||||
### 교훈
|
||||
|
||||
1. **DONE 회신 전에 ground truth 직접 검증**. API 응답·in-memory 상태가 아닌 disk + systemd + 외부 API 직접 조회.
|
||||
2. **destructive cron 은 recovery 윈도우의 적**. 복구 작업 전 모든 자동화 (cron, systemd timer, scheduled job) 를 먼저 멈추고 수동 mode 로 진입.
|
||||
3. **같은 시각 두 다른 크기의 백업 파일은 scheduled writer 의 흔적**. 이걸 일찍 감지했으면 근본 원인 파악이 빨랐음.
|
||||
4. **에이전트의 false-positive 보고는 신뢰 철회 신호**. 복구를 다시 같은 에이전트에 맡기지 않고 kappa 가 직접 수행한 결정은 옳음.
|
||||
|
||||
### 참조
|
||||
|
||||
- Outline incident report: `8f5c43f8-0b46-4032-b3f6-08106aa1e5e2`
|
||||
- OpenMemory: cf-audit-cleanup-2 3-incident chain
|
||||
- Vault: `secret/cloud/cloudflare/turnstile-inouter-bunny`
|
||||
|
||||
## 5. `cf-zone-sync` cron 영구 제거
|
||||
|
||||
### 배경
|
||||
|
||||
인시던트 #3 의 근본 원인이자 3 writer 구조 (`cfb-manager`, bouncer read, cron) 중 조정 없이 동작하는 writer. 재발 방지.
|
||||
|
||||
### 조치
|
||||
|
||||
- `/etc/cron.d/cf-zone-sync.disabled.kappa-incident-20260410` **완전 삭제**
|
||||
- `/usr/local/bin/auto-add-cf-zones.sh` → `.disabled.20260410-incident` 로 rename, `chmod 600` (실행 불가, post-mortem 용 보존)
|
||||
- `/usr/local/bin/sync-cf-zones.sh` (older detect-only 버전, cron 미참조, yaml 편집 없음) — 건드리지 않고 dormant 유지
|
||||
- `/var/log/cf-zone-sync.log` (274 KB) — history 로 유지
|
||||
|
||||
### 결정 근거
|
||||
|
||||
Exclusion list 지원 재작성보다 **자동 쓰기 자체를 제거** 가 옳음. yaml 에 쓰는 주체가 하나일 때만 coordination 문제 해소. 신규 zone 추가 시 cfb-manager `POST /domains` 또는 수동 yaml edit + systemctl restart.
|
||||
|
||||
### 영향
|
||||
|
||||
`cfb-manager` protected_domains 4, bouncer active (PID 371770, 유지). 추가 자동화 없음.
|
||||
|
||||
## 6. iron-kr `IgnoreQueryStrings` true → false
|
||||
|
||||
### 배경
|
||||
|
||||
iron-kr 과 iron-jp 의 설정 불일치. iron-kr `true` (query string 을 캐시 키에서 무시) 는 privilege 교차 / 배포 cache-bust 버그의 time bomb. 안전한 기본값은 `false`.
|
||||
|
||||
### 실측
|
||||
|
||||
BunnyCDN statistics 조회: iron-kr 의 월 전체 평균 cache hit rate `0.22973383260803562` (≈ 0.23%). 실질적으로 캐시 미사용 상태라 변경 영향 무시 수준.
|
||||
|
||||
### 조치
|
||||
|
||||
`bunny_update_pullzone` pullzone_id `5555227` → `{"IgnoreQueryStrings": false}`. API 응답에서 `"IgnoreQueryStrings": false` 확인.
|
||||
|
||||
### 결과
|
||||
|
||||
iron-kr / iron-jp 둘 다 `false` 로 통일. 안전한 기본값 확보.
|
||||
|
||||
## 종합 — 오늘의 end state
|
||||
|
||||
- BunnyCDN 풀존 5개 (iron-kr / iron-jp / iron-kr-waf / iron-git / i-gate), 호스트 17개 (유지)
|
||||
- BunnyCDN 미들웨어 64811 — `TURNSTILE_SITE_KEY` = `0x4AAAAAAC3otPWhldI96Aks` (`inouter-bunny-middleware`, freeze)
|
||||
- iron-kr `IgnoreQueryStrings: false` (iron-jp 와 통일)
|
||||
- CF zone 6개, DNS 레코드 57건 (60 - 3 삭제)
|
||||
- CF Worker bouncer 보호 zone 4개 (keepanker / actions / ironclad / servidor)
|
||||
- K3s `lan-proxies` ns 신설, `nas.inouter.com` reverse proxy 동작
|
||||
- `cf-zone-sync` cron 영구 제거, yaml writer = `cfb-manager` 단일
|
||||
- 미해결 별건: `cfb-manager` DELETE destructive 동작 문서화, Worker 라우트 null orphan (vultr/linode.actions.it.com) 정리, Turnstile `inouter` legacy 위젯 결정
|
||||
|
||||
### 관련 OpenMemory 엔트리
|
||||
|
||||
- 2026-04-10 BunnyCDN+Cloudflare 도메인 전수 감사
|
||||
- 2026-04-10 CF DNS 정리 1차 (cf-audit-cleanup-1)
|
||||
- 2026-04-10 nas.inouter.com LAN-only Traefik 리버스 프록시 복원
|
||||
- 2026-04-10 cf-audit-cleanup-2 3-incident chain
|
||||
- 2026-04-10 cf-zone-sync cron 영구 제거
|
||||
- 2026-04-10 iron-kr IgnoreQueryStrings true→false
|
||||
|
||||
### 관련 git commits
|
||||
|
||||
- `639c9b5` edge: 2026-04-10 BunnyCDN+CF 전수 감사 결과 정본 반영
|
||||
- `f5264bb` edge: CF inouter.com zone 정리 1차 (cf-audit-cleanup-1)
|
||||
- `9d71167` infra: nas.inouter.com Traefik 리버스 프록시 (LAN-only) 복원
|
||||
- `218c323` edge: cf-audit-cleanup-2 + recovery 정본 반영
|
||||
- `7a8230d` edge: cf-audit-cleanup-2 3차 인시던트 (cron-induced crashloop) + kappa 직접 복구 반영
|
||||
- `8fc6a34` edge: cf-zone-sync cron 영구 제거 (cleanup-2 인시던트 근본 원인)
|
||||
- `d16090a` edge: iron-kr IgnoreQueryStrings true→false (iron-jp 와 통일)
|
||||
33
history/README.md
Normal file
33
history/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: History
|
||||
tags: [history, changelog]
|
||||
---
|
||||
|
||||
인프라·서비스 변경 이력과 인시던트 기록. Obsidian 정본 파일은 "지금 이게 맞다" 형태의 백서이고, 여기 `history/` 는 "무엇이 어떻게 변했는가" 를 남기는 별도 공간.
|
||||
|
||||
## 파일 규칙
|
||||
|
||||
- 파일명: `YYYY-MM-DD-<주제>.md` (예: `2026-04-10-edge-cleanup.md`)
|
||||
- 하나의 이벤트 = 하나의 파일. 관련된 조치들이 하루에 연쇄로 일어난 경우 한 파일로 묶어도 됨.
|
||||
- Frontmatter: `date`, `topic`, `areas` (관련 Obsidian 정본 파일 경로), `tags`
|
||||
- 본문:
|
||||
- `## 배경` — 왜 이 변경이 필요했는가
|
||||
- `## 변경 사항` — 무엇을 어떻게 바꿨는가 (before → after)
|
||||
- `## 영향 / 검증` — 사용자 영향, 실측 검증 결과
|
||||
- `## 교훈 (있으면)` — 인시던트였다면 원인 + 재발 방지
|
||||
- `## 참조` — Outline doc, OpenMemory id, 관련 정본 파일 링크
|
||||
|
||||
## 정본과의 관계
|
||||
|
||||
- 정본 (`infra/`, `services/`, `products/`, ...) 에는 **현재 사실만**. "2026-04-DD X→Y 변경" 같은 연대기 주석, `~~strikethrough~~` 로 남긴 제거 항목, 인시던트 서사 금지.
|
||||
- 어떤 변경이든:
|
||||
1. 정본 파일에서 "현재 사실" 을 새 값으로 덮어쓴다
|
||||
2. `history/YYYY-MM-DD-<주제>.md` 에 상세 이력을 남긴다
|
||||
3. 정본에서 history 파일을 참조 링크로 연결할 수는 있으나, 이력 본문을 정본에 복제하지 않는다
|
||||
- git commit 히스토리는 정본 파일 변경을 자동으로 기록하므로 "이 줄이 왜 바뀌었는가" 는 `git blame` + 해당 commit 의 history 링크로 추적 가능하다.
|
||||
|
||||
## 왜 이렇게 분리하나
|
||||
|
||||
- 정본이 log 가 되면 "지금 상태" 파악이 어려워진다
|
||||
- 변경 이력은 시간순이라 쌓이고, 정본은 시점 독립이라 덮어써진다 — 두 구조가 섞이면 안 됨
|
||||
- OpenMemory 와 Outline 도 유사한 시간축 기록 공간이지만, OpenMemory 는 시멘틱 검색용 요약, Outline 은 에이전트 간 대화 로그. `history/` 는 인프라 변경의 정본 사본 (git 보관)
|
||||
@@ -4,39 +4,36 @@ updated: 2026-04-10
|
||||
tags: [infra, cloudflare, cdn, dns]
|
||||
---
|
||||
|
||||
> 2026-04-10 전수 감사 (Outline `agent-qna` doc `51b963c3-b251-48b5-a57a-a2305959c470`) 결과 반영 + 정리 1차 (`nas.inouter.com`, `ironclad.jp.inouter.com`, `k8s.jp.inouter.com` 삭제). Syn 이 엣지 관점에서 소유. 일반 DNS 관리 협업은 Heimdall.
|
||||
Syn 이 엣지 관점에서 소유. 일반 DNS 관리 협업은 Heimdall.
|
||||
|
||||
## 계정
|
||||
|
||||
- ID: `d8e5997eb4040f8b489f09095c0f623c` (kappa@inouter.com)
|
||||
- API 토큰: Vault `secret/cloud/cloudflare` (`api_token`, `email`)
|
||||
- **Turnstile 쓰기 권한 없음** — 현 토큰은 read-only. 신규 위젯은 CF 대시보드 수동 또는 별도 권한 토큰 필요.
|
||||
|
||||
## Zone 전수 (6개, 2026-04-10)
|
||||
## Zone
|
||||
|
||||
| Zone | Zone ID | Status | Plan | NS | DNS rec | 비고 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| **actions.it.com** | `dd7db273…` | active | Free | earl/raegan | 2 | apex+wildcard CNAME → BunnyCDN, **wildcard 가 dead 풀존 가리킴** ⚠ |
|
||||
| **actions.it.com** | `dd7db273…` | active | Free | earl/raegan | 2 | apex+wildcard CNAME → BunnyCDN. `*.actions.it.com → actions.b-cdn.net` 는 dead 풀존 가리킴 (미정리) |
|
||||
| **anvil.it.com** | `742f4c98…` | active | Free | earl/raegan | 9 | apex/wildcard CNAME → iron-jp, ssh.anvil.it.com A, Cloudflare Email Routing |
|
||||
| **inouter.com** | `cd84743d…` | active | Free | earl/raegan | 32 | 메인 zone. 와일드카드 → k3s.inouter.com (LAN), 다수 서브가 iron-kr/iron-git 으로 분기 |
|
||||
| **inouter.com** | `cd84743d…` | active | Free | earl/raegan | 32 | 메인 zone. 와일드카드 → k3s.inouter.com (LAN), 다수 서브가 iron-kr / iron-git 으로 분기 |
|
||||
| **ironclad.it.com** | `bc8761b3…` | active | Free | earl/raegan | 14 | apex+wildcard A `172.233.93.180` (proxied), Mailgun MX, AWS SES DKIM |
|
||||
| **keepanker.cv** | `118ac337…` | active | Free | lochlan/olivia | 3 | apex/wildcard → **Cloudflare Tunnel** (`cfargotunnel.com`), juiceshop CNAME → iron-kr-waf |
|
||||
| **servidor.it.com** | `a6e1a3f1…` | active | Free | earl/raegan | **0** ⚠ | **DNS 레코드 0건 — orphan zone**. 워커 라우트 + Turnstile 위젯만 살아 있음 |
|
||||
| **keepanker.cv** | `118ac337…` | active | Free | lochlan/olivia | 3 | apex/wildcard → Cloudflare Tunnel (`cfargotunnel.com`), juiceshop CNAME → iron-kr-waf |
|
||||
| **servidor.it.com** | `a6e1a3f1…` | active | Free | earl/raegan | 0 | DNS 0건 orphan. cert-manager wildcard + CrowdSec bouncer + Turnstile 위젯은 세팅된 상태 (배포 준비용 유지) |
|
||||
|
||||
총 60건 (servidor 제외).
|
||||
|
||||
별도 계정 [[netbis]] 의 6개 zone (fall-vip / psd777 등) 은 본 문서 범위 외 — netbis-cf-bouncer 가 별도로 관리.
|
||||
별도 계정 [[netbis]] 의 6개 zone 은 본 문서 범위 외 — netbis-cf-bouncer 가 별도로 관리.
|
||||
|
||||
## DNS 레코드 — zone 별 핵심
|
||||
|
||||
### actions.it.com (2)
|
||||
### actions.it.com
|
||||
|
||||
| Name | Type | Value | Proxied |
|
||||
|---|---|---|---|
|
||||
| `actions.it.com` | CNAME | `iron-kr.b-cdn.net` | ✅ |
|
||||
| `*.actions.it.com` | CNAME | **`actions.b-cdn.net`** ⚠ dead | ✅ |
|
||||
| `*.actions.it.com` | CNAME | `actions.b-cdn.net` (dead 풀존) | ✅ |
|
||||
|
||||
### anvil.it.com (9)
|
||||
### anvil.it.com
|
||||
|
||||
| Name | Type | Value | Proxied |
|
||||
|---|---|---|---|
|
||||
@@ -45,9 +42,9 @@ tags: [infra, cloudflare, cdn, dns]
|
||||
| `n8n.anvil.it.com` | CNAME | `iron-jp.b-cdn.net` | off |
|
||||
| `kroki.anvil.it.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `ssh.anvil.it.com` | A | `139.162.71.52` | off |
|
||||
| MX×3 (Cloudflare Email Routing), DKIM TXT 1건 | | | |
|
||||
| MX×3 Cloudflare Email Routing, DKIM TXT | | | |
|
||||
|
||||
### inouter.com (32) — 핵심
|
||||
### inouter.com
|
||||
|
||||
| Name | Type | Value | Proxied | 메모 |
|
||||
|---|---|---|---|---|
|
||||
@@ -57,28 +54,28 @@ tags: [infra, cloudflare, cdn, dns]
|
||||
| `jp.inouter.com` | A | `42.125.196.116` | off | jp1 |
|
||||
| `derp.inouter.com` | A | `42.125.196.116` | off | jp1 derp |
|
||||
| `gitea.inouter.com` | CNAME | `iron-git.b-cdn.net` | off | 별도 풀존 (미들웨어 우회) |
|
||||
| `n8n.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off |
|
||||
| `jarvis.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off |
|
||||
| `vault.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off |
|
||||
| `outline.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off |
|
||||
| `telegram-webhook.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off |
|
||||
| `n8n.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off | |
|
||||
| `jarvis.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off | |
|
||||
| `vault.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off | |
|
||||
| `outline.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off | |
|
||||
| `telegram-webhook.inouter.com` | CNAME | `iron-kr.b-cdn.net` | off | |
|
||||
| `desk-api.inouter.com` | A | `172.233.93.180` | ✅ | osaka 직통, CF proxied |
|
||||
| `sftp.inouter.com` | A | `220.120.65.245` | ✅ | OpenWrt 직통, CF proxied |
|
||||
| `git.inouter.com` | A | `52.79.45.166` | off | relay4wd Lightsail |
|
||||
| `teleport.inouter.com` | A | `52.79.45.166` | off | relay4wd Lightsail |
|
||||
| `twilio.jp.inouter.com` | A | `172.233.93.180` | off |
|
||||
| `bunny.mcp.inouter.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `twilio.jp.inouter.com` | A | `172.233.93.180` | off | |
|
||||
| `bunny.mcp.inouter.com` | CNAME | `k3s.inouter.com` | off | |
|
||||
| `vl.inouter.com` | CNAME | `k3s.inouter.com` | off | [[victorialogs|VictoriaLogs]] |
|
||||
| `emulator.api.inouter.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `linode.api.inouter.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `namecheap.api.inouter.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `vultr.api.inouter.com` | CNAME | `k3s.inouter.com` | off |
|
||||
| `email.inouter.com` | CNAME | `mailgun.org` | off |
|
||||
| MX×2 Mailgun, TXT (SPF/DMARC/DKIM/google verification) | | | |
|
||||
| `emulator.api.inouter.com` | CNAME | `k3s.inouter.com` | off | |
|
||||
| `linode.api.inouter.com` | CNAME | `k3s.inouter.com` | off | |
|
||||
| `namecheap.api.inouter.com` | CNAME | `k3s.inouter.com` | off | |
|
||||
| `vultr.api.inouter.com` | CNAME | `k3s.inouter.com` | off | |
|
||||
| `email.inouter.com` | CNAME | `mailgun.org` | off | |
|
||||
| MX×2 Mailgun, TXT (SPF/DMARC/DKIM/google verification) | | | | |
|
||||
|
||||
> **이전 메모(updated 2026-04-04)는 폐기**: jarvis/telegram-webhook/vault/n8n 이 `actions.b-cdn.net` 가리킨다는 기록은 dead 풀존을 가리키는 구식 정보. 실제 정본은 위 표와 같이 모두 `iron-kr.b-cdn.net`.
|
||||
`nas.inouter.com` 은 특정 A/CNAME 레코드 없음. `*.inouter.com` 와일드카드 폴백으로 `192.168.9.53` (LAN MetalLB VIP) 로 해석되어 K3s `lan-proxies/nas` IngressRoute 를 통해 Synology DSM (`192.168.9.100:5000`) 으로 reverse proxy. 상세 [[nas-storage#DSM Reverse Proxy — `nas.inouter.com`]].
|
||||
|
||||
### ironclad.it.com (14)
|
||||
### ironclad.it.com
|
||||
|
||||
| Name | Type | Value | Proxied |
|
||||
|---|---|---|---|
|
||||
@@ -86,9 +83,9 @@ tags: [infra, cloudflare, cdn, dns]
|
||||
| `*.ironclad.it.com` | A | `172.233.93.180` | ✅ |
|
||||
| MX×2 Mailgun, AWS SES DKIM CNAME×3, TXT (SPF/DMARC/google) | | | |
|
||||
|
||||
> ironclad.it.com 은 **BunnyCDN 풀존을 거치지 않음**. CF proxied A 로 osaka 172.233.93.180 직통. 보호는 CF Worker (`ironclad-site` apex + bouncer wildcard) 단독.
|
||||
ironclad.it.com 은 **BunnyCDN 풀존을 거치지 않음**. CF proxied A 로 osaka `172.233.93.180` 직통. 보호는 CF Worker (`ironclad-site` apex + bouncer wildcard) 단독.
|
||||
|
||||
### keepanker.cv (3)
|
||||
### keepanker.cv
|
||||
|
||||
| Name | Type | Value | Proxied |
|
||||
|---|---|---|---|
|
||||
@@ -96,143 +93,97 @@ tags: [infra, cloudflare, cdn, dns]
|
||||
| `*.keepanker.cv` | CNAME | `f1aa79f2-….cfargotunnel.com` | ✅ |
|
||||
| `juiceshop.keepanker.cv` | CNAME | `iron-kr-waf.b-cdn.net` | off |
|
||||
|
||||
apex/wildcard 는 Cloudflare Tunnel (cfargotunnel). juiceshop 은 BunnyCDN iron-kr-waf 로 override.
|
||||
apex/wildcard 는 Cloudflare Tunnel. juiceshop 은 BunnyCDN iron-kr-waf 로 override.
|
||||
|
||||
### servidor.it.com (0)
|
||||
### servidor.it.com
|
||||
|
||||
DNS 레코드 **없음**. zone 만 등록. 워커 라우트 + Turnstile 위젯은 살아있음 → 트래픽 자체가 불가능한데 보안 자원만 회전 중. zone 정리 또는 DNS 레코드 추가 결정 필요.
|
||||
DNS 레코드 없음. zone 만 등록. 워커 라우트 + Turnstile 위젯 + cert-manager wildcard cert 는 세팅되어 있으며 배포 준비 상태로 유지.
|
||||
|
||||
## Workers (9개)
|
||||
## Workers
|
||||
|
||||
| Worker | 라우트 부착 zones | 비고 |
|
||||
|---|---|---|
|
||||
| **crowdsec-cloudflare-worker-bouncer** | actions, anvil, inouter, ironclad, keepanker, servidor (전 6 zone) | CrowdSec CF bouncer 본체. cs-cf-worker-bouncer (jp1) 가 168h 마다 secret rotate. 정본 [[crowdsec-safeline]] |
|
||||
| **crowdsec-cloudflare-worker-bouncer** | actions, ironclad, keepanker, servidor | CrowdSec CF bouncer 본체. cs-cf-worker-bouncer (jp1) 가 168h 마다 secret rotate. 정본 [[crowdsec-safeline]] |
|
||||
| **ironclad-site** | ironclad.it.com (apex) | 정적 사이트, has_assets |
|
||||
| **cf-multisite** | `*.actions.it.com/*` | 라우팅 워커 |
|
||||
| chat-worker | (없음) | workers.dev only |
|
||||
| cloud-instances-api | (없음) | 〃 |
|
||||
| cloud-orchestrator | (없음) | 〃 |
|
||||
| telegram-ai-support | (없음) | 〃 |
|
||||
| telegram-cli-web | (없음) | 〃 |
|
||||
| telegram-summary-bot | (없음) | 〃 |
|
||||
| cloud-instances-api | (없음) | workers.dev only |
|
||||
| cloud-orchestrator | (없음) | workers.dev only |
|
||||
| telegram-ai-support | (없음) | workers.dev only |
|
||||
| telegram-cli-web | (없음) | workers.dev only |
|
||||
| telegram-summary-bot | (없음) | workers.dev only |
|
||||
|
||||
### Worker 라우트 (zone 별, 2026-04-10 cf-audit-cleanup-2 후)
|
||||
### Worker 라우트 (zone 별)
|
||||
|
||||
| Zone | Pattern | Script |
|
||||
|---|---|---|
|
||||
| actions.it.com | `*actions.it.com/*` | crowdsec-cloudflare-worker-bouncer |
|
||||
| actions.it.com | `*.actions.it.com/*` | cf-multisite |
|
||||
| actions.it.com | `vultr.actions.it.com/*` | **null** ⚠ orphan |
|
||||
| actions.it.com | `linode.actions.it.com/*` | **null** ⚠ orphan |
|
||||
| actions.it.com | `vultr.actions.it.com/*` | null (orphan, 미정리) |
|
||||
| actions.it.com | `linode.actions.it.com/*` | null (orphan, 미정리) |
|
||||
| ironclad.it.com | `ironclad.it.com/*` | ironclad-site |
|
||||
| ironclad.it.com | `*ironclad.it.com/*` | crowdsec-cloudflare-worker-bouncer |
|
||||
| keepanker.cv | `*keepanker.cv/*` | crowdsec-cloudflare-worker-bouncer |
|
||||
| servidor.it.com | `*servidor.it.com/*` | crowdsec-cloudflare-worker-bouncer |
|
||||
|
||||
**2026-04-10 삭제 (cf-audit-cleanup-2)**:
|
||||
- ~~`*inouter.com/*`~~ (inouter.com zone, crowdsec-cloudflare-worker-bouncer) — DNS proxied=false 라 enforce 안 됐음
|
||||
- ~~`*anvil.it.com/*`~~ (anvil.it.com zone, 동일)
|
||||
inouter.com / anvil.it.com 에는 Worker 라우트 없음. DNS proxied=false 라 CF 엣지를 거치지 않으므로 enforce 불가 — 이들 zone 의 엣지 보호는 BunnyCDN 미들웨어 64811 이 단독 책임.
|
||||
|
||||
이 두 라우트는 cs-cf-worker-bouncer 의 zone 제거 사이클에 의해 자동 삭제됨 (CF API 직접 호출 불필요했음).
|
||||
Worker Custom Domains (계정 레벨): 0건.
|
||||
|
||||
> Worker Custom Domains (계정 레벨): **0건**.
|
||||
|
||||
## Turnstile 위젯 (현재 6개, 2026-04-10 cf-audit-cleanup-2 후)
|
||||
## Turnstile 위젯
|
||||
|
||||
| Sitekey | 이름 | mode | 도메인 | 역할 |
|
||||
|---|---|---|---|---|
|
||||
| `0x4AAAAAABvmO8BKc1ss5d-S` | `crowdsec-captcha` | managed | actions / anvil / charon.my / ironclad / keepanker / n8n.my / servidor / subin.my | multi-domain 운영용 (8 도메인). 2025-08-29 생성. bouncer 관리 외 |
|
||||
| `0x4AAAAAACbmaudAjITah7y7` | `inouter` | managed | anvil.it.com **만** | 2026-02-13 생성. 이름과 도메인 불일치 → legacy/orphan 후보. 별건 결정 미정 (kappa) |
|
||||
| **`0x4AAAAAAC3otPWhldI96Aks`** | **`inouter-bunny-middleware`** | managed | inouter.com | **2026-04-10 신규** (cf-audit-cleanup-2 복구). **BunnyCDN 미들웨어 64811 이 TURNSTILE_SITE_KEY/SECRET_KEY env 로 baked-in 사용**. 이름이 bouncer 패턴 (`crowdsec-cloudflare-worker-bouncer-widget`) 과 다르므로 cs-cf-worker-bouncer 가 관리 대상에 넣지 않음 → freeze. **수동 관리** |
|
||||
| `0x4AAAAAAC3nIMLBRKWfiY8A` | `crowdsec-cloudflare-worker-bouncer-widget` | managed | actions.it.com | bouncer 자동 (168h rotation), 2026-04-10 00:23 재생성 (이전 sitekey `…2cn8bzKBex_ihU` 폐기) |
|
||||
| `0x4AAAAAAC3nIYV_A5OA0Xzv` | 〃 | managed | ironclad.it.com | bouncer 자동, 2026-04-10 00:23 재생성 (이전 `…2coU0PB8O8oJqY` 폐기) |
|
||||
| `0x4AAAAAAC3nHnAB6Q9dlvHM` | 〃 | managed | keepanker.cv | bouncer 자동, 2026-04-10 00:23 재생성 (이전 `…2coNrK9rRq7S_b` 폐기) |
|
||||
| `0x4AAAAAAC3nH0xXSU8kbwsn` | 〃 | managed | servidor.it.com | bouncer 자동, 2026-04-10 00:23 재생성 (이전 `…2cnZzIyNRayTcG` 폐기) |
|
||||
| `0x4AAAAAABvmO8BKc1ss5d-S` | `crowdsec-captcha` | managed | actions / anvil / charon.my / ironclad / keepanker / n8n.my / servidor / subin.my | multi-domain 운영용 (8 도메인). 수동 관리 (bouncer 외) |
|
||||
| `0x4AAAAAACbmaudAjITah7y7` | `inouter` | managed | anvil.it.com | 이름·도메인 불일치 (legacy/orphan 후보, 결정 미정) |
|
||||
| `0x4AAAAAAC3otPWhldI96Aks` | `inouter-bunny-middleware` | managed | inouter.com | BunnyCDN 미들웨어 64811 의 `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` env baked-in. 이름이 bouncer auto 패턴과 달라 cs-cf-worker-bouncer 가 관리 대상 외. **수동 관리**, sitekey/secret 변경 시 미들웨어 64811 env 동시 갱신 필수 |
|
||||
| `0x4AAAAAAC3nIMLBRKWfiY8A` | `crowdsec-cloudflare-worker-bouncer-widget` | managed | actions.it.com | cs-cf-worker-bouncer 자동 (168h rotation). 수동 편집 금지 |
|
||||
| `0x4AAAAAAC3nIYV_A5OA0Xzv` | 〃 | managed | ironclad.it.com | 〃 |
|
||||
| `0x4AAAAAAC3nHnAB6Q9dlvHM` | 〃 | managed | keepanker.cv | 〃 |
|
||||
| `0x4AAAAAAC3nH0xXSU8kbwsn` | 〃 | managed | servidor.it.com | 〃 |
|
||||
|
||||
**2026-04-10 삭제 (cf-audit-cleanup-2)**:
|
||||
- ~~`0x4AAAAAAC2cnEA797HwesRX`~~ (anvil.it.com bouncer-managed) — bouncer 가 zone 제거 시 자동 cleanup
|
||||
- ~~`0x4AAAAAAC2cntUlRC3KKMKG`~~ (inouter.com bouncer-managed) — bouncer 가 zone 제거 시 자동 cleanup. **이로 인해 BunnyCDN 미들웨어 64811 stale 발생 → 수동 신규 위젯 `inouter-bunny-middleware` 로 복구.** 인시던트 doc `8f5c43f8-0b46-4032-b3f6-08106aa1e5e2`
|
||||
`inouter-bunny-middleware` 의 secret 은 Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` (`sitekey`, `secret`, `name`).
|
||||
|
||||
bouncer 자동 위젯 4개 (actions/ironclad/keepanker/servidor) 는 `cs-cf-worker-bouncer` 가 rotate. **수동 편집 금지** — 다음 rotate 때 덮어써짐. `inouter-bunny-middleware` 는 bouncer 관리 밖이라 수동 관리 (sitekey/secret 변경 시 BunnyCDN 미들웨어 64811 env 동시 갱신 필수).
|
||||
### Turnstile 토큰 권한
|
||||
|
||||
### Turnstile 토큰 권한 (2026-04-10 사실)
|
||||
|
||||
- **Vault `secret/cloud/cloudflare` `api_token` (`pUIZdTV0…`)**: DNS R/W + Turnstile **read-only**. 위젯 생성/수정/삭제 불가.
|
||||
- **cs-cf-worker-bouncer 가 jp1 bouncer 호스트의 `/etc/crowdsec/bouncers/crowdsec-cloudflare-worker-bouncer.yaml` 안에 보유한 별도 CF 토큰** (`token: seUKZID4…`): Turnstile **read+write**. 위젯 생성/수정/삭제 가능. 이 토큰은 bouncer 의 자체 인증 자산이며 Vault 에 복제되어 있지 않음.
|
||||
- **2026-04-10 cf-audit-cleanup-2 복구**: kappa 가 jp1 bouncer 호스트의 위 토큰을 일시 빌려 `inouter-bunny-middleware` 위젯을 직접 API 로 생성. 결과 (sitekey/secret/name) 만 Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` 에 보관. 토큰 본체는 복제 없음.
|
||||
- **Vault `secret/cloud/cloudflare.api_token`** (`pUIZdTV0…`): DNS R/W + Turnstile **read-only**. 위젯 생성/수정/삭제 불가
|
||||
- **jp1 bouncer 호스트의 `/etc/crowdsec/bouncers/crowdsec-cloudflare-worker-bouncer.yaml` 내 `token: seUKZID4…`**: Turnstile **read+write**. bouncer 의 자체 인증 자산이며 Vault 에 복제되어 있지 않음
|
||||
|
||||
## 특이사항
|
||||
|
||||
### Orphan / dead 자원
|
||||
- **`*.actions.it.com → actions.b-cdn.net`** — 와일드카드가 dead 풀존 가리킴. 일부 서브가 5xx 가능. 미정리 (영향 평가 후 별건)
|
||||
- **Worker routes `vultr.actions.it.com/*`, `linode.actions.it.com/*`** — `script: null` orphan. 미정리
|
||||
- **Turnstile `inouter` (`…CbmaudAjITah7y7`)** — 이름·도메인 불일치 legacy 후보. 미정리
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| **servidor.it.com zone** | DNS 레코드 0건. 워커 라우트 + Turnstile 위젯만 살아있음. 2026-04-10 kappa 판정 "죽은 도메인 아님" → **유지**. |
|
||||
| ~~`nas.inouter.com → actions.b-cdn.net`~~ | **2026-04-10 삭제 완료** (cf-audit-cleanup-1). dead 풀존 참조였고 Synology 는 LAN 전용. → 같은 날 Heimdall 이 K3s `lan-proxies/nas` (Traefik IngressRoute) 로 LAN-only 복원, `*.inouter.com → k3s.inouter.com (192.168.9.53)` 폴백 활용. 상세 [[nas-storage#DSM Reverse Proxy — `nas.inouter.com` (2026-04-10)]] |
|
||||
| **`*.actions.it.com → actions.b-cdn.net`** | 와일드카드 자체가 dead 풀존 가리킴. proxied=on 이라 CF 가 어디로 보내는지 의문. 일부 서브가 5xx 가능. **미정리** (영향 평가 후 별건). |
|
||||
| **Worker route `vultr.actions.it.com/*`, `linode.actions.it.com/*`** | `script: null`. 등록만 되고 워커 미연결. (linode.actions.it.com 자체는 BunnyCDN iron-jp 호스트네임으로도 있음 — 중복 의도?) **미정리**. |
|
||||
| **Turnstile `inouter` (sitekey `…CbmaudAjITah7y7`)** | 이름은 inouter 인데 허용 도메인은 anvil.it.com 단일. legacy 후보. **미정리** (CF 토큰 read-only 라 대시보드 수동 필요). |
|
||||
### CF proxy on/off 패턴
|
||||
|
||||
### 사설 IP 공개 DNS 노출 — 2026-04-10 정리 완료
|
||||
|
||||
| 레코드 | 값 | 상태 |
|
||||
| Zone | Proxy | 보호 |
|
||||
|---|---|---|
|
||||
| ~~`ironclad.jp.inouter.com`~~ | ~~A `10.19.228.193`~~ | **2026-04-10 삭제** (cf-audit-cleanup-1) |
|
||||
| ~~`k8s.jp.inouter.com`~~ | ~~A `10.253.103.124`~~ | **2026-04-10 삭제** (cf-audit-cleanup-1) |
|
||||
|
||||
향후 사설 IP 가 필요하면 Tailscale Magic DNS 또는 split-horizon (예: jp.inouter.com 내부 zone) 으로 처리.
|
||||
|
||||
### CF proxy on/off 패턴 (중요)
|
||||
|
||||
- **inouter.com / anvil.it.com**: 거의 전부 `proxied: false` — CF 는 DNS 만, 트래픽은 BunnyCDN 또는 LAN 직통. **2026-04-10 cf-audit-cleanup-2 에서 두 zone 의 CF Worker bouncer 라우트 + bouncer 관리 zone 항목 모두 제거**. 보호는 BunnyCDN 미들웨어 64811 이 단독 책임.
|
||||
- **actions.it.com / ironclad.it.com**: apex/wildcard 모두 `proxied: true` — CF Worker 효과적으로 enforce.
|
||||
- **keepanker.cv**: CF Tunnel.
|
||||
|
||||
### 정책 일관성
|
||||
|
||||
- iron-kr `IgnoreQueryStrings: true` vs iron-jp `IgnoreQueryStrings: false` — 같은 미들웨어 64811 공유인데 캐시 키 정책이 다름. iron-jp 트래픽이 미미해 영향 작지만 통일이 운영 단순화.
|
||||
| inouter.com / anvil.it.com | off | BunnyCDN 미들웨어 64811 단독 |
|
||||
| actions.it.com / ironclad.it.com | on | CF Worker (bouncer + cf-multisite / ironclad-site) |
|
||||
| keepanker.cv | on (Tunnel) | CF Tunnel + juiceshop 만 iron-kr-waf override |
|
||||
|
||||
## cfb-manager (CrowdSec CF Worker bouncer 관리 API)
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 위치 | K3s `default/cfb-manager` (10.43.68.76:8000) |
|
||||
| 위치 | K3s `default/cfb-manager` (`10.43.68.76:8000`) |
|
||||
| 구현 | Python FastAPI |
|
||||
| 기능 | bouncer 보호 도메인 추가/삭제, decision 조회, CF zone 동기화, bouncer 재시작 트리거 |
|
||||
| SSH 키 | K8s `default/cfb-ssh-key` 시크릿 (ed25519, 2026-04-09 재생성) |
|
||||
| SSH 키 | K8s `default/cfb-ssh-key` (ed25519) |
|
||||
|
||||
```bash
|
||||
BASE=http://cfb-manager.default.svc.cluster.local:8000
|
||||
curl $BASE/status # bouncer_running, pids, protected_domains
|
||||
curl $BASE/domains # 보호 중인 zone 상세
|
||||
curl $BASE/decisions # 현재 결정
|
||||
curl -X POST $BASE/sync?auto_apply=true # CF 의 모든 zone 을 보호 목록 동기화
|
||||
curl -X POST $BASE/domains/<zone> # zone 추가
|
||||
curl -X DELETE $BASE/domains/<zone> # zone 제거 (destructive — bouncer restart + widget rotate)
|
||||
```
|
||||
|
||||
> **BunnyCDN 미들웨어와는 무관**. BunnyCDN 미들웨어 64811 의 bloom filter 동기화는 jp1 `infra-tool` 컨테이너 `/opt/crowdsec-bouncer/bouncer.py` (3분 delta + 매시 full sync) 가 담당.
|
||||
**중요**: `DELETE /domains/<zone>` 는 단순 config 항목 제거가 아니라 bouncer restart 를 트리거하며, restart 가 모든 zone 의 widget 을 force-rotate 하고 제거된 zone 의 widget 을 destroy 한다. 외부에서 baked-in 으로 사용 중인 sitekey 가 있다면 동시에 깨진다.
|
||||
|
||||
## 인시던트 이력
|
||||
|
||||
### 2026-04-10 cf-audit-cleanup-2 — destructive widget cleanup + 복구
|
||||
|
||||
- 의도: cs-cf-worker-bouncer 의 managed zones 에서 inouter.com, anvil.it.com 제거 (DNS proxied=false 라 enforce 안 되는 dead route 정리)
|
||||
- 잘못된 가정: zone 제거 시 위젯이 freeze 된 채 남는다
|
||||
- 실제 동작: 다음 bouncer restart 가 모든 zone 의 bouncer-managed widget 을 새 sitekey 로 rotation 하면서, config 에서 빠진 zone 의 옛 widget 은 destroy. **BunnyCDN 미들웨어 64811 이 baked-in 으로 사용하던 inouter sitekey `…2cntUlRC3KKMKG` 가 삭제되어 stale 발생**
|
||||
- 영향: 잠재 버그. 현재 ban 없으면 미발현, 첫 inouter.com 호스트 ban 시 캡차 페이지 로드 실패
|
||||
- 복구: kappa 가 jp1 bouncer 호스트의 cs-cf-worker-bouncer 토큰을 일시 빌려 신규 위젯 `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`) 생성. 이름이 bouncer 패턴과 다르므로 향후 rotation 영향 없음. Syn 이 BunnyCDN 미들웨어 64811 의 `TURNSTILE_SITE_KEY/SECRET_KEY` env 갱신 + publish (deployment `3816dbc5-…`)
|
||||
- 부수: cfb-manager YAML 두 번째 DELETE 호출 시 파싱 깨짐 (anvil zone_id 라인 12-space orphan indent), 003003 자동 백업과 002237 API 백업 보유. 직접 수동 수리 (orphan 22 라인 제거) 후 `wc -l 79` 확인, restart 없이 정상 복구
|
||||
- 학습: 보안/엣지 리소스 cleanup 경로는 destructive 가능성을 디폴트로 가정. 1개 항목 dry-run 후 부작용 0 확인 후 다음 진행
|
||||
- 정본: 인시던트 doc `8f5c43f8-0b46-4032-b3f6-08106aa1e5e2`, recovery 절차 동 doc `## 복구 완료` 섹션
|
||||
|
||||
## 참조
|
||||
|
||||
- 전수 감사 정본 (대화 로그): Outline `agent-qna` doc `51b963c3-b251-48b5-a57a-a2305959c470` (2026-04-10)
|
||||
- cf-audit-cleanup-2 인시던트: Outline `agent-qna` doc `8f5c43f8-0b46-4032-b3f6-08106aa1e5e2` (2026-04-10)
|
||||
- 워크스페이스 런북: `~/syn/cloudflare/README.md`
|
||||
- BunnyCDN 매핑: [[bunnycdn-security]]
|
||||
- CrowdSec/Worker bouncer: [[crowdsec-safeline]]
|
||||
- 별도 계정: [[netbis]] (Netbis 계정 6 zone, 별도 cs-cf-worker-bouncer)
|
||||
- DNS 프리셋: cloudflare, aws, google, github, bunnycdn
|
||||
BunnyCDN 미들웨어와는 무관. BunnyCDN 미들웨어 64811 의 bloom filter 동기화는 jp1 `infra-tool` 컨테이너 `/opt/crowdsec-bouncer/bouncer.py` (3분 delta + 매시 full sync) 가 담당.
|
||||
|
||||
## 관련 문서
|
||||
|
||||
@@ -240,3 +191,4 @@ curl -X POST $BASE/sync?auto_apply=true # CF 의 모든 zone 을 보호 목록
|
||||
- [[cf-multisite]] — `*.actions.it.com` 라우팅 워커
|
||||
- [[crowdsec-safeline]] — CrowdSec CF Worker Bouncer 연동
|
||||
- [[bunnycdn-security]] — BunnyCDN 엣지 보안
|
||||
- [[nas-storage]] — Synology NAS + `nas.inouter.com` reverse proxy
|
||||
|
||||
@@ -160,10 +160,9 @@ ddos-detect AI 분석기 폐기 후 deterministic 패턴 매칭으로 대체.
|
||||
- `499-burst`: 모바일 클라이언트 끊김으로 정상 발생할 수 있어 30 임계값을 며칠 관찰 후 조정 권장.
|
||||
- `high-rate-per-ip`: APISIX `limit-req` 글로벌 룰(20 req/s burst 10)을 통과한 트래픽만 도달 → 1차 통과 후 sustained pattern을 잡는 2차 layer.
|
||||
- 현재 모두 `remediation: true` (즉시 ban). dry-run으로 시작 안 함 — false positive 발생 시 임계값 또는 ban duration 조정.
|
||||
- **2026-04-09 조정**: `high-rate-per-ip` 초기값(capacity 200, leakspeed 300ms) 사용 중 kappa 본인 트래픽이 지속 ≈3.3 req/s 한도를 넘어 오탐 ban 발생 → BunnyCDN 엣지 미들웨어가 캡챠 페이지 반환 → **POST /__captcha/verify 가 BunnyCDN 미들웨어에서 미처리 상태로 origin까지 흘러 404 반환하는 dead-end 버그**와 결합되어 outline/vault/n8n/jarvis/telegram-webhook/actions 전 호스트 접근 불가. 조치: (1) cscli로 ban decision 삭제 + BunnyCDN zone 캐시 퍼지, (2) 시나리오 완화 capacity 200→1000, leakspeed 300ms→100ms (sustained 10 req/s 허용), (3) **BunnyCDN 엣지 스크립트 64811 middleware.ts 수정** — `/__captcha/verify` 라우트를 `isBlocked` 블록 밖으로 끌어올려 bloom filter 업데이트 race와 무관하게 항상 인터셉트하도록 변경. POST는 handleCaptchaVerify, 그 외(method/ip 없음)는 302 to `/`. 소스: [gitea 7da39b2ac](https://gitea.inouter.com/kaffa/crowdsec-bunny-bouncer/commit/7da39b2acb91f5dd65e63b0ec078d37259bb2950).
|
||||
- **2026-04-09 별건**: `cs-cf-worker-bouncer.yaml` line 68-78 (anvil.it.com 블록) 들여쓰기 12칸 오타로 5일간 42,593회 systemd crash loop, Cloudflare Worker KV 동기화 중단. sed로 인덴트 4칸으로 정정, 5일 만에 정상 기동. 별건: K8s `default/cfb-ssh-key` 시크릿의 id_rsa 데이터가 libcrypto parse 실패 상태라 `cfb-manager` → `cs-cf-worker-bouncer` SSH 인증 불가, `/domains` `/status` API가 500 반환. 새 ed25519 키페어 생성·시크릿 교체·authorized_keys 등록·파드 재시작으로 복구.
|
||||
- **2026-04-09 Turnstile sitekey 교체**: BunnyCDN 엣지 스크립트 64811의 `TURNSTILE_SITE_KEY` env 변수가 `0x4AAAAAACbmaudAjITah7y7` (name `inouter`, allowed domain `['anvil.it.com']`)로 설정되어 있어 outline.inouter.com에서 Turnstile 위젯이 "웹 사이트에 연결할 수 없음" 에러. cs-cf-worker-bouncer가 managed 모드로 자동 생성한 `inouter.com` zone 위젯(`0x4AAAAAAC2cntUlRC3KKMKG`, secret `0x4AAAAAAC2cnp9fkaIBt3rixDBalNKfLZQ`)으로 교체. **Turnstile managed 위젯은 zone apex 도메인으로 등록해도 서브도메인을 암묵 허용함**이 확인됨 (outline.inouter.com 정상 동작). 단, iron-kr 풀존에는 `actions.it.com`·`iron-kr.b-cdn.net`도 포함되는데 이들은 inouter.com zone 외부라 캡챠 위젯 로드 불가. iron-jp 풀존(anvil.it.com 등)도 동일 제약. **TODO**: 스크립트를 수정해 `request.hostname`에 따라 zone별 sitekey/secret을 dispatch하거나, CF 대시보드에서 multi-domain 위젯 하나로 통합.
|
||||
- **2026-04-10 cf-audit-cleanup-2 인시던트 (3-incident chain)**: ① Syn 가 cfb-manager API 로 inouter/anvil 를 bouncer 관리에서 제외 시도. cfb-manager 의 DELETE 가 단순 config 항목 제거가 아니라 bouncer restart + destructive widget cleanup 을 트리거 → BunnyCDN 미들웨어 64811 이 baked-in 사용 중이던 inouter Turnstile 위젯 `0x4AAAAAAC2cntUlRC3KKMKG` 가 함께 삭제 (잠재 버그, ban 발동 시 캡차 깨짐). ② kappa 가 jp1 cs-cf-worker-bouncer 의 CF 토큰 (`seUKZID4...`, Turnstile R+W) 을 일시 차용해 새 위젯 `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`) 직접 생성, Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` 보관, Syn 가 미들웨어 64811 env 갱신 + publish. ③ Syn 의 yaml 수동 fix 가 disk 에 반영되지 않아 (또는 반영 직후 원복) bouncer 가 깨진 yaml 로 crashloop, 4개 zone (keepanker/actions/ironclad/servidor) 의 Worker route 와 widget 도 함께 사라져 CF Worker enforcement 다운. 근본 원인: `/etc/cron.d/cf-zone-sync` 의 `auto-add-cf-zones.sh` 가 매 10분마다 CF API 의 zone 목록을 yaml 에 자동 추가하는데 추가 indent 가 12-space 로 잘못되어 yaml 파괴. 복구: kappa 가 cron 파일을 `cf-zone-sync.disabled.kappa-incident-20260410` 로 rename, yaml 을 `bak.20260410004004` 클린 백업으로 복원, bouncer 재기동 → 4개 zone widget/route 자동 재생성 확인. **결론: cfb-manager API 의 DELETE 는 destructive, cf-zone-sync cron 은 exclusion 미지원**. 둘 다 영구 수정 필요. 인시던트 보고서: Outline doc `8f5c43f8-0b46-4032-b3f6-08106aa1e5e2`.
|
||||
|
||||
|
||||
과거 인시던트 및 변경 이력은 `history/` 참조. 예: `history/2026-04-10-edge-cleanup.md` (cf-audit-cleanup-2 3-incident chain, Turnstile sitekey 교체, 미들웨어 64811 `/__captcha/verify` 버그 수정 등).
|
||||
|
||||
### 발견 사항: K3s APISIX 글로벌 limit-req
|
||||
|
||||
@@ -190,10 +189,10 @@ ddos-detect AI 분석기 폐기 후 deterministic 패턴 매칭으로 대체.
|
||||
| 정본 | `gitea.inouter.com/kaffa/k8s` → `configs/crowdsec/crowdsec-cloudflare-worker-bouncer.yaml` |
|
||||
| 동기화 | 10초 (decision stream polling) |
|
||||
| 방식 | LAPI → bouncer → Cloudflare Worker KV (bloom filter) → Worker에서 차단/captcha |
|
||||
| 보호 zone (현재) | keepanker.cv, actions.it.com, ironclad.it.com, servidor.it.com (4 zone, 2026-04-10 cf-audit-cleanup-2 후) |
|
||||
| 제거된 zone | inouter.com, anvil.it.com — DNS `proxied: false` 라 CF 엣지를 거치지 않아 enforce 안 되던 dead route. 보호는 BunnyCDN 미들웨어 64811 단독. 2026-04-10 cfb-manager DELETE + 002323 단계 destructive cleanup → 003943 수동 YAML 수리 → 005203 kappa 긴급 복구 (cron 비활성화 + 백업 복원) |
|
||||
| Turnstile | bouncer-managed 4개 (rotate 168h, 005217 신규 생성: servidor `0x4AAAAAAC3rgjWkt-40fI7d`, actions `0x4AAAAAAC3rg3VTXEllaMhY`, keepanker `0x4AAAAAAC3rhJWcBgQ5aPym`, ironclad `0x4AAAAAAC3rhaCWqBq5Qgza`), + 별도 수동 위젯 `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`) — BunnyCDN 미들웨어 64811 전용, bouncer 관리 외 freeze. [[cloudflare#Turnstile 토큰 권한 (2026-04-10 사실)]] |
|
||||
| **cron `cf-zone-sync` 영구 제거 (2026-04-10)** | 원본 cron 은 매 10분마다 `auto-add-cf-zones.sh` 실행 → CF 의 모든 zone 을 자동으로 yaml 에 추가 (12-space indent bug 로 yaml 파괴, cleanup-2 인시던트 근본 원인). kappa 판단: exclusion 지원 재작성보다 **자동 쓰기 자체를 제거** 가 옳음 (yaml 에 쓰는 주체가 하나여야 coordination 문제 해소). 조치: `/etc/cron.d/cf-zone-sync` 파일 삭제, `/usr/local/bin/auto-add-cf-zones.sh` 는 post-mortem 용 archive (`.disabled.20260410-incident`, chmod 600). `/usr/local/bin/sync-cf-zones.sh` (older, detect-only 버전) 는 cron 미참조 + yaml 편집 없음이라 그대로 유지. `/var/log/cf-zone-sync.log` 는 history 로 유지. 신규 zone 추가 시 = cfb-manager `POST /domains` 또는 수동 yaml edit + systemctl restart |
|
||||
| 보호 zone | keepanker.cv, actions.it.com, ironclad.it.com, servidor.it.com |
|
||||
| 비보호 zone | inouter.com, anvil.it.com — DNS `proxied: false` 라 CF 엣지를 거치지 않아 bouncer 라우트가 enforce 되지 않음. 보호는 BunnyCDN 미들웨어 64811 단독 |
|
||||
| Turnstile 위젯 | 4개 bouncer-managed (`crowdsec-cloudflare-worker-bouncer-widget` 이름, 168h rotation). BunnyCDN 미들웨어용 `inouter-bunny-middleware` 는 별도 수동 관리 — [[cloudflare#Turnstile 위젯]] |
|
||||
| yaml writer | `cfb-manager` 단일 (K8s `default/cfb-manager` REST API). 과거 `/etc/cron.d/cf-zone-sync` + `auto-add-cf-zones.sh` 자동 쓰기는 coordination 문제로 제거됨 — 신규 zone 추가는 `cfb-manager POST /domains` 또는 수동 yaml edit + systemctl restart |
|
||||
|
||||
#### Decision 수동 관리
|
||||
|
||||
@@ -245,7 +244,7 @@ Kappa 계정용 `cs-cf-worker-bouncer`와 별도 컨테이너로 분리 운영.
|
||||
| 방식 | LAPI → Bloom filter → BunnyCDN Edge Script 임베딩 → 퍼블리시 |
|
||||
| Edge Script | ID 64811 (`crowdsec-bouncer-middleware`), FNV-1a bloom filter |
|
||||
| 차단 시 | Cloudflare Turnstile CAPTCHA + LibSQL verified IP 캐싱(4h) |
|
||||
| 적용 풀존 | iron-jp (5555247), iron-kr (5555227) — 두 풀존 모두 `MiddlewareScriptId: 64811` (2026-04-09 실측) |
|
||||
| 적용 풀존 | iron-jp (5555247), iron-kr (5555227) — 두 풀존 모두 `MiddlewareScriptId: 64811` |
|
||||
| API 키 | Vault `secret/infra/crowdsec-bunny-bouncer` |
|
||||
| 소스 | `~/crowdsec-bunny-bouncer/` |
|
||||
|
||||
|
||||
@@ -156,9 +156,9 @@ kr2의 USB 2.5GbE 어댑터(Realtek RTL8157, 0bda:8157)는 커널 기본 `cdc_nc
|
||||
- Jumbo Frame은 경로 전체(NIC → 스위치 → NIC)가 지원해야 함. 미지원 스위치가 중간에 있으면 프레임 드롭
|
||||
- `ping -M do -s 8972` 로 end-to-end JF 동작 확인 가능
|
||||
|
||||
## DSM Reverse Proxy — `nas.inouter.com` (2026-04-10)
|
||||
## DSM Reverse Proxy — `nas.inouter.com`
|
||||
|
||||
LAN 전용으로 Synology DSM 웹 UI 접근. 2026-04-10 Cloudflare 감사 정리 1차에서 dead 풀존(`actions.b-cdn.net`) 을 가리키던 `nas.inouter.com` CNAME 을 삭제한 뒤, 와일드카드 `*.inouter.com → k3s.inouter.com` (Traefik MetalLB VIP `192.168.9.53`) 로 폴백되도록 두고 K3s 측에 라우트를 신설하여 복원.
|
||||
LAN 전용으로 Synology DSM 웹 UI 접근. `nas.inouter.com` 은 `*.inouter.com` 와일드카드 폴백으로 `k3s.inouter.com (192.168.9.53, Traefik MetalLB VIP)` 로 해석되고, Traefik 에서 이 호스트를 Synology NAS 로 reverse proxy 한다.
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
@@ -237,7 +237,7 @@ spec:
|
||||
secretName: wildcard-inouter-tls
|
||||
```
|
||||
|
||||
### 검증 (heimdall, 2026-04-10)
|
||||
### 동작 검증
|
||||
|
||||
```bash
|
||||
curl -sk --resolve nas.inouter.com:80:192.168.9.53 http://nas.inouter.com/ # → 301 https://nas.inouter.com/
|
||||
|
||||
@@ -4,133 +4,122 @@ updated: 2026-04-10
|
||||
tags: [cdn, bunnycdn, security, crowdsec, edge-script]
|
||||
---
|
||||
|
||||
> 2026-04-10 전수 감사 (Outline `agent-qna` doc `51b963c3-b251-48b5-a57a-a2305959c470`) 결과 반영. 5개 풀존, 17개 호스트네임, 미들웨어 64811 attach 매트릭스를 모두 정본화.
|
||||
|
||||
## 구성
|
||||
|
||||
- 엣지 스크립트: `crowdsec-bouncer-middleware` (ID: 64811, ScriptType=2 Middleware)
|
||||
- **연결된 Pull Zone (2026-04-09 실측)**: **iron-kr (5555227)**, **iron-jp (5555247)** — `MiddlewareScriptId: 64811`. 두 풀존 모두 동일 미들웨어 공유.
|
||||
- 미장착 풀존: iron-git (5584382, gitea.inouter.com), iron-kr-waf (5555224, SafeLine 자체 보호), i-gate (5557897, 미사용)
|
||||
- 관리·동기화: jp1 `infra-tool` 컨테이너 `/opt/crowdsec-bouncer/bouncer.py` (3분 delta + 매시 full sync). cfb-manager 는 **Cloudflare Worker** bouncer 관리이며 BunnyCDN 미들웨어와 무관.
|
||||
- 소스: [[crowdsec-safeline|CrowdSec]] bloom filter (FNV-1a 임베디드 BLOOM_B64) + Cloudflare Turnstile 캡차
|
||||
- 엣지 스크립트: `crowdsec-bouncer-middleware` (ID `64811`, ScriptType `2` Middleware)
|
||||
- 연결된 Pull Zone: **iron-kr (5555227)**, **iron-jp (5555247)** — 둘 다 `MiddlewareScriptId: 64811` 공유
|
||||
- 미장착 풀존: `iron-git` (git smart HTTP 보호 우회, 의도), `iron-kr-waf` (SafeLine 다운스트림), `i-gate` (idle)
|
||||
- bloom filter 동기화: jp1 `infra-tool` 컨테이너의 `/opt/crowdsec-bouncer/bouncer.py` (3분 delta + 매시 full sync)
|
||||
- 소스: [[crowdsec-safeline|CrowdSec]] bloom filter (FNV-1a 임베디드 `BLOOM_B64`) + Cloudflare Turnstile 캡차
|
||||
|
||||
> 옛 메모의 풀존 ID `5316471 (inouter)`, `5330178 (actions)`, `5554681 (waf-kr)` 는 현 계정에 더 이상 존재하지 않음. iron-kr / iron-jp / iron-kr-waf 로 통합·이전됨.
|
||||
`cfb-manager` (K8s `default/cfb-manager`) 는 **Cloudflare Worker bouncer 관리 API** 이며 BunnyCDN 미들웨어 64811 와 무관.
|
||||
|
||||
## 동작 순서
|
||||
|
||||
```
|
||||
요청 → BunnyCDN 엣지
|
||||
1. 국가 차단 (Cdn-RequestCountryCode 헤더)
|
||||
- 차단 시 403 반환
|
||||
1. 국가 차단 (Cdn-RequestCountryCode 헤더 기반)
|
||||
- 차단 국가 → 403 반환
|
||||
2. CrowdSec bloom filter (악성 IP 판별)
|
||||
- bloom filter hit → 캡차 또는 403
|
||||
- cfb-manager가 주기적으로 bloom filter 업데이트
|
||||
- hit → 캡차 또는 403
|
||||
- miss → 통과
|
||||
3. 캡차 (Cloudflare Turnstile)
|
||||
- bloom hit된 IP에게 캡차 제시
|
||||
- bloom hit IP 에게 캡차 제시
|
||||
- 통과 시 4시간 허용 (DB + 쿠키)
|
||||
4. 정상 → Origin으로 전달
|
||||
4. 정상 → Origin 으로 전달
|
||||
```
|
||||
|
||||
## 차단 국가
|
||||
|
||||
US, CA, GB, DE, FR, IT, ES, NL, BE, AT, CH, SE, NO, DK, FI, PL, CZ, PT, IE, RO, HU, BG, HR, SK, SI, LT, LV, EE, LU, MT, CY, GR, IS, UA, RU, BY
|
||||
북미·유럽·구소련 권역:
|
||||
|
||||
(북미 + 유럽 + 구소련)
|
||||
`US, CA, GB, DE, FR, IT, ES, NL, BE, AT, CH, SE, NO, DK, FI, PL, CZ, PT, IE, RO, HU, BG, HR, SK, SI, LT, LV, EE, LU, MT, CY, GR, IS, UA, RU, BY`
|
||||
|
||||
## 주의사항
|
||||
|
||||
- **BunnyCDN Traffic Manager 국가 차단은 사용하지 않음** — Let's Encrypt 검증 및 Origin Shield fetch를 막아서 Free SSL 발급 실패 + 500 에러 유발
|
||||
- 엣지 스크립트의 국가 차단은 `Cdn-RequestCountryCode` 헤더 기반 → CDN 내부 요청(Let's Encrypt, Origin Shield)에는 이 헤더가 없으므로 영향 없음
|
||||
- **BunnyCDN Traffic Manager 국가 차단은 사용하지 않음** — Let's Encrypt 검증 및 Origin Shield fetch 를 막아서 Free SSL 발급 실패 + 500 에러 유발
|
||||
- 엣지 스크립트의 국가 차단은 `Cdn-RequestCountryCode` 헤더 기반 → CDN 내부 요청 (Let's Encrypt, Origin Shield) 에는 이 헤더가 없으므로 영향 없음
|
||||
- Free SSL 자동 발급/갱신 정상 동작
|
||||
|
||||
## Pull Zone 전수 (2026-04-10)
|
||||
## Pull Zone
|
||||
|
||||
| ID | 이름 | OriginUrl | Middleware | Smart Cache | IgnoreQS | BlockNoRef | 비고 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 5555227 | **iron-kr** | `https://220.120.65.245` | **64811** | ✅ | false | true | 메인 inouter.com 계열. 2026-04-10 `IgnoreQueryStrings` `true→false` (iron-jp 와 통일, privilege 교차 / 배포 cache-bust 버그 방지) |
|
||||
| 5555247 | **iron-jp** | `https://172.233.93.180` | **64811** | ✅ | **false** ⚠ | true | anvil.it.com 계열 |
|
||||
| 5555224 | iron-kr-waf | `https://220.120.65.245:9443` | null | ❌ | true | true | SafeLine WAF 다운스트림 보호 |
|
||||
| 5584382 | iron-git | `https://220.120.65.245` | null | ❌ | true | **false** ⚠ | git smart HTTP 보호 우회 (의도) |
|
||||
| 5557897 | i-gate | `https://172.233.93.180` | null | ❌ | true | true | idle 슬롯, 0 byte |
|
||||
| 5555227 | `iron-kr` | `https://220.120.65.245` | 64811 | ✅ | false | true | 메인 inouter.com 계열 |
|
||||
| 5555247 | `iron-jp` | `https://172.233.93.180` | 64811 | ✅ | false | true | anvil.it.com 계열 |
|
||||
| 5555224 | `iron-kr-waf` | `https://220.120.65.245:9443` | null | ❌ | true | true | SafeLine WAF 다운스트림 보호 |
|
||||
| 5584382 | `iron-git` | `https://220.120.65.245` | null | ❌ | true | false | git smart HTTP 보호 우회 (의도) |
|
||||
| 5557897 | `i-gate` | `https://172.233.93.180` | null | ❌ | true | true | idle 슬롯 |
|
||||
|
||||
공통: `EnableLogging: true`, `EnableWebSockets: true (max 500)`, `EnableGeoZone*: true (전 지역)`, `BlockedCountries: []`, `BlockedIps: []`, `EdgeRules: []` (Edge Rules 미사용 — 모든 분기는 미들웨어 코드 안), `OriginType: 0 (URL)`, `VerifyOriginSSL: false`, `EnableOriginShield: false`. `OptimizerEnabled`: iron-kr / iron-jp 만 true.
|
||||
공통 설정: `EnableLogging: true`, `EnableWebSockets: true (max 500)`, `EnableGeoZone*: true (전 지역)`, `BlockedCountries: []`, `BlockedIps: []`, `EdgeRules: []` (모든 분기는 미들웨어 코드 안에서), `OriginType: 0 (URL)`, `VerifyOriginSSL: false`, `EnableOriginShield: false`. `OptimizerEnabled` 는 `iron-kr` / `iron-jp` 만 `true`.
|
||||
|
||||
## 호스트네임 인벤토리 (17개)
|
||||
## 호스트네임 인벤토리
|
||||
|
||||
| Pull Zone | Hostname | 시스템? | TLS | ForceSSL |
|
||||
|---|---|---|---|---|
|
||||
| iron-kr | `iron-kr.b-cdn.net` | ✅ | ✅ | false |
|
||||
| iron-kr | `actions.it.com` | — | ✅ | false |
|
||||
| iron-kr | `n8n.inouter.com` | — | ✅ | false |
|
||||
| iron-kr | `jarvis.inouter.com` | — | ✅ | false |
|
||||
| iron-kr | `telegram-webhook.inouter.com` | — | ✅ | false |
|
||||
| iron-kr | `vault.inouter.com` | — | ✅ | false |
|
||||
| iron-kr | `outline.inouter.com` | — | ✅ | false |
|
||||
| iron-jp | `iron-jp.b-cdn.net` | ✅ | ✅ | false |
|
||||
| iron-jp | `anvil.it.com` | — | ✅ | false |
|
||||
| iron-jp | `n8n.anvil.it.com` | — | ✅ | false |
|
||||
| iron-jp | `tg.anvil.it.com` | — | ✅ | false |
|
||||
| iron-jp | `linode.actions.it.com` | — | ✅ | false |
|
||||
| iron-kr-waf | `iron-kr-waf.b-cdn.net` | ✅ | ✅ | false |
|
||||
| iron-kr-waf | `juiceshop.keepanker.cv` | — | ✅ | false |
|
||||
| iron-git | `iron-git.b-cdn.net` | ✅ | ✅ | false |
|
||||
| iron-git | `gitea.inouter.com` | — | ✅ | false |
|
||||
| i-gate | `i-gate.b-cdn.net` | ✅ | ✅ | false |
|
||||
| Pull Zone | Hostname | 시스템? |
|
||||
|---|---|---|
|
||||
| iron-kr | `iron-kr.b-cdn.net` | ✅ |
|
||||
| iron-kr | `actions.it.com` | |
|
||||
| iron-kr | `n8n.inouter.com` | |
|
||||
| iron-kr | `jarvis.inouter.com` | |
|
||||
| iron-kr | `telegram-webhook.inouter.com` | |
|
||||
| iron-kr | `vault.inouter.com` | |
|
||||
| iron-kr | `outline.inouter.com` | |
|
||||
| iron-jp | `iron-jp.b-cdn.net` | ✅ |
|
||||
| iron-jp | `anvil.it.com` | |
|
||||
| iron-jp | `n8n.anvil.it.com` | |
|
||||
| iron-jp | `tg.anvil.it.com` | |
|
||||
| iron-jp | `linode.actions.it.com` | |
|
||||
| iron-kr-waf | `iron-kr-waf.b-cdn.net` | ✅ |
|
||||
| iron-kr-waf | `juiceshop.keepanker.cv` | |
|
||||
| iron-git | `iron-git.b-cdn.net` | ✅ |
|
||||
| iron-git | `gitea.inouter.com` | |
|
||||
| i-gate | `i-gate.b-cdn.net` | ✅ |
|
||||
|
||||
**합계**: 사용자 호스트 12 + 시스템 호스트 5 = 17. 모두 `HasCertificate: true` (Let's Encrypt 자동 발급/갱신). Bunny API 의 list/get 응답에는 인증서 만료일이 노출되지 않음 → 만료 임박 모니터링은 능동 외부 cert 체크 또는 Bunny 대시보드 알림에 의존.
|
||||
총 17 (사용자 12 + 시스템 5). 전부 `HasCertificate: true` (Let's Encrypt 자동 발급/갱신). Bunny API 응답에는 인증서 만료일이 노출되지 않아 만료 모니터링은 외부 cert 체크 또는 Bunny 대시보드 알림에 의존.
|
||||
|
||||
## Edge Script / Middleware attach 매트릭스
|
||||
## Edge Script / Middleware attach
|
||||
|
||||
| Script ID | 이름 | Type | Attached pullzones | 비고 |
|
||||
|---|---|---|---|---|
|
||||
| **64811** | `crowdsec-bouncer-middleware` | 2 (Middleware) | iron-kr (5555227), iron-jp (5555247) | 두 풀존 동일 미들웨어 공유 |
|
||||
| (none) | — | — | iron-kr-waf, iron-git, i-gate | iron-git 의도적 우회 (git pack 바이너리 보호 불가), iron-kr-waf 는 다운스트림 SafeLine, i-gate idle |
|
||||
| Script ID | 이름 | Type | 부착 풀존 |
|
||||
|---|---|---|---|
|
||||
| 64811 | `crowdsec-bouncer-middleware` | 2 (Middleware) | iron-kr, iron-jp |
|
||||
|
||||
## CrowdSec Bouncer 동기화 구조
|
||||
기타 풀존 미장착 사유: `iron-git` 은 git smart HTTP 바이너리 보호 불가라 의도적 우회, `iron-kr-waf` 는 SafeLine 이 담당, `i-gate` 는 idle.
|
||||
|
||||
## CrowdSec bloom filter 동기화
|
||||
|
||||
```
|
||||
CrowdSec LAPI (jp1 Incus, 10.253.100.240:8080) → 악성 IP decision
|
||||
CrowdSec LAPI (jp1, 10.253.100.240:8080) → decision stream
|
||||
↓
|
||||
infra-tool 컨테이너 (jp1) /opt/crowdsec-bouncer/bouncer.py
|
||||
infra-tool 컨테이너 /opt/crowdsec-bouncer/bouncer.py
|
||||
├ 3분 delta sync
|
||||
└ 매시 full sync
|
||||
↓
|
||||
bloom filter (FNV-1a) base64 → BunnyCDN compute API
|
||||
→ Edge Script 64811 코드의 BLOOM_B64/BLOOM_VERSION 상수 정규식 교체
|
||||
→ Edge Script 64811 코드의 BLOOM_B64 / BLOOM_VERSION 상수 정규식 교체
|
||||
→ publish
|
||||
↓
|
||||
엣지 스크립트가 요청마다 client IP 를 bloom filter 로 체크
|
||||
→ hit → Turnstile 캡차 (verified 4h 쿠키)
|
||||
→ miss → origin 통과
|
||||
hit → Turnstile 캡차 (verified 4h 쿠키)
|
||||
miss → origin 통과
|
||||
```
|
||||
|
||||
> **주의**: `cfb-manager` (K8s `default/cfb-manager`) 는 **Cloudflare Worker bouncer 관리 API** 이며 BunnyCDN 미들웨어 64811 와는 무관. 옛 메모 혼동 정정.
|
||||
## Turnstile sitekey
|
||||
|
||||
## 미들웨어 64811 Turnstile sitekey 이력
|
||||
미들웨어 64811 의 `TURNSTILE_SITE_KEY` 와 `TURNSTILE_SECRET_KEY` 는 env 변수로 주입 (코드에 hardcoded 아님). 현재 값은 [[cloudflare#Turnstile 위젯]] 의 `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`). 이 위젯은 cs-cf-worker-bouncer 의 이름 패턴 (`crowdsec-cloudflare-worker-bouncer-widget`) 과 다르므로 bouncer rotation 대상 외 — 수동 관리.
|
||||
|
||||
| 시점 | sitekey | 이름 | 비고 |
|
||||
|---|---|---|---|
|
||||
| ~2026-04-09 | `0x4AAAAAAC2cntUlRC3KKMKG` | `crowdsec-cloudflare-worker-bouncer-widget` (inouter.com) | cs-cf-worker-bouncer 가 자동 발급/rotate. 미들웨어 64811 이 baked-in 사용 |
|
||||
| **2026-04-10** | **삭제됨** | — | cf-audit-cleanup-2 의 cfb-manager DELETE inouter.com 트리거 → bouncer restart 가 destructive cleanup. 미들웨어 stale, 잠재 버그 발생 |
|
||||
| **2026-04-10** | **`0x4AAAAAAC3otPWhldI96Aks`** | **`inouter-bunny-middleware`** | 복구. kappa 가 jp1 bouncer 호스트의 cs-cf-worker-bouncer 토큰을 일시 빌려 직접 API 로 생성. 이름이 bouncer 패턴과 다르므로 freeze. Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` (sitekey/secret/name). Syn 이 미들웨어 64811 env 갱신 + publish (deployment `3816dbc5-…`) |
|
||||
위젯 교체 절차:
|
||||
1. 신규 위젯 생성 (이름에 `bouncer` 포함 금지)
|
||||
2. Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` 에 `sitekey`, `secret`, `name` 저장
|
||||
3. 미들웨어 64811 의 `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` env 두 변수 **동시** 갱신 + publish
|
||||
4. 옛 sitekey 가 미들웨어 env 에 남아있지 않은지 검증 (grep), 옛 위젯 삭제 가능
|
||||
|
||||
> 미들웨어 64811 의 `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` env 변수를 갱신할 때는 반드시 두 변수 모두 동시에 갱신 + publish. 코드 자체에는 sitekey 가 hardcoded 되지 않음 (env 만 참조).
|
||||
## 특이사항
|
||||
|
||||
## 특이사항 (2026-04-10 감사)
|
||||
|
||||
- **i-gate (5557897)**: 시스템 호스트네임 1개만, 0 byte 트래픽. 빈 슬롯 — 제거 또는 명확한 용도 부여 필요.
|
||||
- ~~**iron-kr / iron-jp `IgnoreQueryStrings` 불일치**~~: 2026-04-10 둘 다 `false` 로 통일 완료. iron-kr 의 실측 cache hit rate 가 0.23% 로 사실상 0 이라 변경 영향 무시할 수준. 안전한 기본값 (query string 무시 안 함) 으로 맞춤.
|
||||
- **Turnstile sitekey gap**: 미들웨어 64811 의 `TURNSTILE_SITE_KEY` 는 `inouter-bunny-middleware` (inouter.com zone) 단일 키 → `actions.it.com`, `anvil.it.com`, `*.b-cdn.net` 호스트에서 ban 발동 시 캡챠 위젯 로드 실패 가능. zone별 dispatcher 또는 multi-domain 위젯 통합 TODO.
|
||||
- 옛 메모의 풀존 ID `5316471 (inouter)`, `5330178 (actions)`, `5554681 (waf-kr)` 는 현 계정에 더 이상 존재하지 않음. `*.actions.it.com` Cloudflare DNS 가 아직 `actions.b-cdn.net` 을 가리키는 dead reference 가 남아 있음 — [[cloudflare]] 정리 필요. (`nas.inouter.com` 은 2026-04-10 cf-audit-cleanup-1 에서 정리 완료)
|
||||
|
||||
## 참조
|
||||
|
||||
- 전수 감사 정본 (대화 로그): Outline `agent-qna` doc `51b963c3-b251-48b5-a57a-a2305959c470` (2026-04-10)
|
||||
- 워크스페이스 런북: `~/syn/bunnycdn/README.md`
|
||||
- API 레퍼런스: [[bunnycdn]]
|
||||
- **i-gate (5557897)**: 시스템 호스트 1개, 0 byte 트래픽. 빈 슬롯 — 용도 부여 또는 제거 필요
|
||||
- **Turnstile sitekey zone gap**: `TURNSTILE_SITE_KEY` 가 `inouter.com` zone 단일 키 → `actions.it.com`, `anvil.it.com`, `*.b-cdn.net` 호스트에서 ban 발동 시 캡차 위젯 로드 실패 가능. zone별 dispatcher 또는 multi-domain 위젯 통합 TODO
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [[bunnycdn]] — BunnyCDN API 레퍼런스
|
||||
- [[crowdsec-safeline]] — CrowdSec 및 SafeLine WAF 설정
|
||||
- [[cloudflare]] — Cloudflare DNS/CDN (Turnstile 캡차 키 관리)
|
||||
- [[cloudflare]] — Cloudflare DNS/CDN (Turnstile 위젯 정본)
|
||||
|
||||
Reference in New Issue
Block a user