Crowny Gateway v3.1 고도화
날짜: 2026-05-21
대상: /Users/ef/crowny-gateway
범위: 인증서 갱신 + 무중단 재시작 + 도메인 자동 등록 + 블록체인 앵커링
개요
기존 게이트웨이 v3.0의 약점(인증서 갱신 시 30초 다운타임, 동기 I/O 블로킹, 메모리 누수, 봇 감지 우회) 을 해소하고, nginx/Caddy/Traefik 수준의 무중단 reload + 도메인 자동 등록 + 온체인 감사 추적 기능을 추가했다.
작업 내역 (12개)
Phase 1: 안정성 강화
| # | 파일 | 변경 |
|---|
| 1 | scripts/cert-renew.sh | ERR/INT/TERM/EXIT trap 추가 — certbot 실패 시 LaunchAgent 자동 복구 보장 |
| 2 | lib/ssl.js | _renewAll/getCertStatus/handleChallenge 의 동기 fs.readFileSync → 비동기 fsp.readFile + Promise.all. 헬퍼 _readDomainCert() 추가. 6561 도메인 환경에서 이벤트루프 블로킹 해소 |
| 3 | lib/proxy.js + lib/gateway.js | pruneAgents(activeUpstreams), destroyAllAgents() 신규. _reload()에서 변경된 upstream Agent 자동 destroy. stop()에서 전체 cleanup. FD/메모리 누수 차단 |
| 4 | lib/shield.js | BotDetector cleanup 기준 firstSeen → lastSeen 으로 교체. 3분 간격 재진입으로 누적 플래그 우회하던 버그 차단. flags ≥ 5 IP는 30분 추적 유지. Map 상한 처리 시 전체 keys() 복사 제거 (DDoS GC 부담 해소) |
Phase 2: 무중단 reload
| # | 파일 | 변경 |
|---|
| 5 | bin/cli.js | CROWNY_CLUSTER=2 env로 cluster 모드 opt-in. SIGHUP rolling restart 선결조건 |
| 6 | lib/gateway.js _startPrimary() | SIGHUP 핸들러: 워커 순차 fork → drain → kill. SIGUSR2: 모든 워커에 cert-reload 메시지. Worker 측 drain/cert-reload 메시지 처리 |
| 7 | lib/gateway.js Admin API | POST /reload (rolling 또는 config), POST /certs/reload (인증서 핫리로드). bin/cli.js 에 reload, cert-reload 서브커맨드 추가 |
| 8 | scripts/cert-renew.sh | --standalone 기본 → --webroot -w /Users/ef/crowny-gateway/webroot 로 전환. 게이트웨이 살아있는 동안 certbot 갱신 가능 (다운타임 30초 → 0초). 게이트웨이 응답 없으면 standalone 자동 폴백. 갱신 후 Admin /certs/reload 호출 |
Phase 3: 자동화 + 블록체인
| # | 파일 | 변경 |
|---|
| 9 | lib/domain-registry.js + lib/도메인등록기.한선 | 파이프라인: 검증 → DNS확인 → YAML 백업+추가 → 핫리로드 → cert-renew 트리거. 실패 시 yaml 자동 롤백. unregister() 도 동일 패턴 |
| 10 | lib/chain-anchor.js + lib/체인앵커.한선 | crowny-chain(9729) 에 서비스 변경 이력 앵커링. 체인 오프라인 시 NDJSON 저널 누적 → 60초마다 백그라운드 재생 (at-least-once). 통계: anchored/pending/failed |
| 11 | lib/gateway.js Admin API | POST /services/register, POST /services/unregister, GET /anchor/stats, POST /anchor/replay. 등록 시 자동으로 chain anchor (비동기) |
| 12 | 검증 | 모든 엔드포인트 정상 응답 확인 (포트 8080/8443/9100, 138개 도메인 인증서) |
핵심 개선 지표
| 지표 | Before (v3.0) | After (v3.1) |
|---|
| 인증서 갱신 다운타임 | 30초 | 0초 (webroot 모드) |
| 갱신 실패 시 복구 | 수동 (게이트웨이 죽은 채 방치 위험) | 자동 (trap 보장) |
getCertStatus 6561 도메인 | 동기 → 이벤트루프 블로킹 | 비동기 병렬 |
| Proxy Agent 메모리 | reload마다 누적 | 변경/삭제 시 자동 destroy |
| Bot 감지 우회 | 3분 간격 재진입으로 가능 | lastSeen 기준 → 차단 |
| 도메인 등록 | yaml 수동 편집 + 재시작 | API 한 번 호출 |
| 변경 감사 추적 | 없음 | 온체인 앵커링 |
새 Admin API 엔드포인트
bash# 무중단 reload
curl -X POST http://127.0.0.1:9100/reload # cluster=rolling, single=config
curl -X POST http://127.0.0.1:9100/certs/reload # 인증서만 핫리로드
# 도메인 자동 등록
curl -X POST http://127.0.0.1:9100/services/register \
-H "Content-Type: application/json" \
-d '{"service":{"name":"new-svc","domain":"new.crowny.org","upstream":"http://127.0.0.1:9999"},
"options":{"skipDnsCheck":false}}'
# 도메인 제거
curl -X POST "http://127.0.0.1:9100/services/unregister?name=new-svc"
# 체인 앵커 상태
curl http://127.0.0.1:9100/anchor/stats
curl -X POST http://127.0.0.1:9100/anchor/replay
CLI 명령
bashcrowny-gw reload # 무중단 reload (cluster=rolling, single=config)
crowny-gw cert-reload # 인증서만 핫리로드
CROWNY_CLUSTER=2 crowny-gw start # 2워커 cluster 모드
변경된 파일
/Users/ef/crowny-gateway/
├── bin/cli.js (수정)
├── scripts/cert-renew.sh (재작성 — webroot + trap)
├── lib/
│ ├── gateway.js (수정 — SIGHUP, Admin API, domain-registry/chain-anchor 통합)
│ ├── ssl.js (수정 — 비동기 I/O)
│ ├── proxy.js (수정 — Agent cleanup)
│ ├── shield.js (수정 — BotDetector 버그 수정)
│ ├── domain-registry.js (신규)
│ ├── 도메인등록기.한선 (신규 — 한선씨 동반본)
│ ├── chain-anchor.js (신규)
│ └── 체인앵커.한선 (신규 — 한선씨 동반본)
└── data/anchor-journal.ndjson (자동 생성)
검증 결과
✓ 138개 도메인 인증서 관리 (LE 101 + 자체서명 37)
✓ crowny.org HTTPS — SSL verify 통과
✓ /reload, /certs/reload, /services/register, /anchor/stats 모두 정상
✓ 게이트웨이 재시작 후 모든 포트(8080/8443/9100) 바인딩
다음 단계 (잔여)
- cluster 모드 안정화: 현재 opt-in (
CROWNY_CLUSTER=2). 프로덕션 검증 후 기본 활성화 검토
- hosting.kr API 자동 등록: 현재는 사용자가 hosting.kr에서 A 레코드 수동 추가. API 연동 시 완전 자동화
- 6개 cert 발급 실패 도메인 (artist, bank, jirayer, market, project, real): HTTP-01 챌린지 실패 원인 파악 후 재시도
- 인증서 분할 자동화 개선: 100개 SAN 제한 도달 시 도메인 우선순위 정렬 로직
- 신규 모듈 학습DB 등록: domain-registry, chain-anchor 패턴을 크라우니코드 학습DB에 추가
관련 파일
- 진단 보고서: 3개 서브에이전트 분석 (cert-renew 비교, graceful reload 패턴, 코드 품질 감사)
- 이전 작업:
2026-05-19-gateway-인증서.md (crowny.org 인증서 추가)