7.8 KiB
7.8 KiB
| name | description |
|---|---|
| csap-compliance | GUARDiA CSAP/ISMS-P 공공기관 보안 준수 자동 점검 구현 스킬. 기존 compliance.py를 확장하여 공공기관 보안 체크리스트(100개 항목) 자동 점검, 증적 수집, Excel/HTML 보고서 생성을 구현한다. 다음 상황에서 반드시 사용: (1) 'CSAP', 'ISMS', '보안인증', '공공기관 보안점검' 구현 요청; (2) compliance.py CSAP 고도화 또는 core/csap_checker.py 작업; (3) 보안 점검 보고서, 준수율 대시보드 구현; (4) 증적 수집, 체크리스트 자동화; (5) 다시 실행, 업데이트, 보완 요청. |
CSAP 자동 점검 구현 스킬
구현 대상 파일
itsm/core/csap_checker.py— CSAP 점검 엔진itsm/routers/compliance.py— 기존 파일에 CSAP 엔드포인트 추가
DB 모델 (models.py에 추가)
class CSAPCheckResult(Base):
__tablename__ = "tb_csap_result"
id = Column(Integer, primary_key=True)
scan_id = Column(String(50), nullable=False, index=True) # CSAP-YYYYMMDD-NNN
inst_id = Column(Integer, ForeignKey("tb_inst_meta.id"))
item_id = Column(String(20), nullable=False) # M-01, T-15 등
category = Column(String(20)) # 관리적 | 기술적 | 물리적 | 운영
item_name = Column(String(200))
status = Column(String(20)) # PASS|FAIL|PARTIAL|MANUAL_REQUIRED|N_A
severity = Column(String(20)) # HIGH|MEDIUM|LOW
finding = Column(Text) # 발견 사항
evidence = Column(JSON) # 자동 수집 증적 (마스킹 처리)
recommendation = Column(Text) # 개선 권고
scanned_at = Column(DateTime, default=func.now())
CSAP 점검 항목 구조 (core/csap_checker.py)
CSAP_ITEMS = [
# ── 관리적 보안 (M) ────────────────────────────────────────────────
{"id":"M-01","cat":"관리적","sev":"HIGH","auto":False,
"name":"정보보호 정책 수립","check":"policy_doc_uploaded"},
{"id":"M-02","cat":"관리적","sev":"HIGH","auto":False,
"name":"정보보호 조직 구성","check":"org_chart_uploaded"},
{"id":"M-03","cat":"관리적","sev":"MEDIUM","auto":True,
"name":"정보보호 교육 이력","check":"training_records_exist"},
# ── 기술적 보안 (T) ────────────────────────────────────────────────
{"id":"T-01","cat":"기술적","sev":"HIGH","auto":True,
"name":"계정 잠금 정책 (5회 실패 시 잠금)","check":"account_lockout"},
{"id":"T-02","cat":"기술적","sev":"HIGH","auto":True,
"name":"패스워드 복잡도 정책 (8자 이상+특수문자)","check":"password_policy"},
{"id":"T-03","cat":"기술적","sev":"HIGH","auto":True,
"name":"불필요 서비스 비활성화","check":"unnecessary_services"},
{"id":"T-04","cat":"기술적","sev":"HIGH","auto":True,
"name":"SSH root 직접 로그인 차단","check":"ssh_root_disabled"},
{"id":"T-05","cat":"기술적","sev":"HIGH","auto":True,
"name":"보안 패치 최신화 (30일 이내)","check":"patch_currency"},
{"id":"T-06","cat":"기술적","sev":"MEDIUM","auto":True,
"name":"방화벽 룰 최소 권한 원칙","check":"fw_least_privilege"},
{"id":"T-07","cat":"기술적","sev":"HIGH","auto":True,
"name":"암호화 전송 (HTTPS/TLS 1.2 이상)","check":"tls_version"},
{"id":"T-08","cat":"기술적","sev":"HIGH","auto":True,
"name":"개인정보 암호화 저장","check":"pii_encryption"},
# ── 운영 보안 (O) ─────────────────────────────────────────────────
{"id":"O-01","cat":"운영","sev":"HIGH","auto":True,
"name":"로그 보존 기간 (6개월 이상)","check":"log_retention"},
{"id":"O-02","cat":"운영","sev":"HIGH","auto":True,
"name":"백업 실시 및 무결성 검증","check":"backup_integrity"},
{"id":"O-03","cat":"운영","sev":"MEDIUM","auto":True,
"name":"변경 관리 프로세스 이행","check":"change_management"},
# ── 물리적 보안 (P) ───────────────────────────────────────────────
{"id":"P-01","cat":"물리적","sev":"MEDIUM","auto":False,
"name":"출입 통제 시스템 운영","check":"physical_access"},
{"id":"P-02","cat":"물리적","sev":"HIGH","auto":True,
"name":"DR 사이트 운영 (RTO/RPO 충족)","check":"dr_test_passed"},
# ... 총 100개 항목 (실제 구현 시 전체 목록 확장)
]
자동 점검 함수 패턴
class CSAPChecker:
async def check_ssh_root_disabled(self, db, inst_id: int) -> dict:
"""T-04: SSH root 로그인 차단 확인."""
# 기관 서버 목록 조회 → 각 서버 SSH 접속 → /etc/ssh/sshd_config 확인
# PermitRootLogin no 확인
...
async def check_patch_currency(self, db, inst_id: int) -> dict:
"""T-05: 보안 패치 최신화 (30일 이내 패치 여부)."""
# SSH → rpm -qa --last | head -20 또는 apt list --upgradable
...
async def check_log_retention(self, db, inst_id: int) -> dict:
"""O-01: 로그 보존 6개월 이상."""
# GUARDiA tb_audit_log 최오래된 레코드 날짜 확인
from sqlalchemy import select, func
oldest = await db.scalar(select(func.min(AuditLog.created_at)))
...
async def check_backup_integrity(self, db, inst_id: int) -> dict:
"""O-02: 백업 무결성 (DR 테스트 최근 90일 이내 PASS)."""
# tb_dr_test에서 최근 PASS 결과 확인
...
async def check_dr_test_passed(self, db, inst_id: int) -> dict:
"""P-02: DR 테스트 이력."""
# tb_dr_test에서 최근 1년 이내 PASS 확인
...
def generate_scan_id(self) -> str:
from datetime import datetime
now = datetime.now()
return f"CSAP-{now.strftime('%Y%m%d')}-{now.strftime('%H%M%S')}"
보고서 생성 패턴
def generate_excel_report(self, results: list, inst_name: str) -> bytes:
"""openpyxl 기반 Excel 보고서 생성."""
import openpyxl
from openpyxl.styles import PatternFill, Font
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "CSAP 점검 결과"
# 헤더: 항목ID, 카테고리, 항목명, 심각도, 결과, 발견사항, 개선권고
# 결과별 색상: PASS=녹, FAIL=적, PARTIAL=황
...
def generate_html_report(self, results: list, scan_id: str) -> str:
"""HTML 점검 보고서 (인쇄 가능, 공문 첨부용)."""
# 준수율 차트 (SVG inline), 항목별 상세 테이블
...
compliance.py 추가 엔드포인트
POST /api/compliance/csap/scan 전체 자동 점검 (ADMIN 전용)
GET /api/compliance/csap/items 점검 항목 목록 (category 필터)
GET /api/compliance/csap/results 최근 점검 결과 요약 목록
GET /api/compliance/csap/results/{scan_id} 배치 상세 결과
POST /api/compliance/csap/evidence/{item_id} 수동 증적 업로드
GET /api/compliance/csap/report/html HTML 보고서 (scan_id 쿼리)
GET /api/compliance/csap/report/excel Excel 보고서 (scan_id 쿼리)
GET /api/compliance/csap/dashboard 기관별 준수율 대시보드
준수율 계산 공식
자동 점검 통과율 = (PASS + PARTIAL*0.5) / (전체 자동 항목) * 100
수동 항목 = MANUAL_REQUIRED로 표시, 별도 집계
전체 준수율 = (자동 통과 항목 수 + 수동 PASS 업로드 수) / 전체 100개 * 100