InfraGuard

화이트리스트 (차단 면책)

자동 차단에서 제외할 IP·CIDR을 만료 개념(영구/임시)으로 관리하고, srct_tx가 차단 직전 참조하는 면책 목록을 제공합니다.

개요 — 무엇을 하나

화이트리스트는 InfraGuard의 자동 차단 파이프라인에서 면책(exempt) 할 IP·대역을 관리하는 화면입니다. 여기 등록된 IP/CIDR은 탐지 수집기가 차단을 실행하기 직전에 반드시 확인하는 "면책 명부"가 되어, CDN·파트너 API·사내 회선 같은 신뢰 출발지가 오탐으로 차단되는 사고를 막습니다.

핵심 개념은 만료(expiry) 입니다.

면책 항목은 세 가지 소스(source) 로 들어옵니다.

소스 값 의미
수동 manual 운영자가 화면에서 직접 추가
자동(무죄) auto srct_tx가 평판 조회로 "무죄 확실" 판정한 IP를 30일 면책으로 자동 등록
기본 seed 하드코딩되어 있던 CDN/OFFICE 대역을 InfrWhitelistSeeder로 이관한 영구 항목

화이트리스트 테이블 infr_whitelist는 앱 DB가 아니라 legacy_glory 커넥션(= blacklist_info·suricata_*와 동일한 DB)에 생성됩니다. 그래야 Node 탐지 수집기 srct_tx가 차단 직전에 이 테이블을 직접 읽고, 무죄 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. 수동 면책 추가

  1. [수동 추가]를 누릅니다.
  2. IP 또는 CIDR 입력. 단일 IP는 /32로, 대역은 네트워크 주소로 자동 정규화됩니다(아래 정규화 규칙).
  3. 이름(선택)과 만료 일시(선택)를 입력합니다. 만료를 비우면 영구 면책.
  4. [추가]. 이미 같은 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)

/24 대역을 넣을 때 호스트 비트가 섞여 있어도 됩니다. 203.0.113.55/24를 넣으면 자동으로 203.0.113.0/24(네트워크 주소)로 저장됩니다.

3. 만료 입력

4. 삭제

목록 행의 삭제 액션 → 확인 후 remove. 행이 물리적으로 삭제(delete) 됩니다(soft-delete 아님). CDN seed 항목도 삭제 가능하나, 다음 시더 실행 시 재생성될 수 있습니다.

5. srct_tx 무죄 자동 면책(auto 소스) — 어떻게 채워지나

srct_tx 수집기는 스캔/레이트 이상 IP를 차단하기 직전에 매우 엄격한 절차로 무죄를 검증하고, 확실한 경우에만 이 화면에 auto 항목을 남깁니다.

  1. 화이트리스트 필터 — infr_whitelist(+ 코드 내 CDN)에 이미 있으면 즉시 면책·스킵.
  2. E-only 후보만 평판 조회 — "짧은 스캔 단독" 같은 오탐 다발 신호(휴리스틱 E)만 남고 하드 시그널(A/A2/B/C/D)이 하나도 없는 IP에 한해 AbuseIPDB를 조회합니다(라운드로빈 키·6h 캐시·스윕당 상한).
  3. 완전 무죄 판정 — abuse_score=0 AND reports=0 AND 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

모델 · 서비스


권한

동작 최소 레벨 비고
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에 남습니다.

자세한 레벨/역할 정책은 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에 차단 기록이 남아 있는지를 확인하세요. 기존 차단은 블록리스트에서 해제해야 합니다.


관련 항목

화이트리스트 — 차단 면책 목록
화이트리스트 — 차단 면책 목록