500개 이상의 보안 용어를 검색 가능한 용어집으로 색인화하며 지식 베이스(Knowledge Bases)에 대해 배운 점
요약
사이버 보안 용어집을 구축하며 500개 이상의 데이터를 체계적인 지식 베이스로 색인화한 경험을 공유합니다. MySQL, Meilisearch, Go Fiber를 활용한 기술 스택과 데이터베이스 설계 및 카테고리 구조화의 중요성을 다룹니다.
핵심 포인트
- MySQL의 UNIQUE 제약 조건을 통한 데이터 무결성 확보
- Meilisearch를 활용한 전문 검색(Full-text search) 구현
- 데이터 정의보다 카테고리 분류 체계 설계가 우선되어야 함
- 확장성을 고려한 데이터베이스 스키마 설계의 중요성
약 8개월 전, 저는 제가 운영하는 사이버 보안 사이트에 제대로 된 용어집(Glossary)이 필요하다고 결정했습니다. 단순히 50개의 정의가 담긴 정적인 페이지가 아니라, 카테고리별로 정리되고 각 용어마다 적절한 정의, 관련 용어, 난이도, 그리고 깔끔한 URL을 갖춘 진정한 검색 가능한 지식 베이스(Knowledge Base)를 만들고자 했습니다. 현재 저희는 8개 카테고리에 걸쳐 500개 이상의 용어를 보유하고 있습니다: Active Directory (102개), 일반 보안 (General Security, 101개), AI 보안 (AI Security, 100개를 목표로 작업 중), 해킹 (Hacking, 100개를 목표로 작업 중), 컴플라이언스 (Compliance), 클라우드 보안 (Cloud Security), DevSecOps, 포렌식 (Forensics), 그리고 OT/ICS입니다. 백엔드는 MySQL을 사용하고, 프론트엔드는 전문 검색(Full-text search)을 위해 Meilisearch를 사용하며, 전체 시스템은 Go Fiber 애플리케이션의 일부로 구축되었습니다. 제가 이를 구축하며 실제로 배운 점들을 공유하고자 합니다.
데이터베이스는 UNIQUE 제약 조건으로 고유성을 강제합니다: CREATE TABLE glossary_terms ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY , term VARCHAR ( 255 ) NOT NULL , slug VARCHAR ( 255 ) NOT NULL UNIQUE , category ENUM ( 'general' , 'active-directory' , 'ia' , 'hacking' , 'conformite' , 'cloud' , 'devsecops' , 'forensics' , 'ot' ) NOT NULL , definition TEXT NOT NULL , difficulty TINYINT UNSIGNED DEFAULT 1 COMMENT '1=beginner, 2=intermediate, 3=expert' , related JSON COMMENT 'array of related term slugs' , sources JSON COMMENT 'array of {title, url} objects' , created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP , updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , INDEX idx_category ( category ), INDEX idx_difficulty ( difficulty ), FULLTEXT INDEX ft_term_def ( term , definition ) ); slug에 대한 UNIQUE 제약 조건은 삽입 시 충돌 발생을 강하게 실패(fail hard)시키는데, 이는 올바른 동작입니다. 처리할 수 있는 실패한 삽입이 기존 용어의 조용한 덮어쓰기보다 낫습니다. 카테고리 분류 체계가 정의보다 더 중요합니다. 초반에는 좋은 정의를 작성하는 데 집중했습니다. 제가 먼저 제대로 집중했어야 할 것은 카테고리 구조를 잡는 것이었습니다. 원래 제 카테고리는 너무 광범위했습니다. 전체 용어집이 보안에 관한 것인데, 'Security'라는 카테고리는 의미가 없습니다. 현재 구조를 확립하기까지 다섯 번이나 분할했습니다. 데이터베이스에 이미 200개의 용어가 있는 상태에서 카테고리를 재구성하는 문제는 모든 용어의 배치를 다시 검토해야 하고, 모든 카테고리 필터링 검색 인덱스를 업데이트하며, 카테고리 랜딩 페이지를 재생성해야 한다는 것입니다. Active Directory 카테고리는 가장 많이 방문되는 곳이었습니다 — 102개의 용어를 보유했으며, 명확하게 정의된 범위(AD, LDAP, Kerberos, GPO, LDAP injection, pass-the-hash, BloodHound 등과 관련된 모든 것), 그리고 분명한 독자층(시스템 관리자 및 침투 테스터)을 가지고 있습니다. 카테고리 일관성은 독자와 검색 클러스터 결과에 중요합니다.
어떤 지식 베이스(Knowledge Base)에도 적용할 수 있는 교훈이 있습니다. 분류 체계(Taxonomy)를 확정하기 전에 각 카테고리당 최소 10개의 예시 용어를 설계해 보십시오. 중복 없이 10개의 명확한 예시를 생성할 수 없다면, 귀하의 카테고리 설정이 잘못된 것입니다. LLM(대규모 언어 모델)이 생성한 정의는 반드시 인간의 검토가 필요합니다. 특히 CVE(Common Vulnerabilities and Exposures)의 경우, 저는 정의의 상당 부분을 LLM을 사용하여 초안을 작성했습니다. 500개 이상의 용어 규모에서 소규모 팀이 모든 정의를 처음부터 직접 작성하는 것은 불가능합니다. 초안 작성 속도는 진정으로 유용합니다. 문제는 정확도의 편차입니다. RSA, TLS 핸드셰이크 (TLS handshake), SQL 인젝션 (SQL injection), VLAN과 같이 학습 데이터가 풍부하고 잘 정립된 용어의 경우, 약간의 수정만 거치면 초안이 훌륭했습니다. 하지만 특정 CVE, 니치(niche)한 공격 기법, 또는 최근 추가된 항목(2024년 중반 이후의 모든 것)의 경우 품질이 급격히 떨어졌습니다. 모델은 취약점 패턴은 정확하게 설명했지만, 잘못된 CVSSv3 점수를 부여하거나, 잘못된 영향 버전, 또는 잘못된 발견 시점을 기술하곤 했습니다. 저의 검토 프로세스는 다음과 같이 변했습니다. 일반적/개념적 용어는 빠르게 읽은 후 정의를 자동 승인하고, CVE 관련 사항이나 버전별 기술적 주장이 포함된 모든 항목은 반드시 수동으로 사실 확인(Fact-checking)을 수행하는 방식입니다. 특히 CVE 정의는 NVD(National Vulnerability Database) 항목과 교차 참조가 반드시 필요합니다. 돌이켜보면 당연한 이야기처럼 들립니다. AI 보안 카테고리의 경우, 용어 환경 자체가 매우 빠르게 진화하고 있어 정의를 초안 형태로 작성하기보다는 새로 작성해야 했습니다. 개념들이 너무 최신이고 소스마다 정의가 너무 일관되지 않아, LLM이 이에 대해 신뢰할 수 있는 학습 신호(Training signal)를 갖기에는 무리가 있었습니다. 용어집에 대한 검색에는 퍼지 매칭 (Fuzzy matching)이 필요합니다. 정적인 MySQL FULLTEXT 인덱스는 사용자가 "kerberosting"('a' 누락), "phising"('s' 하나 누락), 또는 "ransomwar"(끝 글자 누락)를 검색하기 전까지는 잘 작동합니다. 이것들은 로그에서 확인된 실제 쿼리들입니다. 완전 일치(Exact-match) 방식의 Fulltext 검색은 아무것도 반환하지 않습니다. Meilisearch는 이러한 상황을 별도의 설정 없이도 훨씬 더 잘 처리합니다.
오타 허용(typo-tolerance) 기능은 설정이 가능하며, 거의 모든 쿼리가 기술 용어인 용어집의 경우 다음과 같은 설정이 적합합니다:
minWordSizeForTypos.oneTypo: 4— 4자 이상의 단어에 대해 1개의 오타 허용minWordSizeForTypos.twoTypos: 8— 더 긴 단어에 대해 2개의 오타 허용- 검색 가능한 속성(searchable attributes)을
["term", "definition"]으로 설정하되,term일치 항목의 순위(rank)를 더 높게 설정
기술 용어집에서 정확한 일치(exact-match) 검색과 오타 허용(typo-tolerant) 검색 사이의 사용자 경험 차이는 상당합니다. 누군가가 "kerberosting"을 검색했는데 결과가 나오지 않는다면, 그 사람은 다시 검색하지 않고 사이트를 떠나버립니다.
기대보다 더 효과적이었던 부분들
관련 용어를 연결한 것은 충분히 가치 있는 노력이었습니다. 한 용어가 다른 3~4개의 슬러그(slug)를 가리키는 관련 배열(related array)을 가지고 있을 때, 독자들은 세션당 두 배 이상의 페이지를 탐색합니다. 이해의 깊이가 중요한 지식 베이스(knowledge base)의 경우(예를 들어, NTLM 해시를 이해하지 못하면 pass-the-hash를 이해할 수 없고, 이는 다시 인증 프로토콜에 대한 이해를 요구합니다), 이러한 링크들은 막다른 길이 아닌 학습 경로를 만들어 줍니다.
난이도 설정 또한 제가 완전히 예상하지 못했던 방식으로 유용했습니다. "초급(beginner)" 용어로 필터링하면 일관된 입문 경로를 제공할 수 있습니다. 최종적인 분포는 대략 초급 20%, 중급 60%, 전문가 20%로 나타났는데, 이는 신입보다는 실무자가 대부분인 대상 독자층에게 적절하게 느껴졌습니다.
이 용어집은 AYI NEDJIMI Consultants의 광범위한 콘텐츠 라이브러리의 일부이며, 이곳에서는 네트워크 강화(network hardening), 컴플라이언스 프레임워크(compliance frameworks), 위협 분석(threat analysis) 등 실무적인 보안 주제도 다룹니다. 보안 분야에 종사하신다면, 사이트에서 가장 실용적으로 유용한 것은 아마 무료 강화 체크리스트(hardening checklists)일 것입니다. FortiGate, pfSense, Sophos, Active Directory, Windows Server, Linux, DNS 보안 등을 위한 17개의 체크리스트가 준비되어 있습니다.
이 프로젝트를 구축하면서 저는 사이버 보안 자체보다 분류 체계(taxonomy) 설계와 검색 관련성 조정(search relevance tuning)에 대해 더 많은 것을 배웠습니다. 지식 베이스 프로젝트에서 발생하는 기술적 문제들은 대부분 여러분이 예상하는 것과는 다릅니다.
저는 사이버 보안 컨설팅 기업인 AYI NEDJIMI Consultants를 운영하고 있습니다. 저희는 FortiGate, Palo Alto, pfSense, Sophos, Active Directory 등을 위한 무료 보안 강화 (Security Hardening) 체크리스트를 PDF 및 Excel 형식으로 발행하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기