[CS300 #260] 제로 트러스트 — 안쪽이라는 이유만으로 믿지 않는다
컴퓨터공학 300 주제 시리즈의 260번째 글이다. 전체 지도는 여기.
한 줄 요약
제로 트러스트는 네트워크 위치(사내망, VPN 안쪽)를 신뢰의 근거로 삼지 않고, 모든 자원 접근을 요청마다 신원·기기 상태·맥락으로 평가해 최소 권한으로 허용하는 보안 설계 원칙이다. 제품 이름이 아니라 아키텍처의 방향이다.
왜 필요한가
전통적인 경계 모델은 성곽과 해자다. 방화벽 바깥은 위험하고 안쪽은 안전하다. VPN 으로 들어오면 내부 사용자와 같은 대접을 받는다. 이 모델은 몇 가지 현실 앞에서 무너졌다.
- 경계가 사라졌다: 업무 시스템이 클라우드·SaaS 에 있고, 직원은 집과 카페에서 일한다. “안쪽” 이 어디인지 정하기 어렵다.
- 한 번 뚫리면 끝: 피싱으로 직원 노트북 하나가 장악되면 공격자는 “안쪽 사용자” 가 된다. 평평한 내부망에서는 옆으로 이동하기 쉽다. 이 시리즈의 침해 사고 대응 글에서 본 시나리오가 전형이다.
- 내부자와 공급망: 위협이 항상 바깥에서 오지 않는다.
NIST SP 800-207(2020)은 제로 트러스트를 “방어를 정적인 네트워크 경계에서 사용자·자산·자원 중심으로 옮기는 일련의 사이버보안 패러다임” 으로 정의한다. 이 시리즈에서 다룬 인증·인가, 최소 권한, 암호화, 로깅이 하나의 설계로 모이는 지점이다.
핵심 개념
NIST 의 일곱 가지 원칙(tenets)
SP 800-207 의 원칙을 요약한다.
- 모든 데이터 소스와 컴퓨팅 서비스를 자원으로 본다(개인 기기, SaaS 포함).
- 모든 통신은 네트워크 위치와 무관하게 보호한다. 사내망이라는 이유로 평문 통신을 허용하지 않는다.
- 개별 자원 접근은 세션 단위로 허가한다. 한 자원의 인증이 다른 자원 접근을 자동으로 허락하지 않는다.
- 접근은 동적 정책으로 결정한다. 신원, 애플리케이션, 요청 자산의 관측 가능한 상태, 행동·환경 속성을 포함한다.
- 조직은 소유한 모든 자산의 무결성과 보안 상태를 감시·측정한다.
- 모든 인증과 인가는 동적이며 접근 전에 엄격히 시행한다.
- 자산·네트워크 인프라·통신의 현재 상태 정보를 최대한 수집해 보안 수준 개선에 쓴다.
논리 구성 요소
┌───────────── 제어 평면 ─────────────┐
│ PE (정책 엔진) ── 결정 │
│ PA (정책 관리자) ── 세션 설정·해제 │ ← 신원, 기기 상태,
└──────────────┬──────────────────────┘ 위협 정보, 로그,
│ 데이터 접근 정책
[주체: 사용자+기기] ──> PEP (정책 시행 지점) ──> [자원]
└───────────── 데이터 평면 ─────────────┘
- PE(Policy Engine): 접근 허가 여부를 최종 결정한다. PE 와 PA 를 합쳐 PDP(정책 결정 지점)라 한다.
- PA(Policy Administrator): PE 의 결정에 따라 주체와 자원 사이의 통신 경로를 열고 닫는다. 세션 토큰·자격 증명을 발급한다.
- PEP(Policy Enforcement Point): 실제로 트래픽을 막거나 통과시키는 지점. 신원 인식 프록시, API 게이트웨이, 서비스 메시의 사이드카 등이 이 역할을 한다.
경계 모델과의 비교
| 항목 | 경계 모델 | 제로 트러스트 |
|---|---|---|
| 신뢰의 근거 | 네트워크 위치 | 신원 + 기기 상태 + 맥락 |
| 평가 시점 | 접속할 때 한 번(VPN 로그인) | 요청·세션마다 |
| 접근 범위 | 내부망 전체 | 개별 자원 |
| 내부 통신 | 평문 허용 경우 많음 | 모두 인증·암호화 |
| 침해 시 | 옆으로 이동 쉬움 | 자원 단위로 막힘 |
흔한 오해
- “제로 트러스트 제품을 사면 된다”: 제품은 PEP·PE 의 일부를 제공할 뿐이다. 자산 목록, 신원 체계, 자원별 정책이 없으면 동작하지 않는다.
- “방화벽이 필요 없다”: 네트워크 분리는 여전히 유효한 심층 방어다. 다만 유일한 근거가 되지 않을 뿐이다.
- “한 번에 전환한다”: SP 800-207 도 대부분의 조직이 경계 기반과 제로 트러스트가 섞인 상태로 오래 운영하며 점진적으로 옮겨 간다고 본다.
실무 출발점
Google 은 2014년 발표한 BeyondCorp 논문에서 사내망 특권을 없애고 기기·사용자 신원 기반으로 내부 애플리케이션에 접근하게 한 사례를 공개했다. 이를 따라 많은 조직이 다음 순서로 시작한다.
- 강한 인증(피싱 저항 MFA)과 단일 신원 공급자
- 기기 목록과 상태(관리 여부, 패치 수준) 확인
- 중요한 내부 애플리케이션 앞에 신원 인식 프록시 배치(VPN 의존 줄이기)
- 서비스 간 통신에 mTLS 와 워크로드 신원
- 모든 결정을 로그로 남기고 정책을 데이터로 다듬기
직접 해 보기
정책 엔진(PE)을 단순하게 흉내 낸다. 판단에 네트워크 위치를 쓰지 않고, 자원 민감도에 따라 기기 상태와 MFA 시점을 요구한다. 결과는 허용·거부 외에 추가 인증 요구(STEP_UP) 도 있다.
from dataclasses import dataclass
@dataclass
class Request: # PEP 가 매 요청마다 PE 에 넘기는 정보
user: str
groups: set
mfa_age_min: int # 마지막 강한 인증 후 경과 분
device_managed: bool
device_patched: bool
network: str # "office" / "home" / "unknown" — 판단에 거의 쓰지 않는다
resource: str
action: str
RESOURCES = { # 자원별 민감도와 허용 그룹
"wiki": {"level": 1, "groups": {"staff"}},
"payroll-db": {"level": 3, "groups": {"hr"}},
}
def policy_engine(r: Request):
res = RESOURCES.get(r.resource)
if res is None or not (r.groups & res["groups"]):
return "DENY", "자원 권한 없음"
if not r.device_managed:
return "DENY", "관리되지 않는 기기"
if res["level"] >= 3:
if not r.device_patched:
return "DENY", "민감 자원: 기기 패치 미흡"
if r.mfa_age_min > 15:
return "STEP_UP", "민감 자원: 최근 15분 내 MFA 재인증 필요"
return "ALLOW", f"세션 한정 허용({r.action})"
cases = [
Request("kim", {"staff"}, 300, True, True, "home", "wiki", "read"),
Request("kim", {"staff"}, 1, True, True, "office", "payroll-db", "read"), # 사무실이어도 권한 없음
Request("lee", {"staff", "hr"}, 120, True, True, "office", "payroll-db", "read"),
Request("lee", {"staff", "hr"}, 3, True, False, "home", "payroll-db", "read"),
Request("lee", {"staff", "hr"}, 3, True, True, "unknown", "payroll-db", "read"),
]
for r in cases:
d, why = policy_engine(r)
print(f"{r.user:<4} {r.network:<8} {r.resource:<11} -> {d:<8} {why}")
실행 결과(Python 3.12):
kim home wiki -> ALLOW 세션 한정 허용(read)
kim office payroll-db -> DENY 자원 권한 없음
lee office payroll-db -> STEP_UP 민감 자원: 최근 15분 내 MFA 재인증 필요
lee home payroll-db -> DENY 민감 자원: 기기 패치 미흡
lee unknown payroll-db -> ALLOW 세션 한정 허용(read)
두 번째 줄에서 kim 은 사무실에 있지만 급여 DB 권한이 없어 거부됐다. 마지막 줄에서 lee 는 알 수 없는 네트워크에 있지만 권한·기기·최근 MFA 를 모두 갖춰 허용됐다. 위치가 결과를 바꾸지 않는다. 이것이 경계 모델과의 차이다. 실제 정책 엔진은 여기에 위협 정보(유출 자격 증명 목록), 행동 이상(평소와 다른 시간·양), 데이터 분류를 더하고, 결정 하나하나를 로그로 남겨 다음 정책 개선에 쓴다.
현업에서는
- 쿠버네티스는 경계 모델이 기본이다: 별도 설정이 없으면 모든 파드가 서로 통신할 수 있다. 제로 트러스트 쪽으로 옮기려면 네임스페이스 기본 거부 NetworkPolicy(신원 대신 레이블 기반이지만 첫걸음), 서비스 메시의 mTLS 와 워크로드 신원 기반 인가, 서비스 어카운트별 최소 RBAC 를 겹친다.
- 관리 접근: 클러스터 API·SSH 를 VPN 안쪽이라고 열어 두지 않는다. 단기 인증서·OIDC 로그인·접근 기록이 남는 경로로 바꾼다. 홈랩이라도 관리 포트를 공유기 포트 포워딩으로 여는 대신 신원 기반 터널을 쓰면 노출 면이 크게 준다.
- 사용자 경험과의 균형: 모든 요청에 MFA 를 묻는 건 제로 트러스트가 아니라 피로다. 민감도에 따라 단계별 인증(step-up)을 걸고, 평소 패턴과 같은 접근은 조용히 통과시키는 것이 지속 가능한 설계다.
- 로그가 연료다: 동적 정책은 기기 상태·접근 이력·이상 징후 데이터 없이 작동하지 않는다. 앞 글의 SIEM 이 제로 트러스트의 정보 공급원 역할을 한다.
확인 문제
- 경계 기반 보안 모델의 핵심 가정과 그것이 깨지는 상황 두 가지는?
- NIST SP 800-207 의 논리 구성 요소 PE, PA, PEP 의 역할을 구분하라.
- “세션 단위 허가” 원칙이 막으려는 것은 무엇인가?
- 제로 트러스트를 도입한 조직에서도 방화벽과 네트워크 분리를 유지하는 이유는?
- 위 실습의 정책 엔진에서
network필드를 판단에 쓰지 않은 이유는?
풀이
- 가정: 내부망 안쪽은 신뢰할 수 있다. 깨지는 상황: 피싱으로 내부 단말이 장악됨, 클라우드·원격 근무로 경계가 모호해짐, 내부자 위협 중 둘.
- PE 는 접근 허가 여부를 결정하고, PA 는 그 결정에 따라 세션·경로·자격 증명을 설정하거나 해제하며, PEP 는 실제 트래픽을 막거나 통과시키는 시행 지점이다.
- 한 자원에서 얻은 신뢰가 다른 자원으로 자동 확장되어 공격자가 옆으로 이동하는 것.
- 심층 방어. 정책 엔진의 실수나 우회가 있어도 네트워크 분리가 피해 범위를 줄인다. 위치를 유일한 근거로 쓰지 않을 뿐, 통제 수단으로는 계속 쓴다.
- 네트워크 위치만으로는 신뢰를 주지 않는다는 원칙을 보이기 위해서다. 실제 정책에서는 위치를 위험 신호의 하나로 참고할 수는 있지만 허가의 근거로 삼지는 않는다.