1년간 푼 문제들 — BSOD 분석기·DB Migration 체계·매니저 RBAC·커널 드라이버 데드락·매니저 진단 도구 — 연간 리뷰 (2025-05-26 ~ 2026-05-26)

서버 백엔드 파트가 서버 DB Migration v0000 baseline 체계·Python 환경 uv + 3.13 폐쇄망 오프라인 설치·Mosquitto/Nginx/MongoDB 설정 강화·fail2ban·KISA 보안 검증으로 서버 아키텍처를 대정비하고, 분석 서비스 파트가 서버 모니터링 SNMP 5영역·nginx 리버스 프록시 + HTTP/2·매니저 RBAC 권한 체계로 운영 인프라를 완성하고, 매니저·에이전트 파트가 BSOD 분석기 + 매니저 상태 패널 현장 진단 도구 + Z-score 기반 증상 위젯 공통 기준 + Git/Jira 자동화 5종 리뷰 루틴을 깔고, 커널 드라이버 파트가 orange.sys Driver Unload 데드락 근본 해소·MS 서명 프로세스 SL 캡처 인프라·파일 삭제·오류 증상화 3축으로 커널 안정성을 끌어올리고, 룰·데이터 분석 파트가 고객사 데이터 49일 실측·룰·분석 모델 고도화로 탐지 정확도 기반을 마련한 1년.

2025-05-26 ~ 2026-05-26 1년치 회고. 5명이 8개 레포에서 2,880커밋, +342,469 / −154,115 라인(대량 커밋 제외). 양보다 '제품의 어려운 부분을 누가 떠안았는가'로 풀어쓴다.

트레이닝 계획 단계였던 manager-web 파트의 활동은 통계에 포함하지 않았다.


서버 아키텍처 대정비

서버 DB Migration 체계 구축 — v0000 baseline + 순번 기반 (OR-374). REST API·Service 두 서브모듈이 공유하는 MongoDB에 대해 버전별 마이그레이션이 추적 안 되던 구조(upgrade.py 522줄 단일 스크립트)를 정리. Beanie 내장·mongodb-migrations·Liquibase 등 후보를 라이선스·동기성·생태계 활성도로 전수 비교한 끝에 경량 자체 구현이 적합하다는 결론. servers/migrations/ 공용 위치에 BaseMigration + MigrationRunner + v0000_baseline(upgrade.py 흡수) 구조를 짜고, _migrations 컬렉션으로 적용 이력 추적. 순번 기반(v0001, v0002 ...) 네이밍으로 VERSION과 1:1 묶지 않아 평소 자유롭게 쓰고 릴리스 시점에만 manifest 작성. 24커밋의 분기 최대 작업.

서버 Python 환경을 uv + 3.13으로 전환 + 폐쇄망 오프라인 설치 (OR-1045). 시스템 python3 + pip + --break-system-packages 운영을 /home/@server/.venv/ uv 기반으로 전환. pyproject.toml + uv.lock 한 벌로 개발과 배포 모두 통일하고, Python 3.13 인터프리터를 패키지에 동봉(@python/cpython-*.tar.gz)해 폐쇄망에서도 네트워크 없이 설치 가능. 빌드(uv export --no-dev)와 설치(uv pip sync --no-index --find-links wheels/) 양쪽이 운영 의존성만 다루도록 dev 분리. systemd unit 7개·cron 3개의 python 경로 일괄 .venv/bin/python으로 변경. orange 계정 범용 pip은 독립 유지. 16커밋.

mosquitto SSL_OP_IGNORE_UNEXPECTED_EOF preload shim 패키징 동봉 (OR-1414). OpenSSL 3.0.x record layer 버그(partial TLS record + close 에러 시 SSL_CTX 공유 상태 손상)를 Ubuntu 24.04가 패치하지 않는 점을 격리 환경에서 확정한 뒤, SSL_OP_IGNORE_UNEXPECTED_EOF 플래그를 LD_PRELOAD로 주입하는 shim을 도입. 폐쇄망 update 안정성을 위한 3단계 보강: ① silent skip 방지 안전망(install.sh 실패 시 setup/update가 die 대신 경고만), ② WSL Ubuntu 24.04(glibc 2.39)에서 빌드한 사전 빌드 .so를 git에 동봉 + Makefile MAX_GLIBC=2.39 ceiling을 make verify가 강제, ③ package CLAUDE.md 트리·동봉 정책·setup/uninstall 단계 문서 동기화. 운영 서버 .so와 byte-identical(sha256) 확정. 11커밋.

fail2ban 패키지 통합 — firewall.rules __SSH_PORT__ 토큰화 (OR-1313). 인터넷 노출 서버 SSH 무차별 대입을 systemd journal 백엔드 + nftables banaction + 지수 증가 ban + recidive 메타-jail(24h 내 5번 ban → 1주 장기차단)로 차단. 패키지 install/setup/update/uninstall 4개 스크립트에 일관 통합하고, firewall.rules에 __SSH_PORT__ 토큰을 도입해 install 시점에 detect_ssh_port 헬퍼가 동적 치환 — 고객사마다 다른 sshd 포트를 자동 반영. 폐쇄망 update에서 fail2ban 미설치 환경도 graceful skip. 5커밋.

Mosquitto 브로커 설정 강화 — 좀비 세션·메모리·로깅·logrotate (OR-1141). 기본 설정에 의존하던 브로커를 운영 관점에서 점검. 좀비 persistent session 7일 후 자동 정리(persistent_client_expiration), OOM 방어 위한 1GB memory_limit, warning/notice/connection_messages 추가로 인증 실패·브로커 상태 가시화, 미사용 비암호화 WS 리스너(3173) 제거로 공격 표면 축소, max_keepalive 300초로 dead connection 감지 지연 방지. 또 logrotate가 잘못된 경로(/var/log/mosquitto)를 바라봐 개발서버에 36GB 로그가 누적된 사실을 적발해 /home/orange/mosquitto/로 교정. 11커밋.

Nginx 설정 개선 — 보안 헤더 상속 버그 + 폰트 immutable + 진단 로그 (OR-1144). nginx_orange 16개 개선 항목을 도출해 11건 적용. Critical은 add_header 상속 함정 — /manager/ 이하 7개 location에서 HSTS·nosniff·X-Frame-Options가 전부 누락되던 문제를 snippet include로 복구. 자체서명 환경에서 영구 차단 위험 있는 HSTS preload 플래그 제거, X-XSS-Protection을 0으로(폐기 + 공격 악용 가능), Permissions-Policy로 카메라·마이크·결제 등 8개 강력 기능 원천 차단, 폰트는 1년 immutable 캐시, access 로그에 req_time/upstream_resp_time 등 추가해 nginx vs REST API 병목 즉시 구분. gzip comp_level은 측정 데이터(level 5는 CPU 2.71배 vs 압축률 6.2%p) 근거로 1 회귀. 10커밋.

nodedetect v3 마이그레이션 — distinctCount + totalCount 두 의미 분리 (OR-1424). /v2/nodedetect/count(group_by_cuid_cgid=true)를 /v3/detect/nodes/count로 옮기며 응답을 '고유 증상 인스턴스 수(distinctCount, 기존 v2 의미)'와 '기간 내 발생 횟수(totalCount, 1시간 버킷 누적 합산)' 둘로 명확히 분리. 1회 aggregate로 두 값 동시 산출, get_date_range_obj DI로 tz 누락 시 422 자동 검증. manager-web 호출부 마이그레이션 + dead 위젯·dead code 정리 + '기간 내' 접두사 라벨 통일까지. 4커밋.

Service 계층의 API 스키마 의존 제거 — 순환 import 근본 정리 (OR-1425). Service/Infra가 API 스키마(app/api/v3/schemas/*)를 거꾸로 import하던 layer 위반 3건(CommandTemplate·Organization·infra/cgroup)을 모두 정상화. 각 계층 전용 schemas/ 디렉터리에 입력/결과 모델 신설, usecases/mapper/ 3개(CommandTemplate·Organization·Health)로 API↔내부 변환을 일관화. __future__ + TYPE_CHECKING 회피책 완전 제거. 외부 API 응답 변경 0건 — 순수 내부 리팩터링. 3커밋.

Playwright MCP 도입 — AI 에이전트 기반 매니저 UI 회귀 자동화 (OR-1361). Claude Code 등 AI 에이전트가 manager-web의 로그인·페이지 진입·할당 흐름을 자연어 한 번으로 검증하도록 @playwright/mcp 3채널(headed/headless/legacy-v105)을 등록. --isolated로 세션마다 깨끗한 프로필. 고객사 구형 Chromium v105 호환성 회귀까지 같은 명령으로 검증. CLAUDE_PLAYWRIGHT.md에 진입점·selector·alias 검증 패턴·운영 주의까지 통합. 3채널 모두 동일 시나리오 통과 검증(alias 24/24).

v3 파일 I/O 비동기 전환 — aiofiles.os 도입 (OR-1422). v3 파일 업로드/다운로드/삭제 경로의 sync os.path / open / os.remove 호출을 aiofiles.os 기반 비동기 syscall로 전환. 핵심은 raw 성능이 아니라 '소수 파일 경로의 sync syscall이 다수 Mongo/Redis 요청의 p99 latency까지 오염시키는 비대칭 구조'를 차단하는 서버 응답성 보존. 향후 HDD 전환 대비(매체별 sync stat latency 분석)와 async 스택 일관성까지 한 작업으로 묶음. 동시 16요청 + 1ms heartbeat 벤치마크로 효과 입증. ruff ASYNC230/240 위반 8건 + silent blocking 5건 해소.

KISA SW개발 보안 가이드에 따른 서버 코드 검증 (OR-994) · 폐쇄망 무인 서버 업데이트 스크립트 update.sh (OR-1062, 8커밋) 도 같은 라인에서 진행. 292건 중 264건 완료 — 완료율 91%. 결정 전 조사의 깊이가 특징 — migration 도구 전수 비교, MongoDB 튜닝을 학술 논문까지 근거로 삼고, fail2ban은 커널 netfilter 패킷 흐름까지 이해하고 적용.


매니저 진단·통계 기반 이상 탐지 + 전 스택의 어려운 부분

BSOD 분석기 마무리 — StackWalker pdb 다운로드 차단 + 콜스택 major 재배치 (OR-1310). DumpAnalyzer 0x9F 디바이스 스택 워킹·Cause 분류·Hardware 보강이 끝난 뒤 남아 있던 두 마무리. 폐쇄망/오프라인에서도 분석이 즉답이 되도록 StackWalker가 PDB 다운로드 시도하지 않게 막고, RaiseException 후처리에서 콜스택 major 프레임을 원인 모듈 기준으로 재배치해 룰 매칭 일관성을 끌어올렸다. 분석기·룰 분담 원칙(분석기는 식별·분류, 룰은 사용자 안내) 하에서 마지막 정리를 완성한 작업.

매니저 상태 패널 — 현장 진단 도구 내장 (OR-1105). 한 보험사 고객사에서 12대 노드만으로 Manager가 심하게 느려진 사례(OR-1101)를 계기로, 오른편 요약 패널 '상태' 탭에 현장 즉시 진단 도구를 내장. 대시보드 진입과 동시에 browserCollector·fetch/WebSocket/error interceptor·perfStats가 일제히 가동되어 처음부터 모든 데이터를 기록. Google Core Web Vitals + Lighthouse 가중치로 종합 등급(양호/개선 필요/느림) 산출, 10초 간격 /health/live 핑으로 네트워크 vs 서버 병목을 즉시 구분, 캐시 카드(PerformanceObserver('resource'))로 폰트 반복 다운로드 같은 문제가 곧바로 드러나도록 설계. 31커밋의 분기 최대 작업.

증상 요약 위젯 공통 이상 탐지 기준 — Z-score 기반 상태 라벨 (OR-1113). 관리자가 룰별 임계값을 설정하지 않아도 위젯이 스스로 '평소 vs 지금'을 판정해 수집 중/정상/상승/급증을 표시하는 통계 기반 기준을 정립. 과거 6일 일별 고유 노드 수의 평균·σ(최소 하한 1.0) 위에서 2σ 초과면 상승, 3σ 초과면 급증으로 판정. 설치 초기처럼 비교 데이터 없는 상태에서는 '정상'이라는 근거 없는 안심을 주지 않고 '수집 중'으로 정직하게 표현. 라벨도 '주의/경고' 같은 판단어 대신 '상승/급증' 같은 사실 전달어. 12커밋. typeEvent prop으로 TCP/IP·CPU 점유·DNS 등 전 카테고리 자동 적용 — 향후 모든 증상 요약 위젯의 공통 기준.

ConPTY 감사로그 개선 — 감사 전용 토픽 + Agent 정제 발행 (OR-991). 기존엔 실시간 터미널 렌더링과 감사로그가 같은 토픽을 공유해 dir 명령 하나에 20~50개 noise 메시지가 쌓이고 입력/출력 연결도 불가능했다. public/audit/live-response 전용 토픽을 신설해 Agent가 정제된 페이로드(action·manager_id·command·response 등)를 발행, 동시에 동일 Agent에 여러 관리자가 LiveCMD를 동시 실행하면 한쪽 입력이 다른 쪽에 노출되던 보안 취약점을 세션 점유 모델로 차단. session_denied 액션은 OR-1158과 묶어 진행.

매니저 웹 성능 개선 — nginx 캐시 정책 + 폰트 prefetch 중복 제거 (OR-1142). 사내 한 서버에서 재현된 느린 매니저 응답의 두 원인을 동시 해소. nginx /manager 전체에 걸려 있던 무차별 no-cache를 SPA 진입점·PACKAGE·SW·env 4곳만 no-cache로 좁히고 나머지(폰트/이미지/manifest)는 ETag 304 응답으로 정상화 — OR-1115 buildHash 메커니즘과도 정합. export 유틸이 3개 위젯에서 12MB 폰트를 각자 prefetch하던 중복도 공용 모듈로 통합해 제거.

매니저 위젯 시스템 레퍼런스 widget-map.html (OR-723). Manager 50개 등록 위젯의 흐름·MQTT 토픽 지도·Store 지도·패밀리 그룹·카탈로그 5탭을 한 HTML로 정리해 분산 개발 시 위젯 역할·배치·호출 관계를 빠르게 파악할 수 있게 했다. 매니저 분산 개발 체계를 후임이 이어받을 수 있도록 라이브 레퍼런스를 남기는 작업.

LiveCMD @ 명령 간헐적 미인식 + 응답 UI 토스트 전환 (OR-1416). atLineStartRef가 Enter/Ctrl+C/Ctrl+Z에만 true로 복구되고 그 외 키 입력에는 false로 잠겨, Backspace로 줄을 비우거나 Esc 클리어·텍스트 붙여넣기 후 @reload를 치면 @가 cmd.exe echo 억제로 사라지고 reload만 실행되던 패턴을 시나리오 3가지로 분리 재현해 확정. lineInputRef로 줄 상태를 정확히 추적하도록 교체. Agent @ 명령 응답은 터미널 직접 출력에서 토스트 형태로 바꿔 ConPTY 화면 오염도 함께 해소.

Git·Jira 자동화 시스템 가동 + 3개 레포 CLAUDE.md 정비 (OR-984). 5개월 전수 분석(커밋 1,884건·미기입률 34%·작성자별 월별 처리량) 결과를 바탕으로 MCP 서버(orange-mcp·systemd·Nginx /mcp)와 Claude Cloud 정기 리뷰 루틴 5종(일/주/월/분기/연간)을 구축해 운영 안착. Agent·Html·OldManagerWeb 3개 레포에 CLAUDE.md를 추가해 c3 레거시·p18 Agent UI(WebView2)·정적 페이지 코드 리뷰 가이드까지 컨텍스트 자급자족이 되도록 묶었다.

패키지에서 p18(Agent UI) 제거 — c3 잔재 정리 (OR-1419). c3 매니저가 LiveAgent를 p18(Agent UI) 코드와 공유하던 구조에서 c4가 LiveAgent를 별도 구현으로 분리한 뒤 남아 있던 패키징 잔재를 일괄 정리. makepackage.sh/.bat의 @user 디렉터리 생성·복사, nginx /user location, install/setup.sh·update.sh의 생성·복사·권한·검증 루프까지 모두 제거. uninstall은 기존 서버 정리를 위해 rm -rf 대상은 보존 — 호환성 한 줄까지 챙겼다.

nodeInfo 위젯 종료 시 set.STATUS offline 미발송 — OR-1409 회귀 추적 (OR-1418). OR-1409 글로벌 MQTT 통합 직후 nodeInfo cleanup 일부가 빠지며 위젯이 닫혀도 Agent가 '이 화면 더 안 본다' 신호를 받지 못해 전용 패킷을 계속 보내는 부작용 발생. 정상 종료 publish 경로는 즉시 복구하고, 비정상 종료용 will은 글로벌 MQTT가 노드별 보조 연결을 전담하도록 시도. 그 과정에서 broker OpenSSL 0A000123 잔여 경로가 크롬 148 이후부터 다시 트리거된다는 사실을 격리 비교(엣지 vs 크롬)로 확정했고, mqtt.js 5.10.2 → 5.15.1 업그레이드로 클라이언트 라이브러리 변수도 배제. 매니저 측 책임의 한계를 명확히 드러낸 진단.

387건의 이슈 중 상당수는 위젯 카피 수정·버튼 이름 변경 같은 루틴 작업이지만, 핵심은 근본 원인 추적과 아키텍처 재설계. C++ 네이티브(드라이버·동시성)부터 React 프론트엔드, nginx·빌드 인프라까지 전 스택을 직접 짚었고, 난이도가 높은 문제일수록 본인이 들어가는 패턴이 뚜렷하다.


서버 모니터링·성능 + 매니저 RBAC 권한 체계

서버 모니터링 고도화 — SNMP OID 5영역 + 카테고리 아코디언 (OR-1055). 서버 모니터링에서 SNMP 모니터의 연결 장비 자동 스캔을 추가하고, 모니터링 목록 UI를 카테고리별 아코디언 그룹핑으로 개편. SNMP는 기본 시스템 정보·CPU 로드·메모리·인터페이스 트래픽·IP/인터페이스 매핑 5영역의 OID를 정리하고, 32비트 카운터 롤오버 보정과 비정상 차분 무시 로직까지 포함. SSL 인증서 체크 파싱 버그 수정과 대상 주소 입력 형식 유연화도 함께. 71커밋의 분기 최대 작업.

서버 성능개선 — nginx 리버스 프록시 + HTTP/2 + WOFF2 폰트 (OR-1130). Manager Web이 :3181 REST API를 직접 호출하던 구조에서 449개 요청 + CORS preflight + 브라우저 6 커넥션 제한이 직격하던 문제를 nginx /api/ 리버스 프록시 + HTTP/2 도입으로 정리. Same-Origin이라 preflight가 사라지고, HPACK 헤더 압축으로 반복 헤더 80~90% 감소, 단일 TCP 커넥션에서 멀티플렉싱. NotoSansKR 폰트는 TTF 5.9MB×2 = 11.8MB → WOFF2 4.1MB로 줄였다(jsPDF용 TTF는 별도 폴백 유지). Lighthouse Performance 55점 환경에서 시작한 사전 분석으로 근거를 만든 작업. 17커밋.

관리자 계정 권한(RBAC) 시스템 — Store + Redis 캐시 + 위젯 ACL 동기화 (OR-1314). /v3/acl 통합 라우터(endpoint/widget/feature/role 14개 엔드포인트)와 Store 컬렉션 패턴(EndpointAclStore·WidgetAclStore·RoleDefinitionStore·FeaturePermissionStore) + Redis 캐시를 깐 위에서, _check_endpoint_acl에 _OPEN_ACCESS_OPERATIONS 바이패스 추가, 위젯 ACL R/W/D 동기화 버그 수정, role 삭제 시 FeaturePermissionStore 캐스케이드 정리, HTTPException → 커스텀 예외 전환, 로그인 응답 ACL 직렬화 camelCase 정합까지 안정화 마무리. product-Orange v0006 시드 매니저 role 보정(orange/신규 admin = super_admin)도 함께. 10커밋.

LiveCMD Role별 권한 적용 — Agent ACL 확인 엔드포인트 + 403 상세 응답 (OR-1415). Agent용 LiveCMD 권한 확인 엔드포인트를 신설하고, feature_permission 빈 배열을 전체차단으로 정의 + 서버 시작 시 기본값 생성. 403 응답에 거부된 method/path/operation_id를 동봉해 매니저의 PermissionErrorBoundary 오버레이가 어떤 API가 막혔는지 정확히 표시. 기능 권한에서 batch_command(1:N) 항목 제거 + ACL 직렬화 camelCase 정합 + 새 엔드포인트 시드 is_reviewed 정책까지. 권한 체계 완성으로 가는 큰 작업의 핵심 줄기. 20커밋.

새 엔드포인트 추가 알림 — is_reviewed 추적 + 토스트 + 미확인 배지 (OR-1359). 서버 배포 후 acl_seed가 새로 시드한 엔드포인트를 is_reviewed=False로 추적하고, admin 로그인 시 useUnreviewedEndpointAlert 훅이 sessionStorage 기반으로 세션당 1회 토스트 알림. '설정 > 권한 관리 > API 권한' 탭에 미확인 카운트 오렌지 배지, PUT 저장 시 endpoint_update_case가 자동으로 is_reviewed=True 설정, '모두 확인 완료' 일괄 처리 엔드포인트까지. is_reviewed 기본값 True로 기존 DB 하위호환 보장. 10커밋.

설정 영역을 위젯 → 기본 내장으로 — ACL OR 합산 버그 근원 해소 (OR-1413). 설정(Setting)을 GridLayout의 위젯 배치에서 빼내고 Content.tsx가 setting 섹션을 직접 렌더링하도록 변경(containType='global', 위젯 헤더바·드래그 핸들 없음). 위젯 패널 노출과 widget.config.json의 requiredApis 25개를 비워, 부모 setting 위젯과 자식 탭 위젯이 같은 API를 중복 보유해 _sync_endpoint_acl의 OR 합산으로 권한 박탈이 되돌려지던 버그를 근본 차단. 편집 모드에서 설정 위젯/섹션은 삭제·이동·수정 차단까지. 백엔드는 empty allowed_roles → 403 커스텀 예외로 전환. 7커밋.

고객사별 기본 ID 생성 및 root ID 처리 (OR-1295) · Live CMD 타입 추가 — session_denied 감사 (OR-1158) · **매니저 권한 적용 오류 수정 — 위젯별 403 + 타입 안전성 + 보안 (OR-1402)**까지로 권한 체계 인프라를 일관성 있게 마무리. 92건 중 66건 완료. 운영 메트릭(호출 수·응답 시간)을 근거로 리팩터링 우선순위를 정하는 데이터 기반 접근, 그리고 RBAC·감사로그·인증서 등 보안·컴플라이언스 영역을 떠안는 두 축이 특징.


커널 드라이버 안정성·필터링

orange.sys Driver Unload 데드락 근본 해소 — ADS read를 PostCreate로 이동 (OR-1290). 'sc stop orange 안 됨' 증상의 진짜 원인은 PreSetInfoCallback에서 ADS(:o5l3c) 읽기 위해 FltCreateFileEx2를 부른 것. FileDispositionInformation 처리 중 NTFS가 FCB ERESOURCE Exclusive + FILE_OBJECT Busy를 잡고 있는 상태에서 같은 스트림에 Create IRP를 던지면 lock-order inversion으로 드물게 hang → Stream Context 참조 release 안 됨 → FltUnregisterFilter 무한 대기 → 결과적으로 Unload 실패. ADS read를 PostCreate(자원 모두 푼 시점)로 이동하고, EX_PUSH_LOCK 전환·디버깅 RefTrack 추가·driver-analyst로 전수 코드 리뷰 17건 도출 후 P0 UAF(ProcessTable ProcPath freed 메모리 접근) 차단까지. 12커밋, 2일 작업.

커널 드라이버 MS 서명 프로세스 필터링 — SL 캡처 인프라부터 게이트 0까지 (OR-1350). 파일 삭제/오류 룰의 노이즈를 드라이버 단에서 차단하려면 각 프로세스 SignatureLevel이 안정적으로 필요. 두 단계로 정비: ① SL 캡처 인프라 — PsGetProcessSignatureLevel을 MmGetSystemRoutineAddress로 동적 해결(import 노출 회피), GetPreCreatedProcess 경로에서 EPROCESS->SignatureLevel 직접 조회, LoadImage가 ProcessNotify보다 먼저 떨어지는 레이스(Edge CREATE_SUSPENDED) 처리 위한 SignaturePending 캐시, 모듈 콜백 분리(LoadImageNotifyRoutineForCheckSignatureLevel). ② File 이벤트 Pre 필터의 게이트 0으로 SE_SIGNING_LEVEL_MICROSOFT(8) 이상이면 즉시 차단. 11커밋.

파일 삭제·오류 증상화 — Rule·드라이버·매니저 3축 동시 진행 (OR-1089). 파일 삭제/오류 탐지를 증상화하기 위해 Rule 세트(FileSharingViolation·FileNotFound 등)·드라이버 코드·매니저 증상 위젯 3축을 묶어서 추진. Rule 메타에는 CGID/CSID/SUID 식별자, evidence·Detail 마크다운 템플릿, priority 분기까지 명시. 공유 위반 시 점유자 식별과 삭제된 파일에 대한 STATUS_OBJECT_NAME_NOT_FOUND를 내부 deleted_file 테이블과 매칭하는 흐름이 핵심. 14커밋.

커널 드라이버 SE_SIGNING_LEVEL 한계 분석 + PE Authenticode 추출 방향 (OR-1423). Medium IL의 MS 서명 user-mode 앱(Code.exe, Teams.exe, Edge 메인, Office)은 OS가 CI 강제를 생략해 SignatureLevel이 영원히 0임을 Windows 11 26100.8493 실측(86건 SL=0 vs 0건 SL≥1)으로 확정. PsSetLoadImageNotifyRoutineEx + PS_IMAGE_NOTIFY_CONFLICTING_ARCHITECTURE 교체는 옳지만 실효 제한적임을 인정. ProcessNotify 시점에 IL Gate(Medium/High이고 SL<8일 때만) → PE 임베디드 서명 PKCS#7 파싱 → CN prefix 'Microsoft' 매칭 → PROCESS_ENTRY 캐시하는 Stage 2 구조 설계. 파일 이벤트당 비용 0, ProcessNotify 1회 PE 헤더 ~수 KB I/O로 한정.

WebView2 가상 호스트 매핑 — file:// → https://orange.local (OR-1404). orange.user.exe의 WebView2가 file:// 스킴을 opaque origin으로 취급해 같은 문서 안의 fragment navigation조차 cross-origin으로 분류되며 보안 경고가 source 라벨 두 개로 이중 출력되던 문제를, WebView2 가상 호스트 매핑(https://orange.local)으로 정식 origin (https, orange.local, 443) 튜플 위에서 풀었다. 프론트엔드 우회(createMemoryHistory, about:blank, v-if 가드)로는 스킴 정책을 제어할 수 없어 스킴 자체를 옮긴 정식 해결책.

Meter > 네트워크 모니터링 추가 — NetworkMonitor.dll (OR-1087). 기존 NetworkTrafficMonitor(MFC 독립 실행형)의 ETW 네트워크 수집 로직을 Meter 플러그인 아키텍처로 포팅. EVENT_TRACE_FLAG_NETWORK_TCPIP + SYSTEM_LOGGER_MODE로 프로세스별 TCP/UDP 송수신 바이트 실시간 캡처, GetIfTable2()로 활성 NIC 트래픽 합산, GetExtendedTcpTable/UdpTable로 네트워크 연결 보유 PID 탐지. Meter 관리자 권한 플러그인. 5커밋.

orange.sys 파일 삭제·오류 탐지 코드 점검 — 형식 필터 + 점유자 추적 (OR-1132). 함수 접두어가 DF·FF로 뒤섞여 있던 부분을 풀어쓰기로 통일하고, 파일 형식(pe·압축·dump 3종만 허용) 필터링을 추가해 파일 오류 탐지 개수를 획기적으로 감소. SHARING_VIOLATION 발생 시 실패한 FileObject로는 Stream Context 조회가 불가하므로 FltCreateFileEx2 + IO_IGNORE_SHARE_ACCESS_CHECK로 임시 열어 점유자 후보 수집, ECP 리스트로 미니필터 재진입 방지, 에이전트 자체 PID는 HolderEntryAdd에서 제외. 디버그용 @Orangelabs 치트 폴더로 모든 필터링 우회 가능.

파일 삭제·오류 필터링 시간 기반 throttle + LRU table 설계 (OR-1427). 기존 count % 100 == 1 throttle은 한 key가 지속 폭주해도 100건당 1건씩 무한 통과되어 폭주 자체를 못 막던 한계를, KeQueryUnbiasedInterruptTime 기반 시간 단위(10분당 1회)로 전환. hash table + ERESOURCE를 LRU array(512 entry, EX_PUSH_LOCK 8B)로 교체해 포화 시 전체 reset이 throttle을 무력화하던 문제까지 해소. 17조 회 케이스 기준 1,700억 건 notify → 4,320건으로 약 4천만배 절감. 시간 source가 sleep을 제외해 절전 직후 폭주도 차단. 진행 중 설계.

70건 중 61건 완료. 주력은 커널 드라이버(orange.sys, ofilter). 파일 삭제·오류 탐지, BSOD·데드락 디버깅 — 제품에서 가장 난도 높은 영역을 떠안았다. Windbg·Ghidra로 어셈블리를 읽고 lock-order까지 추론하는 깊이가 특징.


룰·분석 모델 + 고객사 통증 매핑

증상 → 1:N 명령 — 대응 워크플로우 단축 (OR-1154). 증상 노드 목록에서 '이 PC들 전체에 일괄 명령을 내려서 원인을 확인하고 싶다'는 현장 니즈가 가상 그룹 생성·노드 수동 추가·명령 위젯 호출의 10+클릭으로 끊겨 있던 흐름을 1클릭으로 단축. summaryNodes 위젯에 '1:N 명령' 버튼을 두고, nCommandMain 위젯이 autoCreateInitials prop을 감지해 대상 노드·제목이 미리 세팅된 채로 즉시 열리도록 설계. API 호출 없이 순수 클라이언트 동작으로 즉각 반응. 증상 분석에서 대응 명령까지의 단절을 해소한 UX 작업.

한 국립대 고객사 니즈 분석 — 49일 실측 + 국립대 전산실 통증 매핑 (OR-1420). 한 국립대 고객사가 우리 제품의 어떤 측면에서 가치를 느낄지 가설을 좁히기 위해, 49일치 매니저 실측 데이터(TCP 3,493 / DNS 2,574 / 비정상종료 268 / KillProcess 211 / CPU 점유 129건 등)와 7가지 데이터 축(시스템·앱·프로세스·네트워크·세션·ETW + 메타데이터)을 정리. 동시에 국립대 전산실의 6가지 구조적 조건(인력 부족·예산 제약·인프라 5~6팀 분산·감사 부담 등)과 10가지 통증(헬프데스크 본업 잡아먹기·장애 원인 책임 회피·다운타임 즉시 정치 폭탄 등)을 명확히 분리. 영업의 카운터파트는 기능 매칭이 아니라 통증 매칭이라는 결론으로 다음 미팅 전략을 정렬.

배포 패키지 Agent·룰 안정 버전 위치 정리 (OR-1059). 고객사에 배포되는 패키지에 들어갈 Agent 설치본과 룰의 안정 버전 산출물을 Orange-Package 한 곳에 모아 두는 정리 작업. 룰 분석·개선 본업과는 별개로, 배포 산출물 출처가 흩어져 있던 부분을 단일 위치로 정돈해 다음 패키지 빌드의 입력 경로를 단순화. 4커밋.

74건 중 33건 완료 — 완료율이 45%로 낮아 보이지만 일의 성격 때문. 그의 작업은 조사·분석·룰 설계가 많아 '진행 중/해야 할 일' 상태로 길게 열려 있는 것이 정상이다. 실제 고객사 데이터(운영 MongoDB의 수만 건 report·detect)를 직접 파고들어 노이즈를 걷어내고 룰과 분석 모델을 만드는 분석가. 진행 중 작업의 어플리케이션 행 룰(OR-1084)·프로세스 영향도(OR-1277)·자원사용률 계산 기준(OR-1334)·룰 priority 정리(OR-1088)·summary 컬렉션 통합(OR-1166)이 다음 축의 탐지 정확도 기반이다.


1년의 결

1년치 흐름을 한 줄로 요약하면 다음과 같다.

  • 서버가 임시 운영 환경에서 폐쇄망 무인 설치·이력 추적이 되는 정식 인프라(uv + 3.13 동봉, v0000 baseline migration, fail2ban, KISA 점검)로 정착했다.
  • 매니저가 일반 SPA에서 운영자가 직접 진단·대응할 수 있는 도구(현장 진단 패널, Z-score 기반 증상 라벨, RBAC, HTTP/2 + WOFF2)로 진화했다.
  • **에이전트(드라이버)**가 노이즈를 견디는 수집기에서 MS 서명 게이트·시간 기반 throttle·데드락 근본 해소·BSOD 분석기 마무리까지 갖춘 안정 컴포넌트로 강화됐다.
  • 분석이 데이터 더미에서 실측 49일 + 통증 매핑을 거친 룰·분석 모델 고도화로 옮겨가고 있다.
  • 그 모든 흐름이 동시에 진행될 수 있도록 AI 자동화 인프라(Claude Code 5종 정기 리뷰 루틴, Playwright MCP, Git/Jira 자동화)가 1년 사이 깔렸다.

다음 1년의 축은 (1) 상시 이상 탐지 + AI 자동화, (2) 권한 체계·서버 모니터링 마무리, (3) 파일 탐지·보안 점검 완성, (4) 룰·분석 모델 완성으로 좁혀진다.