보안·인프라 운영 직무 관련 프로젝트 포트폴리오
Github: https://github.com/twotwo-me/
GitHub-Project: BoB-Yamong | CCG-Platform | Shield4U
이 문서는 보안·인프라 운영 직무에서 요구하는 보안 솔루션 운영, 로그 분석·이슈 대응, 자동화, 인프라 동작 원리 이해와 연결되는 제 프로젝트 경험을 정리한 문서입니다.
저는 BoB-Yamong에서 eBPF/LSM 기반 컨테이너 보안 솔루션을 구현하면서, 운영자가 정책을 작성하고, agent가 컨테이너 메타데이터를 커널 식별자와 매핑하며, 이벤트가 Kafka·Analyzer·Alert·Grafana로 이어지는 운영 흐름까지 구성했습니다. 특히 부하 상황에서 로그와 알림이 누락되는 문제를 sequence number로 확인하고, userspace buffer와 Kafka/local storage 구조로 개선했습니다.
10년 이상 홈서버 인프라를 운영하며 구조를 점진적으로 개선하였습니다. Proxmox, OPNsense, VLAN, WireGuard, Authentik, Reverse Proxy를 이용해 관리망·서비스망·DMZ·실습망을 분리하고, 외부 노출 지점과 인증 흐름을 직접 운영했습니다. 단일 서버 운영에서 겪은 보안 사고와 CTF/AI-Infra 실험에서 얻은 시행착오를 바탕으로 VM/컨테이너 격리, VLAN 분리, 스냅샷 복구 구조까지 확장했습니다.
CCG-Platform에서는 Terraform, EKS, Karpenter, NetworkPolicy, RBAC, PodManager API를 다루며 사용자의 요청이 격리된 컨테이너 환경과 네트워크 라우팅으로 이어지는 자동화 흐름을 만들었습니다. Shield4U에서는 crawler, LLM analysis, Nuclei scanner, report 모듈을 controller 중심 API 구조로 연결했습니다.
채용 요건별 핵심 매핑
| 채용 요건 | 바로 연결되는 경험 |
|---|---|
| 네트워크, 엔드포인트, 시스템 전반의 보안 솔루션 운영 | BoB-Yamong에서 컨테이너의 네트워크 연결, 파일 접근, 프로세스 실행, syscall 이벤트를 eBPF/LSM으로 관찰·수집하고 정책 기반 제어 흐름을 구성했습니다. 3개 물리 Zone, 24개 노드, 20,000개 이상 컨테이너 규모를 전제로 컨테이너 식별과 정책 배포 흐름을 다뤘습니다. |
| 보안 설정 점검, 로그 분석, 이슈 대응 | 부하 상황에서 eBPF 로그와 알림이 누락되는 문제를 sequence number gap으로 확인하고, userspace buffer와 Kafka/local storage fallback 구조로 개선했습니다. 룰셋 적용 시 syscall별 즉시 탐지와 빈도 기반 탐지를 나누고 임계치 산정 가이드를 작성했습니다. |
| 자동화 도구 및 AI 활용으로 운영 효율 개선 | Terraform, Karpenter, GitHub Actions self-hosted runner, PodManager API, Shield4U의 LLM/Nuclei 기반 취약점 분석 자동화, AI-Infra 실험 환경을 다뤘습니다. |
| 정보보호/컴공 기본기와 인프라 동작 원리 이해 | cgroup, namespace, LSM hook, tracepoint, Ring Buffer, Kafka, Kubernetes, VLAN, WireGuard, OPNsense, DNS/TLS 라우팅을 프로젝트 안에서 연결해 설명할 수 있습니다. |
| API 연동, 스크립트 작성 등 자동화 경험 | FastAPI, Docker/Kubernetes API, Kafka producer/consumer, controller 기반 API 오케스트레이션, 배포 스크립트, GitHub Actions runner 운영을 경험했습니다. |
1. BoB-Yamong - 컨테이너 보안 솔루션 운영 경험
GitHub: bob-yamong
BoB-Yamong은 Best Of The Best 13기에서 진행한 컨테이너 보안 프로젝트입니다. eBPF/LSM 기반으로 컨테이너의 시스템 콜, 네트워크 연결, 파일 접근, 프로세스 실행 이벤트를 관찰·수집 하고 이를 Kafka로 전송하면 중앙 서비스에서 이벤트를 분석·알림·시각화·정책 기반 제어로 이어지는 운영 흐름을 함께 구성하였습니다. 3개 물리 Zone, 24개 노드, 20,000개 이상 컨테이너 규모에서도 컨테이너 식별, 정책 배포, 로그 안정성, 분석 결과 시각화까지 작동함을 확인하였습니다.
1.1. 맡은 범위
- eBPF 기반 컨테이너 보안 엔진 구조 이해와 구현 참여
- LSM hook은 정책 적용과 필요한 경우의 제어 지점으로 두고, tracepoint/raw tracepoint는 syscall 이벤트 관찰·수집 경로로 분리해 설계
- 컨테이너 식별을 위한 cgroup, PID namespace, mount namespace 활용 방식 정리
- Ring Buffer에서 user-space buffer로 이벤트를 빠르게 옮긴 뒤 Kafka로 전달하는 흐름 구성
- Kafka 기반 로그 분석, 탐지, 알림, Grafana 시각화 흐름과 Analyzer 출력 데이터 계약 연결
- Docker 기반 테스트 환경과 Kubernetes 기반 배포 환경 구성
- Jenkins에서 GitHub Actions self-hosted runner로 이어지는 CI/CD 환경 구성
- 3개 물리 Zone, 24개 노드, 20,000개 이상 컨테이너 규모의 테스트베드에서 통신·내부망 스캔·채굴 시나리오의 로그를 수집·분석하고 Grafana로 시각화하는 흐름 정리
- goorm 내부 개발환경에 LSM 기반 모니터링·제어 기능을 붙여 실제 개발환경에서 동작 확인
1.2. 프로젝트 구조
flowchart LR Policy["보안 정책<br/>YAML / CRD / API"] subgraph Node["Node / Host"] direction LR subgraph UserSpace["User space"] subgraph Workloads["컨테이너 프로세스 영역"] C1["Container A<br/>user processes"] C2["Container B<br/>user processes"] C3["Container C<br/>user processes"] end Agent["Security Agent<br/>metadata matching / event enrichment"] UserBuffer["User-space Buffer<br/>compression / local storage"] end subgraph KernelSpace["Kernel space"] Syscall["Syscall Boundary"] Hook["LSM Hook / Tracepoint / Raw Tracepoint"] BPFMap["BPF Map<br/>cgroup / namespace / policy key"] BPF["eBPF Program"] Ring["BPF Ring Buffer"] end Local["Local Storage"] end Policy --> Agent Agent -->|"컨테이너 메타데이터 매칭 후 정책 반영"| BPFMap BPFMap -->|"policy lookup"| BPF C1 -.->|"syscall / network / file / process"| Syscall C2 -.->|"syscall / network / file / process"| Syscall C3 -.->|"syscall / network / file / process"| Syscall Syscall --> Hook Hook --> BPF BPF -->|"event submit"| Ring Ring -->|"kernel → user boundary"| Agent Agent --> UserBuffer UserBuffer -->|"compressed events"| Kafka["Kafka Topic"] UserBuffer --> Local["Local Storage"] Kafka --> Analyzer["Analyzer<br/>탐지 결과 반환"] Kafka --> Alert["Alert Callback"] Kafka --> ML["ML Log Detection"] Analyzer --> Dashboard["Grafana Dashboard"] Alert --> Dashboard ML --> Dashboard
팀이 프로젝트에서 고민했던 핵심은 “컨테이너를 어떻게 보안 정책의 대상으로 다룰 것인가”였습니다. 컨테이너 이름이나 이미지 정보는 eBPF에서 식별할 수 없기 때문에, user-space agent가 Docker API나 Kubernetes API에서 얻은 메타데이터를 cgroup, PID namespace, mount namespace와 연결하고 그 결과를 BPF map에 반영하도록 했습니다.
컨테이너 내부 애플리케이션은 노드 관점에서는 user space 프로세스입니다. 그래서 각 컨테이너에 별도 모듈을 붙이는 대신, 컨테이너 프로세스가 시스템 콜을 통해 kernel space로 들어오는 경계에서 eBPF 프로그램이 이벤트를 관찰하고 정책을 조회하는 방식으로 구성했습니다. 동일한 이벤트 수집 시나리오에서 sidecar 방식과 비교했을 때, 컨테이너마다 별도 보안 프로세스를 붙이는 방식보다 eBPF 기반 공통 수집 구조가 더 낮은 런타임 오버헤드와 짧은 이벤트 감지 지연을 보이는 것을 확인했습니다.
이 프로젝트에서 보안 솔루션 운영 흐름은 다음처럼 이어졌습니다.
- 운영자가 정책을 작성합니다.
- 정책 대상 컨테이너를 이름, Pod, namespace, label 등으로 찾습니다.
- 컨테이너의 cgroup과 namespace 정보를 확인합니다.
- 정책을 BPF map에 반영합니다.
- LSM hook은 정책 적용과 필요한 경우의 제어를 담당하고, tracepoint/raw tracepoint는 시스템 콜 이벤트를 관찰·수집합니다.
- 모니터링 대상 이벤트는 Ring Buffer를 통해 사용자 공간으로 전달됩니다.
- userspace buffer와 local storage를 거친 이벤트가 Kafka를 통해 분석기, 알림, 대시보드로 흘러갑니다.
LSM hook을 통해 제어 지점을 잡을 때는 정책 범위와 시스템 콜 지정이 잘못되면 agent나 시스템 전체에 영향을 줄 수 있다고 보았습니다. 그래서 정책을 커널에 반영하기 전에 YAML 룰 검사기와 파싱 검증을 두어 형식 오류와 위험한 정책 조합을 먼저 걸러내는 구조를 설계했습니다.
Analyzer가 Kafka 이벤트를 받아 탐지 결과를 반환하고, 그 결과가 알림과 Grafana 시각화로 이어지도록 출력 데이터 계약과 연결 구조를 설계했습니다.
1.3. 네트워크·엔드포인트·시스템 전반의 관찰·수집과 정책 기반 제어
youmuu에서는 BPF LSM을 통해 파일, 네트워크, 프로세스 실행과 관련된 hook을 다뤘습니다. 예를 들어 socket_connect, socket_recvmsg는 네트워크 연결과 수신 행위를 다루고, file_open, path_unlink, inode_create는 파일 접근과 변경 행위를 다룹니다. bprm_check_security나 task_fix_setuid 같은 hook은 프로세스 실행과 권한 변화와 연결됩니다.
이 경험은 네트워크, 엔드포인트, 시스템 전반의 보안 솔루션 운영과 연결됩니다. 팀이 다룬 지점은 컨테이너 내부 프로세스가 OS와 만나는 경계였습니다.
| 관찰·수집 또는 제어 대상 | 프로젝트에서 다룬 방식 | 직무와 연결되는 지점 |
|---|---|---|
| 네트워크 연결 | socket_connect, socket_recvmsg 계열 LSM hook과 네트워크 정책 | 비정상 연결, 내부망 스캐닝, 허용되지 않은 통신 제어 |
| 파일 접근 | file_open, path_unlink, path_mkdir, path_rename, inode_create | 민감 경로 접근, 삭제, 생성 행위 감시 |
| 프로세스 실행 | bprm_check_security, syscall tracepoint | 셸 실행, 권한 상승, 의심 프로세스 실행 탐지 |
| 컨테이너 식별 | cgroup, PID namespace, mount namespace | 어떤 컨테이너에서 이벤트가 발생했는지 추적 |
| 정책 적용 | YAML 정책, Kubernetes 정책 리소스, BPF map | 운영자가 작성한 정책을 런타임 기준으로 연결 |
1.4. 정책 적용부터 로그 분석까지의 흐름
보안 솔루션은 탐지 로직만으로 운영되지 않습니다. 정책이 실제 대상에 적용되고, 모니터링 대상 이벤트의 누락 가능성을 줄이고, 분석 결과가 사람이 볼 수 있는 형태로 올라와야 합니다. BoB-Yamong에서 저는 이 연결 흐름을 중요하게 보았습니다.
sequenceDiagram participant Operator as 운영자 participant API as 정책 API 또는 CRD participant Agent as 컨테이너 보안 Agent participant Kernel as eBPF(LSM, Tracepoint) participant Kafka as Kafka participant Analyzer as Analyzer, Alert, ML participant Dashboard as Grafana Operator->>API: 보안 정책 작성 또는 수정 API->>Agent: 정책 대상과 기준 전달 Agent->>Agent: 컨테이너 메타데이터를 cgroup namespace와 매칭 Agent->>Kernel: BPF Map 갱신 Kernel->>Kernel: 이벤트(시스템 콜, 네트워크, 파일) 관찰 Kernel->>Agent: Ring Buffer로 이벤트 전달 Agent->>Kafka: 이벤트를 토픽별로 전송, 시스템 자원 정보 전송 Kafka->>Analyzer: 탐지기와 알림 처리기로 분기 Kafka->>Dashboard: 노드, 컨테이너별 자원 사용량 시각화 Analyzer->>Dashboard: 모니터링 대상 이벤트와 분석 결과 시각화
이 흐름에서 운영 관점으로 신경 쓴 부분은 다음과 같습니다.
- 정책 배포 단위: 여러 서버와 많은 컨테이너를 기준에 맞게 분류하고 정책을 배포해야 했습니다.
- 컨테이너 식별 정확도: 이벤트가 발생했을 때 프로세스 ID만 보는 것이 아니라 어떤 컨테이너와 연결되는지 확인해야 했습니다.
- 로그 전달 안정성: 커널에서 사용자 공간으로 넘어온 이벤트를 Kafka로 흘려 분석기와 알림이 사용할 수 있게 했습니다.
- 분석 가능성: syscall 로그를 그대로 쌓는 데서 끝나지 않고, 스캐닝, 마이닝, 취약점 악용 시나리오 같은 탐지기로 연결했습니다.
- 시각화와 대응: Grafana를 통해 운영자가 상태를 확인할 수 있는 형태로 만들었습니다.
1.5. 로그 분석 및 알림
| 컴포넌트 | 역할 | 운영 포인트 |
|---|---|---|
youmuu, gomumu | eBPF 기반 이벤트 수집과 정책 적용 | 커널 이벤트가 어떤 기준으로 수집되고 필요한 경우 제어되는지 |
youmuu-syslog | eBPF 이벤트와 syslog 연결 | 보안 이벤트를 기존 로그 체계와 연결하는 방식 |
kafka-sink-connect | Kafka 토픽에서 외부 저장소로 데이터 전달 | 로그 적재와 장기 분석을 위한 연결 방식 |
youmuu-analyzer | syscall 스트림 기반 탐지 | 마이닝, 스캐닝, Spring4Shell 같은 탐지 시나리오 |
kafka-alert | 토픽별 콜백 기반 알림 처리 | 운영 중 알림 로직을 추가·비활성화·정렬하는 구조 |
ML-log-detection | Kafka 로그 스트림 기반 이상 탐지 | 컨테이너 단위 버퍼링과 모델 추론 흐름 |
여러 모듈로 분리하여 로그를 처리하는 구조입니다. 운영 중에 운영자가 특정 토픽에 대한 처리 로직을 수정할 수 있는 구조로 설계하였습니다. 운영 중 모니터링 기준과 대응 로직을 어떻게 바꿀 것인가에 대해서 고민해볼 수 있었습니다.
운영 이슈 1: 부하 상황에서 로그와 알림이 누락되는 문제
부하 테스트 중 특정 행위를 반복했을 때 관련 로그와 알림이 분석 엔진까지 도달하지 않는 문제가 있었습니다. 이 문제를 확인하기 위해 eBPF에서 발생한 모든 로그에 디버깅 용도의 sequence number를 부여했고, 여러 변인들을 조절해보며 수신된 로그 번호 사이에 빈칸이 생기는지 확인했습니다.
문제는 eBPF 자체보다 이벤트 전달 경로에 있었습니다. 네트워크 전송을 제거하고 로컬에서 수신했을 때 syscall 손실률이 극도로 낮아졌고, Kafka 또는 네트워크 전송 구간의 병목이 생기면 Ring Buffer 소비가 늦어져 로그가 유실될 수 있다고 판단했습니다.
그래서 이벤트 로그를 먼저 userspace buffer로 옮기고, 이후 스트림 압축을 거쳐 Kafka와 local storage에 함께 저장하는 구조로 바꿨습니다. 개선 결과 커널 메모리 사용량이 줄었고, 수신 순서와 무관하게 sequence number를 기준으로 수집 결과를 대조했을 때 테스트 조건에서 수집 대상 syscall 이벤트의 결번이 발생하지 않는 것을 확인했습니다. CPU 사용률이 높아지는 상황에서도 시스템이 느려질 수는 있지만, 이벤트 전달 경로를 개선해 기존 구조에서 발생하던 로그 누락 문제를 해소한 사례입니다.
이후 다시 부하테스트를 진행하였습니다. 32코어 서버 환경에서 모든 코어의 CPU 사용률이 100% 도달하도록 100개 컨테이너가 각각 fork workflow를 10,000회 반복하는 테스트를 20회 수행했습니다. eBPF 감시가 없을 때는 평균 23.709초, eBPF 감시가 켜져 있을 때는 평균 24.960초가 걸렸고, fork, child exit, parent wait 이벤트를 기준으로 대략 초당 12만 개 수준의 syscall 이벤트가 발생했습니다. 이때 eBPF 모니터링으로 인한 성능 저하는 약 5.28% 수준으로 확인되었습니다.
운영 이슈 2: syscall 룰셋의 오탐·미탐 기준 정리
어떤 syscall은 1건만 발생해도 위험 신호로 볼 수 있지만, 네트워크 스캐닝이나 DDoS처럼 내부 서비스가 공격용으로 사용되는 경우에는 일정 빈도 이상이 되어야 의미 있는 탐지가 됩니다. 이러한 빈도를 파악하기 위한 방법으로 정상적인 상황에서 하루 이상 실제 서비스가 사용되는 동안의 syscall 빈도를 기준으로 삼고, 그 값에 비율 기반 가중치를 더해 임계치를 설정하는 가이드라인을 작성했습니다.
이렇게 임계치를 설정하니 서비스 상황에 따라서 미탐, 오탐 모두 발생할 수 있다는 점을 확인했습니다. 모든 상황에서 한 가지의 임계치만 가지고 판단하니 피크 시간에는 오탐, 비 피크 시간에는 미탐이 지속적으로 발생하였습니다. 탐지의 트리거가 되는 빈도가 서버 사양, 컨테이너 수에 따라서도 달라지지만, 시간별 서비스 트래픽에 따라 달라진다는 점을 간과하였습니다. 이를 보완하기 위해 단순 횟수만 보지 않고, 정상적인 행위자의 정상적인 시간대에 발생한 행위인지까지 고려하는 syscall-level ABAC 기준을 적용하여 오탐·미탐을 보완하였습니다.
1.6. CI/CD와 운영 자동화
이 프로젝트에서는 eBPF 빌드 환경 때문에 일반적인 hosted GitHub Actions만으로는 충분하지 않았습니다. eBPF 최신 기능을 검증하려면 커널 버전과 OS 환경이 중요했고, 그래서 Jenkins에서 시작한 CI/CD 흐름을 GitHub Actions self-hosted runner로 옮기는 판단을 했습니다.
제가 이 부분에서 중요하게 본 것은 두 가지였습니다.
- 팀원이 익숙한 GitHub Actions 흐름을 유지하면서도 OS와 커널 환경은 직접 통제하는 것
- 빌드 시간이 긴 eBPF 모듈과 일반 모듈의 검증 방식을 분리하는 것
빌드가 빠른 일반 모듈은 ephemeral runner로 깨끗한 환경에서 반복 검증하고, eBPF 모듈은 빌드 시간이 길어 일반 runner의 잔여 빌드 파일을 활용했습니다. 대신 dev/main 브랜치 PR이나 명시적 검증 시점에는 ephemeral runner에서 전체 빌드를 다시 수행했습니다. 이 과정에서 기존 빌드 산출물이 남아 있어 실제로는 문제가 있는 코드가 통과될 수 있는 사례를 확인했고, 주요 검증 경로에서는 깨끗한 환경에서 전체 빌드를 수행하도록 해 이를 방지했습니다. 이를 통하여 자동화는 스크립트를 한 번 작성하는 일이 아니라, 신뢰성과 검증 속도 사이의 균형을 잡는 일이라는 점을 배웠습니다.
1.7. 인프라 동작 원리와 연결되는 지점
- 컨테이너는 격리된 프로세스이지만, 커널 입장에서는 namespace와 cgroup으로 식별됩니다.
- Docker socket은 메타데이터를 얻는 데 사용할 수 있지만, 정책 적용 자체는 커널이 이해할 수 있는 식별자로 내려가야 합니다.
- eBPF LSM은 보안 결정을 커널 hook에서 내리기 때문에 강한 권한이 필요합니다.
- Ring Buffer는 커널 공간과 사용자 공간 사이에서 이벤트를 전달하는 통로가 됩니다.
- Kafka는 여러 분석기와 알림 처리기가 같은 이벤트 스트림을 나눠 사용할 수 있게 해 줍니다.
이 내용은 네트워크, 서버, OS, 컨테이너가 따로 있는 지식이 아니라 한 프로젝트 안에서 이어져야 하는 지식이었습니다.
2. Homeserver & Other
개인 홈서버는 개인용 서비스를 올려두면서 보안 인프라를 직접 나누고 운영해보는 실습 환경도 겸하고 있습니다. Proxmox VE 위에 VM과 LXC 컨테이너를 나누어 올리고, OPNsense, VLAN, WireGuard, Authentik, Nginx Proxy Manager 등을 조합해 관리망, 서비스망, DMZ, 프로젝트망, CTF/실습망을 분리했습니다.
- Proxmox VE 기반 VM/LXC 운영 환경 구성
- OPNsense를 활용한 내부망 라우팅과 네트워크 경계 구성
- VLAN 기반으로 관리, 서비스, DMZ, 프로젝트, CTF/실습 대역 분리
- WireGuard VPN을 통해 외부에서 내부 리소스에 접근하되, peer별 접근 가능 대역을 제한
- Authentik 기반 IdP 구성으로 내부 서비스 인증 흐름 정리
- Nginx Proxy Manager를 DMZ 성격의 Reverse Proxy 진입점으로 운영
- Self-hosted GitHub Actions Runner, 프로젝트 서비스, AI/자동화 서비스, CTF 풀이용 VM을 목적별로 분리 운영
- Proxmox firewall, VM/CT 단위 네트워크 설정, onboot/resource 설정 등을 보며 운영 상태 점검
2.1. 전체 구성
현재 홈서버는 Proxmox VE를 중심으로, VM과 LXC 컨테이너를 역할별로 나누어 운영하고 있습니다. 예를 들어 OPNsense는 네트워크 경계와 라우팅을 담당하고, Nginx Proxy Manager는 외부에서 들어오는 HTTP(S) 트래픽을 서비스별로 분기하는 진입점 역할을 합니다. Authentik은 내부 서비스 접근 시 인증을 담당하는 IdP로 두었고, CTF나 테스트용 VM은 별도 실습망에 배치해 일반 서비스망과 섞이지 않게 했습니다.
flowchart TD Internet["External Network"] --> OPNsense["OPNsense Firewall / Routing"] Remote["Remote Admin"] --> WireGuard["WireGuard VPN Peer별 접근 대역 제한"] OPNsense --> Manage["Manage VLAN Proxmox / 관리 접근"] OPNsense --> Service["Service VLAN Authentik / Runner / 내부 서비스"] OPNsense --> DMZ["DMZ VLAN Nginx Proxy Manager / WAF"] OPNsense --> Project["Project VLAN Capstone 등 프로젝트 워크로드"] OPNsense --> Lab["Danger / Lab VLAN CTF VM / 테스트베드"] DMZ --> Service Service --> Authentik["Authentik IdP"] Lab -. 격리 .- Service
| 영역 | 역할 | 실제 구성 예시 | 보안적으로 본 의미 |
|---|---|---|---|
| Manage | Proxmox와 네트워크 장비 관리 | Proxmox 관리, OPNsense 관리 | 관리 인터페이스를 일반 서비스 트래픽과 분리 |
| VPN | 외부 관리 접근 | WireGuard | peer별 허용 대역을 제한해 원격 접속 범위 축소 |
| Service | 내부 서비스 운영 | Authentik, Runner, 개인 서비스 | 인증과 내부 서비스 운영 영역 분리 |
| DMZ | 외부 노출 진입점 | Nginx Proxy Manager, WAF | 외부 요청이 바로 내부 서비스망으로 닿지 않도록 완충지대 구성 |
| Project | 개발·프로젝트 워크로드 | Capstone 관련 VM/CT | 프로젝트 서비스와 개인 관리망 분리 |
| Danger / Lab | CTF·테스트 환경 | CTF-AGENT, CTF-Wiki, FLAG, Test-Bed 등 | 공격 실습·취약 환경을 일반 서비스망과 격리 |
2.2. 네트워크 분리와 접근 제어
홈서버에서 가장 신경 쓴 부분은 VLAN을 접근 제어의 기준으로 사용한 점입니다. 관리용 대역, 일반 서비스 대역, DMZ, 프로젝트 대역, CTF/실습 대역을 분리하고, 각 VM과 컨테이너를 목적에 맞는 네트워크에 붙였습니다.
예를 들어 CTF 풀이용 VM이나 테스트베드는 의도적으로 위험한 파일, 취약한 서비스, 공격 도구가 들어갈 수 있는 환경입니다. 이런 VM을 일반 서비스나 인증 시스템과 같은 대역에 두면 실습 환경의 위험이 운영 서비스로 번질 수 있습니다. 그래서 CTF 관련 VM은 별도 실습망으로 분리하고, 망간의 통신은 모두 방화벽을 통해 필요한 접근만 허용하는 방향으로 구성했습니다.
WireGuard도 단순히 “VPN으로 내부망에 접속한다”가 아니라, peer마다 접근 가능한 네트워크 대역을 다르게 두는 방식으로 사용했습니다. 개인 관리용 peer, 특정 서비스 접근용 peer, 외부 사용자 peer 등 각 peer가 접근할 수 있는 네트워크 대역을 제어하여, 원격 접속 자체도 최소 권한에 가깝게 운영하려고 했습니다.
2.3. DMZ, Reverse Proxy, 인증 흐름
외부에 노출되는 서비스는 Nginx Proxy Manager를 앞단에 두고, 내부 서비스로 직접 들어오지 않도록 했습니다. 이 영역은 DMZ 성격으로 보고, 외부 요청을 받아 라우팅하되 내부 서비스망과는 역할을 분리했습니다. 여기에 WAF나 프록시 정책을 붙일 수 있는 구조로 만들었습니다.
인증은 Authentik을 별도로 운영해 내부 서비스 접근 흐름을 한 곳에서 관리할 수 있게 구성했습니다. 모든 서비스가 각각 독립적으로 계정과 인증을 관리하면 운영이 복잡해지고 권한 회수가 어려워집니다. 그래서 가능한 서비스는 IdP 중심으로 묶고, Reverse Proxy와 인증 흐름을 함께 고려하는 방식으로 구성했습니다.
서비스 성격에 따라 인증 방식도 나누었습니다. OIDC/SAML 같은 IdP 연동을 지원하는 서비스는 Authentik을 정식 Identity Provider로 붙여 로그인과 권한 관리를 한 곳에서 처리하게 했고, 자체적으로 IdP 연동이 어렵거나 앞단에서 보호하는 편이 더 단순한 서비스는 Reverse Proxy의 Forward Auth 흐름을 사용했습니다. 이 경우 사용자가 서비스에 접근하면 먼저 Authentik으로 리다이렉트되어 인증을 거치고, 인증이 끝난 요청만 내부 서비스로 전달되도록 구성했습니다. 덕분에 서비스 자체에 인증 기능이 약하더라도, 외부 노출 지점에서는 동일한 인증 관문을 적용할 수 있었습니다.
이 경험은 보안 솔루션을 단순히 설치하는 것보다, 어떤 트래픽을 어디에서 받고, 어디까지 통과시키고, 어떤 인증을 거치게 할지를 계속 점검하는 일에 가까웠습니다.
2.4. Proxmox 운영 관점에서 본 경험
Proxmox에서는 VM과 LXC 컨테이너를 섞어 사용했습니다. OPNsense처럼 개별의 운영체제가 필요한 경우는 VM으로 운영하고, Nginx Proxy Manager나 Authentik처럼 가벼운 서비스는 LXC 컨테이너로 분리하여 운영하였습니다. 각 VM/LXC가 어떤 네트워크에 속하고 어떤 경계 안에서 동작해야 하는지를 함께 확인하고, 상시 구동이 필요한 서비스와 실습용 VM을 구분한 뒤, 부팅순서, VLAN, 방화벽, 외부 노출 여부를 고려해 서비스 배치를 조정했습니다.
2.5. 사고 기반 구조 개선 경험
홈서버를 오래 운영하면서 단순한 설정 실수부터 물리 장애, 보안 사고, 실험 환경의 위험까지 여러 시행착오를 겪었습니다. 하드웨어 장애를 겪은 뒤에는 UPS, 전력 사용량 측정, 물리 부저, 휴대폰 알림을 붙여 전원 이상을 더 빨리 확인할 수 있게 했습니다.
단일 Ubuntu 서버에서 여러 서비스를 함께 운영하던 시기에는 보안 사고를 겪은 뒤 서비스를 VM 또는 컨테이너 단위로 분리하는 방향으로 구조를 바꿨습니다. Proxmox 기반으로 이전하고, 외부 접근은 방화벽과 지리적 IP 차단, Nginx, WAF 앞단을 거치도록 구성하여 서비스별 신뢰 경계를 더 명확히 나누게 되었습니다.
CTF 문제나 취약점 테스트 환경을 운영하면서는 외부와 내부 사이의 방화벽만으로는 충분하지 않다는 점도 확인했습니다. 같은 호스트 안의 내부 가상 NIC끼리 통신하면 경계 방화벽을 거치지 않을 수 있기 때문에, CTF/실습 환경은 VLAN으로 분리하고 OPNsense를 통해 정책을 적용하는 구조로 바꿨습니다.
AI-Infra 제어 실험에서도 비슷한 교훈을 얻었습니다. AI 에이전트에 Proxmox 제어 권한을 크게 부여했을 때 잘못된 제어가 발생할 수 있다는 점을 확인했고, 이후 별도 Proxmox 장비와 IPKVM, 스냅샷 백업이 가능한 환경을 구성하여 AI-Infra 제어를 계속 테스트하고 있습니다.
2.6. 보안 직무 관점에서의 의미
이 홈서버 경험은 보안 인프라 운영에서 자주 나오는 질문들을 직접 적용해본 경험입니다.
- 관리 인터페이스와 일반 서비스 트래픽을 같은 네트워크에 둘 것인가?
- 외부에 직접 노출되는 지점은 어디로 제한할 것인가?
- VPN 사용자가 내부 전체를 볼 수 있게 할 것인가, 필요한 대역만 보게 할 것인가?
- 인증은 서비스마다 흩어둘 것인가, IdP 중심으로 묶을 것인가?
- 위험한 실습 VM이나 CTF 환경은 운영 서비스와 어떻게 분리할 것인가?
- 프로젝트용 임시 서비스와 장기 운영 서비스를 같은 신뢰 수준으로 볼 것인가?
이 질문들을 Proxmox, OPNsense, VLAN, WireGuard, Authentik, Reverse Proxy 구성 안에서 계속 다뤘습니다. 그래서 이 경험은 작은 규모의 환경에서 네트워크 분리와 접근 제어, 인증, DMZ, 실습망 격리를 직접 설계하고 운영해본 경험으로 정리할 수 있습니다.
3. CCG-Platform - 인프라 자동화와 네트워크 라우팅 경험
GitHub: ccg-platform
CCG-Platform은 사용자가 웹에서 요청하면 게임별 컨테이너와 Pod를 동적으로 만들고, coturn/TURN 경로를 통해 사용자와 저지연으로 트래픽을 교환할 수 있게 하는 클라우드 게임 플랫폼 프로젝트입니다. 인프라 운영·네트워크·자동화 부분을 잘 보여줄 수 있을 것 같아 추가하였습니다.
제가 이 프로젝트에서 설명하고 싶은 부분은 사용자 요청이 PodManager API를 거쳐 사용자용 컨테이너 생성, coturn/TURN 기반 트래픽 교환, Terraform/EKS/Karpenter 기반 자원 배포까지 이어지는 흐름입니다.
3.1. 맡은 범위
- 팀장 역할로 POC, demo, TerraformLearn, PodManager 흐름을 이어가는 구조 정리
- AWS EKS 기반 인프라를 Terraform으로 구성
- Karpenter 기반 CPU 노드 풀 및 GPU Warm Pool 설계
- PodManager API를 통해 Pod, Service, IngressRoute, NetworkPolicy를 생성하는 흐름 설계
- NetworkPolicy와 RBAC을 통한 최소 권한과 사용자 워크스페이스 격리 구조 정리
- Traefik, Cloudflare, cert-manager를 이용한 라우팅·DNS·TLS 흐름 연결
3.2. 프로젝트 구조
flowchart TD User["사용자 요청<br/>워크스페이스 생성"] --> Portal["Portal Backend"] Portal --> PodAPI["PodManager API"] subgraph K8s["Kubernetes Cluster"] PodAPI --> Template["Jinja2 Template Rendering"] Template --> Pod["Pod"] Template --> Svc["Service"] Template --> Ingress["IngressRoute"] Template --> Netpol["NetworkPolicy"] Template --> Cleanup["Session Cleanup"] end Terraform["Terraform EKS VPC IAM"] --> K8s Karpenter["Karpenter CPU GPU NodePool"] --> K8s DNS["Cloudflare ExternalDNS cert-manager"] --> Ingress Ingress --> Traefik["Traefik Routing"] Traefik --> Coturn["coturn / TURN Server"] Coturn --> Workspace["사용자 전용 컨테이너 접속<br/>고속 트래픽 교환"]
이 흐름은 인프라 운영 관점에서 다음 경험으로 정리할 수 있습니다.
- 사용자의 요청을 Kubernetes 리소스 생성과 coturn/TURN 기반 접속 흐름으로 바꾸는 API 설계
- 컨테이너마다 필요한 Pod, Service, IngressRoute, NetworkPolicy를 템플릿으로 생성
- 외부에 직접 노출하지 않는 내부 PodManager API 구조
- 사용자별 워크스페이스 격리를 위한 NetworkPolicy
- RBAC을 통한 PodManager 권한 범위 제한
- DNS, TLS, coturn/TURN을 포함한 접속 경로 구성
- GPU 워크로드 특성 때문에 노드 자동 확장과 Warm Pool을 함께 고민
3.3. 보안 설정 점검 항목
| 설정 영역 | 내용 | 보안/운영 의미 |
|---|---|---|
| RBAC | PodManager가 필요한 Kubernetes 리소스만 다루도록 권한 구성 | 내부 API의 권한 범위를 줄임 |
| NetworkPolicy | 사용자 Pod 사이의 네트워크 격리 | 워크스페이스 간 불필요한 접근 차단 |
| IngressRoute | 사용자 세션별 라우팅 | 외부 접속 경로를 명시적으로 제어 |
| cert-manager | TLS 인증서 자동화 | 수동 인증서 관리 실수 감소 |
| ExternalDNS/Cloudflare | DNS 레코드 자동 반영 | 배포와 접속 경로의 일관성 유지 |
| Karpenter | 워크로드 기반 노드 확장 | 비용과 응답 속도 사이의 운영 균형 |
3.4. 자동화 설계
CCG-Platform에서 자동화는 크게 두 층으로 나뉩니다.
첫째, 인프라 생성 자동화입니다. TerraformLearn에서는 VPC, EKS, IAM, Karpenter, Traefik, ExternalDNS, cert-manager 같은 인프라 요소를 코드로 관리했습니다. 개발 과정에서 인프라를 항상 켜둘 수 없었기 때문에, Terraform으로 재현 가능한 설정을 남기고 필요할 때만 환경을 생성해 사용했습니다.
둘째, 런타임 리소스 생성 자동화입니다. PodManager_V2에서는 사용자가 요청할 때마다 Pod, Service, IngressRoute, NetworkPolicy를 조합해 만들고, 사용자용 컨테이너가 coturn/TURN 경로로 연결될 수 있게 해야 했습니다. 게임별 프로파일과 세션별 라우팅이 달랐기 때문에 Jinja2 템플릿으로 리소스를 생성하는 구조를 잡았습니다.
4. Shield4U - API 오케스트레이션과 AI 활용 경험
GitHub: hackerspace-Shield4U
Shield4U는 해커톤에서 만든 웹 취약점 탐지 서비스입니다. 짧은 시간 안에 진행한 프로젝트이지만 당장의 완성도보다 추후 확장시킬 수 있는 구조를 중점으로 진행하였습니다. 제가 여기서 강조하고 싶은 부분은 crawler, LLM analysis, scanner, report 같은 보안 분석 모듈을 controller 중심 API 구조로 연결한 점입니다. LLM은 이 구조 안에서 크롤링 결과를 해석하고 Nuclei 스캔 전략과 보고서 생성으로 이어주는 모듈로 사용했습니다.
4.1. 맡은 범위
- 팀장으로서 전체 서비스 구조와 통신 규약 정리
- 중앙 controller 기반 라우팅 구조 설계
- crawler, llm, scanner, report 서비스의 입력·출력 연결
- Docker Compose 기반 서비스 오케스트레이션 구조 정리
- LLM 분석 결과를 Nuclei 스캔 규칙과 보고서 생성으로 연결하는 흐름 설계
- API 콜백 기반으로 각 모듈이 작업 결과를 controller에 되돌려주는 구조 정리
4.2. 프로젝트 구조
보안 스캔은 수집 → 분석 → 스캔 → 보고서처럼 항상 한 방향으로만 끝나지 않습니다. 어떤 URL은 추가 크롤링이 필요하고, 어떤 결과는 바로 스캔으로 넘어갈 수 있으며, 어떤 결과는 보고서에만 반영하면 됩니다. 그래서 Shield4U에서는 중앙 controller가 각 모듈의 결과를 받아 다음 목적지를 정하는 구조를 잡았습니다.
flowchart TD Request["사용자 스캔 요청"] --> Controller["Controller<br/>상태 추적과 라우팅"] Controller --> Crawler["Crawler<br/>URL Form Script Fingerprint 수집"] Crawler --> Controller Controller --> LLM["LLM Analysis<br/>취약 가능성 분류와 스캔 전략 생성"] LLM --> Controller Controller --> Scanner["Scanner<br/>Nuclei Template 실행"] Scanner --> Controller Controller --> Report["LLM Report<br/>결과 보고서 생성"] Report --> Controller Controller --> DB["MariaDB<br/>작업 상태와 결과 저장"]
각 모듈은 독립 서비스로 두되, controller가 상태와 다음 행동을 관리하게 했습니다. 새 보안 도구를 붙이려면 입력과 출력 형식만 맞추면 전체 흐름에 연결할 수 있게 만들고 싶었습니다.
4.3. AI를 운영 효율 개선에 사용한 방식
Shield4U에서 LLM은 전체 구조의 중심이라기보다, controller가 호출하는 분석 모듈 중 하나였습니다. 크롤러가 수집한 URL, 폼, 스크립트, 기술 지문 정보를 바탕으로 어떤 취약점 가능성을 볼지 판단하고, Nuclei 템플릿 실행으로 이어지는 중간 결과를 만들었습니다.
sequenceDiagram participant User as User participant Controller as Controller participant Crawler as Crawler participant LLM as LLM Analysis participant Scanner as Nuclei Scanner participant Report as Report LLM User->>Controller: 대상 URL 입력 Controller->>Crawler: 대상 URL 크롤링 요청 Crawler->>Controller: 링크 폼 스크립트 기술 지문 반환 Controller->>LLM: 구조화된 크롤링 결과 분석 요청 LLM->>Controller: 취약 가능성 태그와 스캔 전략 반환 Controller->>Scanner: Nuclei 템플릿 실행 요청 Scanner->>Controller: 취약점 스캔 결과 반환 Controller->>Report: 분석 결과 기반 보고서 생성 요청 Report->>Controller: 최종 보고서 반환 Controller->>User: 최종 보고서 출력
이 경험에서 제가 배운 점은 AI를 운영 흐름에 넣을 때, AI가 모든 것을 직접 실행하게 두는 것보다 구조화된 중간 산출물을 만들게 하고 실제 실행은 검증된 도구에 맡기는 편이 안전하다는 점입니다. Shield4U에서는 LLM이 직접 페이로드를 실행하는 대신, Nuclei가 사용할 수 있는 템플릿과 스캔 전략으로 연결되도록 했습니다.
4.4. 보안 도구 통합 경험
Shield4U의 scanner는 Nuclei와 통합된 취약점 스캐닝 서비스입니다. 사용자 정의 YAML 템플릿, 타겟 검증, 템플릿 분류, 실행 결과 파싱을 다뤘습니다. crawler는 Selenium과 BeautifulSoup을 사용해 페이지 구조, 폼, 링크, 스크립트, 기술 지문, 로그인 패널 후보, OSINT 노출 정보를 수집했습니다.