개요 — 무엇을 하나
화이트리스트는 InfraGuard의 자동 차단 파이프라인에서 면책(exempt) 할 IP·대역을 관리하는 화면입니다. 여기 등록된 IP/CIDR은 탐지 수집기가 차단을 실행하기 직전에 반드시 확인하는 "면책 명부"가 되어, CDN·파트너 API·사내 회선 같은 신뢰 출발지가 오탐으로 차단되는 사고를 막습니다.
핵심 개념은 만료(expiry) 입니다.
expires_at이 NULL → 영구 면책(만료 없음). CDN·사무실 회선 등 상시 신뢰 대상.expires_at이 날짜 → 임시 면책(그 시각 이후 자동 실효). 짧은 조사 기간, 자동 무죄 판정 등.
면책 항목은 세 가지 소스(source) 로 들어옵니다.
| 소스 | 값 | 의미 |
|---|---|---|
| 수동 | manual |
운영자가 화면에서 직접 추가 |
| 자동(무죄) | auto |
srct_tx가 평판 조회로 "무죄 확실" 판정한 IP를 30일 면책으로 자동 등록 |
| 기본 | seed |
하드코딩되어 있던 CDN/OFFICE 대역을 InfrWhitelistSeeder로 이관한 영구 항목 |
화이트리스트 테이블
infr_whitelist는 앱 DB가 아니라legacy_glory커넥션(=blacklist_info·suricata_*와 동일한 DB)에 생성됩니다. 그래야 Node 탐지 수집기srct_tx가 차단 직전에 이 테이블을 직접 읽고, 무죄 IP를 직접 기록할 수 있습니다.
언제 쓰나
- 오탐 방지: 정상 트래픽(모니터링 봇, 파트너 크롤러, 결제 콜백)이 스캔·레이트 휴리스틱에 걸려 차단될 위험이 있을 때 미리 등록.
- 조사 중 임시 예외: 특정 대역을 며칠간만 관찰해야 할 때 만료일을 주어 임시 면책.
- CDN/오피스 상시 신뢰: Cloudflare·Google·AWS·Akamai 앞단 IP나 사무실 고정 IP를 영구 면책.
- 자동 무죄 결과 검토:
srct_tx가 자동 등록한auto항목을 확인·연장·삭제. - 블록리스트에서 실수로 차단된 IP를 풀고 재차단을 막고 싶을 때(면책 등록).
화면 구성
상단 KPI (5종)
WhitelistService::summary()가 30초 캐시로 산출합니다. 활성(active) = is_active = 1 AND (expires_at IS NULL OR expires_at > now).
| KPI | 의미 | 계산 |
|---|---|---|
| 활성 면책 | 현재 유효한 전체 면책 수 | 활성 조건 count |
| 영구 | 만료 없는 항목 | 활성 AND expires_at IS NULL |
| 임시 | 만료 예정 항목 | 활성 − 영구 |
| 자동 면책 | 무죄 자동 등록 | 활성 AND source = 'auto' |
| 곧 만료 | 7일 이내 만료 | 활성 AND expires_at <= now+7d |
면책 목록
필터형 테이블(페이지당 25행). 정렬은 영구 항목 우선(expires_at IS NULL DESC) → 만료일 오름차순 → id 내림차순.
| 컬럼 | 설명 |
|---|---|
| 대역 | 정규화된 cidr(예: 203.0.113.0/24 또는 203.0.113.10/32) |
| 이름 | label(예: "Cloudflare", "사무실") |
| 소스 | manual / auto / seed 배지 |
| 만료 | 영구 / YYYY-MM-DD HH:MM / n일 남음 / 만료됨 |
| 등록 | created_at |
| 액션 | 삭제(쓰기 권한 시) |
필터: 상태(활성·만료·전체), 소스(수동·자동·기본·전체), 검색(IP·CIDR·이름). 목록은 30초 주기로 폴링 갱신됩니다.
수동 추가 모달
[수동 추가] 버튼 → 모달. 입력: IP 또는 CIDR, 이름(선택), 만료 일시(선택, 비우면 영구).
사용법
1. 수동 면책 추가
[수동 추가]를 누릅니다.- IP 또는 CIDR 입력. 단일 IP는
/32로, 대역은 네트워크 주소로 자동 정규화됩니다(아래 정규화 규칙). - 이름(선택)과 만료 일시(선택)를 입력합니다. 만료를 비우면 영구 면책.
[추가]. 이미 같은cidr가 있으면 재활성(reactivate) 되며(is_active=1), 만료·이름이 갱신됩니다.
2. 정규화(normalizeCidr) 규칙
WhitelistService::normalizeCidr()가 입력을 표준형으로 바꿉니다(로케일 독립, srct_tx 매칭 규약과 동일).
203.0.113.10 → 203.0.113.10/32 (단일 IP는 /32)
203.0.113.0/24 → 203.0.113.0/24 (그대로)
203.0.113.55/24 → 203.0.113.0/24 (호스트 비트 마스킹 → 네트워크 주소)
10.0.0.5/8 → 10.0.0.0/8
999.1.1.1 → (무효 → null, 422 invalid_ip)
- IPv4만 허용. 비트 수는 0~32.
- 저장 전 컨트롤러가 정규식
^\d{1,3}\.\d{1,3}\.\d{1,3}(\.\d{1,3})?(/\d{1,2})?$로 1차 검증하고, 서비스가filter_var(... FILTER_FLAG_IPV4)+ip2long으로 최종 검증합니다.
/24대역을 넣을 때 호스트 비트가 섞여 있어도 됩니다.203.0.113.55/24를 넣으면 자동으로203.0.113.0/24(네트워크 주소)로 저장됩니다.
3. 만료 입력
- 빈 값 → 영구(
expires_at = NULL). YYYY-MM-DD또는YYYY-MM-DD HH:MM→Carbon::parse로 해석.- 파싱 실패 시에도 영구로 처리됩니다(
parseExpiry→ null).
4. 삭제
목록 행의 삭제 액션 → 확인 후 remove. 행이 물리적으로 삭제(delete) 됩니다(soft-delete 아님). CDN seed 항목도 삭제 가능하나, 다음 시더 실행 시 재생성될 수 있습니다.
5. srct_tx 무죄 자동 면책(auto 소스) — 어떻게 채워지나
srct_tx 수집기는 스캔/레이트 이상 IP를 차단하기 직전에 매우 엄격한 절차로 무죄를 검증하고, 확실한 경우에만 이 화면에 auto 항목을 남깁니다.
- 화이트리스트 필터 —
infr_whitelist(+ 코드 내 CDN)에 이미 있으면 즉시 면책·스킵. - E-only 후보만 평판 조회 — "짧은 스캔 단독" 같은 오탐 다발 신호(휴리스틱 E)만 남고 하드 시그널(A/A2/B/C/D)이 하나도 없는 IP에 한해 AbuseIPDB를 조회합니다(라운드로빈 키·6h 캐시·스윕당 상한).
- 완전 무죄 판정 —
abuse_score=0ANDreports=0AND Tor 아님(또는 화이트리스트+점수0)이면 →infr_whitelist(source=auto)에 30일 면책(ip/32)으로 자동 등록하고 차단을 건너뜁니다.
자동 면책은
srct_tx전용입니다.kts_tx(Kitsune ML)는 화이트리스트를 읽어 필터만 하고 평판 조회·자동 등록은 하지 않습니다.
6. cidrList() — 코드 생성에 재사용
WhitelistService::cidrList()는 활성·미만료 CIDR을 중복 제거해 반환합니다(30초 캐시). 이 목록은 규칙 임계 화면이 srct_tx/kts_tx 스크립트를 생성할 때 CDN_WHITELIST_CIDRS 상수의 소스로 주입되어, 화면에서 관리한 면책이 실제 수집기 코드에 반영됩니다.
데이터 소스
테이블 infr_whitelist (커넥션: legacy_glory, 마이그레이션 000734)
| 컬럼 | 타입 | 설명 |
|---|---|---|
id |
bigint PK | |
cidr |
varchar(43) unique | 정규화된 IP(/32) 또는 네트워크(/n) |
label |
varchar(120) null | 무엇/누구 |
source |
varchar(12) | manual / auto / seed |
reason |
varchar(500) null | auto 근거(평판 점수·카테고리 등) |
country |
varchar(4) null | 국가 코드 |
expires_at |
datetime null | NULL = 영구 |
is_active |
tinyint(1) | 활성 여부 |
created_by |
int null | 등록자 user id |
created_at / updated_at |
timestamps |
인덱스: (is_active, expires_at), source.
infr_whitelist는legacy_glory(GLORY) DB에 생성됩니다.legacy_glory가 mysql/mariadb로 설정되어 있지 않으면 마이그레이션·시더가 no-op(가드)로 건너뜁니다 — 화면은 뜨지만 KPI가 0으로 나옵니다. 실 배포에서는 GLORY 커넥션을 반드시 채워야 합니다.
시더 InfrWhitelistSeeder (source=seed, 영구)
하드코딩되어 있던 CDN/OFFICE 대역을 이관합니다(firstOrCreate로 멱등). 포함: Cloudflare·Google·Meta·AWS·Akamai 앞단 대역 + OFFICE 고정 IP.
php artisan db:seed --class=InfrWhitelistSeeder
모델 · 서비스
- 모델:
App\Models\Infr\InfrWhitelist(protected $connection = 'legacy_glory'). - 서비스:
App\Services\Security\WhitelistService—summary()(KPI 30s 캐시),page()(필터·페이지),add()/remove()(쓰기),cidrList()(코드 생성 소스),normalizeCidr()(정적 SOT). - 컨트롤러:
App\Http\Controllers\Security\WhitelistController—index·live·add·remove.
권한
| 동작 | 최소 레벨 | 비고 |
|---|---|---|
| Security 영역 진입·조회 | Security 메뉴 min_req 2 |
demo(1)는 Security 메뉴가 보이지 않음 |
| 화이트리스트 추가/삭제(쓰기) | level ≥ 2 | WhitelistController::canWrite() = user_level >= 2 |
레벨 체계: demo=1 · staff=5 · admin=10. 따라서 staff·admin은 읽기/쓰기 모두 가능하고, 쓰기 실패 시 403 forbidden(토스트 "권한이 없습니다 (레벨 2 이상)")이 반환됩니다.
모든 쓰기는 InfrAuditLog에 남습니다.
- 추가 →
sec.whitelist_add(target=ip, meta에id·reactivated). - 삭제 →
sec.whitelist_remove(target=ip, meta에id).
자세한 레벨/역할 정책은 RBAC 레벨, 감사 열람은 감사 로그 참고.
문제해결 · FAQ
KPI가 전부 0이고 목록이 비어 있어요
legacy_glory 커넥션이 설정되지 않았거나 infr_whitelist 테이블이 아직 없습니다. GLORY DB 설정을 확인하고 마이그레이션/시더를 실행하세요. 서비스는 DB 오류 시 graceful하게 빈 값을 반환하도록 되어 있습니다.
"올바른 IP·CIDR이 아닙니다" (422)
입력이 IPv4 형식이 아니거나 비트 수가 0~32 범위를 벗어났습니다. IPv6는 지원하지 않습니다. 예: 203.0.113.10, 203.0.113.0/24.
/24를 넣었는데 저장된 대역이 달라요
정상입니다. 호스트 비트가 마스킹되어 네트워크 주소로 저장됩니다(203.0.113.55/24 → 203.0.113.0/24).
같은 IP를 다시 추가하면 중복되나요?
아니요. cidr가 unique이므로 기존 항목이 재활성되고 만료·이름이 갱신됩니다(응답 reactivated: true). 단, 기존이 seed였다면 소스는 seed로 유지됩니다.
auto 항목이 왜 생기나요 / 지워도 되나요?
srct_tx가 무죄 확실 판정한 IP를 30일 면책으로 자동 등록한 것입니다. 삭제해도 되지만, 해당 IP가 다시 오탐되면 재등록될 수 있습니다.
만료된 항목은 자동으로 사라지나요?
행은 남되 "활성" 집계에서 빠집니다(만료 시각 경과 시). 상태 필터를 만료/전체로 바꾸면 볼 수 있습니다. 완전 제거는 삭제로.
면책했는데도 계속 차단돼요
(1) 정규화된 대역이 실제 트래픽 IP를 포함하는지(예: /32 vs /24), (2) cidrList() 캐시(30초)와 수집기 스크립트 재생성 여부, (3) 이미 blacklist_info에 차단 기록이 남아 있는지를 확인하세요. 기존 차단은 블록리스트에서 해제해야 합니다.
관련 항목
- 블록리스트 · 평판 — 차단 목록 관리(면책의 반대편)
- 자동 차단 — 스케줄러 자동 차단(화이트리스트·무죄 veto)
- 위협 — IDS 위협 트리아지, IP 드릴다운
- 규칙 임계 — srct_tx/kts_tx 상수 + cidrList 주입
- IP 평판 — AbuseIPDB 인앱 조회
- 감사 로그 — 쓰기 작업 감사
