목차
1. 왜 Zero Trust인가: 경계 보안의 종말
1.1 전통적 경계 보안 모델의 한계
전통적인 네트워크 보안은 "성과 해자(Castle and Moat)" 모델을 기반으로 했습니다. 방화벽 안쪽은 신뢰하고, 바깥쪽은 불신하는 단순한 구조였습니다.
전통적 경계 보안 모델:
[인터넷] ──── [방화벽] ──── [내부 네트워크 (신뢰 영역)]
│ │
불신 영역 모든 것이 신뢰됨
│ │
VPN으로만 자유로운 이동
접근 가능 (Lateral Movement)
하지만 이 모델은 다음과 같은 현실에서 무너졌습니다.
경계가 사라진 이유:
| 변화 요인 | 영향 |
|---|---|
| 클라우드 전환 | 데이터와 애플리케이션이 내부 네트워크 밖으로 이동 |
| 원격/하이브리드 근무 | 직원이 어디서든 접속. VPN 과부하 |
| SaaS 확산 | 비즈니스 데이터가 수십 개 SaaS에 분산 |
| BYOD | 관리되지 않는 개인 디바이스로 업무 |
| API 경제 | 서비스 간 통신이 네트워크 경계를 넘어 확장 |
| 공급망 공격 | 신뢰했던 내부 소프트웨어가 공격 벡터로 변환 |
1.2 실제 침해 사례에서 배우는 교훈
침해 패턴 (경계 보안 실패):
1. 초기 침투
피싱 이메일 → 직원 1명의 계정 탈취
2. 내부 이동 (Lateral Movement)
신뢰된 내부 네트워크에서 자유롭게 이동
→ 다른 서버, DB에 무제한 접근
3. 권한 상승
내부 네트워크이므로 추가 인증 없음
→ 관리자 권한 획득
4. 데이터 유출
내부에서 외부로의 통신은 느슨하게 관리
→ 대량 데이터 유출
SolarWinds 공급망 공격(2020), Colonial Pipeline 랜섬웨어(2021) 등은 모두 "내부는 안전하다"는 가정이 얼마나 위험한지 보여준 사례입니다.
1.3 Zero Trust의 등장
Zero Trust는 2010년 Forrester Research의 John Kindervag가 제안한 보안 모델입니다.
핵심 철학은 단순합니다: "Never Trust, Always Verify" (절대 신뢰하지 말고, 항상 검증하라)
Zero Trust 기본 원칙:
┌─────────────────────────────────────────────────┐
│ Zero Trust Architecture │
│ │
│ 1. 명시적 검증 (Verify Explicitly) │
│ → 모든 접근 요청을 인증 + 인가 │
│ → 사용자, 디바이스, 위치, 행동 패턴 검증 │
│ │
│ 2. 최소 권한 (Least Privilege Access) │
│ → 필요한 최소한의 권한만 부여 │
│ → Just-In-Time, Just-Enough-Access │
│ │
│ 3. 침해 가정 (Assume Breach) │
│ → 이미 내부가 뚫렸다고 가정 │
│ → 폭발 반경(Blast Radius) 최소화 │
│ → 마이크로세그멘테이션으로 격리 │
└─────────────────────────────────────────────────┘
2. NIST 800-207: Zero Trust 프레임워크 표준
2.1 NIST Zero Trust 아키텍처 개요
NIST SP 800-207은 Zero Trust를 구현하기 위한 표준 프레임워크입니다.
NIST 800-207 Zero Trust Architecture:
[사용자/디바이스]
│
▼
┌──────────────┐ ┌──────────────────────┐
│ PEP │────▶│ PDP (Policy Engine) │
│ Policy │◀────│ + Policy Admin │
│ Enforcement │ │ │
│ Point │ │ 결정 기준: │
└──────┬───────┘ │ - 사용자 ID │
│ │ - 디바이스 상태 │
▼ │ - 네트워크 위치 │
┌──────────────┐ │ - 요청 리소스 │
│ Enterprise │ │ - 시간/행동 패턴 │
│ Resources │ └──────────────────────┘
└──────────────┘ │
▼
┌──────────────────────┐
│ Data Sources: │
│ - CDM (자산 관리) │
│ - Threat Intel │
│ - Activity Logs │
│ - Compliance │
│ - SIEM/SOAR │
└──────────────────────┘
2.2 핵심 컴포넌트
Policy Engine (PE): 접근 허용/거부를 결정하는 두뇌입니다.
# Policy Engine 의사결정 예시
policy_evaluation:
input:
user: "engineer@company.com"
device_trust_score: 85
location: "South Korea"
resource: "production-database"
time: "2025-03-15T14:30:00Z"
mfa_verified: true
risk_score: "low"
rules:
- name: "prod-db-access"
conditions:
- user.role IN ["sre", "dba"]
- device.trust_score >= 80
- device.os_patched == true
- mfa.verified == true
- risk.score IN ["low", "medium"]
action: "allow"
session_controls:
max_duration: "4h"
require_reauthentication: true
log_all_queries: true
decision: "ALLOW with session controls"
Policy Enforcement Point (PEP): 실제로 접근을 제어하는 게이트입니다.
PEP 동작 흐름:
요청 → [PEP] → 정책 확인 요청 → [PDP]
│
허용/거부 결정
│
[PEP] ← 결정 수신 ←─────────┘
│
허용 시 → 리소스 접근 (암호화 채널)
거부 시 → 접근 차단 + 로깅
2.3 Zero Trust 성숙도 모델
CISA Zero Trust 성숙도 모델:
Level 1: Traditional (전통적)
├── 정적 보안 정책
├── 수동 프로비저닝
└── 제한적 가시성
Level 2: Advanced (고도화)
├── 일부 자동화된 정책
├── 중앙화된 ID 관리
├── 기본 분석
Level 3: Optimal (최적)
├── 완전 자동화된 정책
├── 지속적 검증
├── AI/ML 기반 분석
└── 동적 정책 적용
5개 핵심 영역:
┌────────────┬────────────┬────────────┬────────────┬────────────┐
│ Identity │ Devices │ Networks │ Apps/ │ Data │
│ │ │ │ Workloads │ │
├────────────┼────────────┼────────────┼────────────┼────────────┤
│ MFA, SSO │ MDM, EDR │ Micro- │ SDLC │ 분류, │
│ Conditional│ 디바이스 │ Segment │ DAST/SAST │ DLP, │
│ Access │ 인벤토리 │ 암호화 │ Runtime │ 암호화 │
└────────────┴────────────┴────────────┴────────────┴────────────┘
3. Google BeyondCorp: Zero Trust의 실제 구현
3.1 BeyondCorp 탄생 배경
Google은 2009년 Operation Aurora 공격 이후 내부 네트워크 보안을 근본적으로 재설계했습니다. 그 결과가 BeyondCorp입니다.
BeyondCorp 핵심 원칙:
1. 네트워크 위치로 신뢰를 결정하지 않음
→ 회사 사무실 = 카페 Wi-Fi (동일하게 취급)
2. 접근 권한은 사용자 + 디바이스에 의해 결정
→ 누구(Who) + 무엇(What device) + 어떤 상태(Health)
3. 모든 접근은 인증, 인가, 암호화
→ VPN 불필요. 인터넷을 통해 직접 접근
4. 접근 정책은 동적이고 지속적으로 평가
→ 한 번 인증으로 끝나지 않음
3.2 BeyondCorp 아키텍처
BeyondCorp Architecture:
[직원 디바이스]
│
│ (인터넷 - 어디서든)
▼
┌──────────────────┐
│ Access Proxy │ ← 모든 요청의 진입점
│ (Identity-Aware │
│ Proxy) │
└────────┬─────────┘
│
┌──────┴──────┐
▼ ▼
┌────────┐ ┌────────────┐
│ Access │ │ Device │
│ Control│ │ Inventory │
│ Engine │ │ Service │
└───┬────┘ └─────┬──────┘
│ │
▼ ▼
┌────────────────────────┐
│ Trust Evaluation │
│ │
│ User Identity ────────┤
│ Device State ─────────┤
│ Access Policy ────────┤
│ Context (time, loc) ──┤
│ │
│ → Trust Score 계산 │
│ → 접근 허용/거부 결정 │
└────────────────────────┘
3.3 Identity-Aware Proxy (IAP) 구현
Google Cloud IAP를 사용한 구현 예시입니다.
# GCP IAP 설정 예시
# iap-config.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: iap-backend-config
spec:
iap:
enabled: true
oauthclientCredentials:
secretName: iap-oauth-secret
securityPolicy:
name: "rate-limit-policy"
healthCheck:
requestPath: /healthz
port: 8080
# IAP를 통한 접근 검증 (서버 사이드)
from google.auth.transport import requests
from google.oauth2 import id_token
def verify_iap_jwt(iap_jwt, expected_audience):
"""IAP JWT 토큰을 검증하여 사용자 ID를 반환"""
try:
decoded_jwt = id_token.verify_token(
iap_jwt,
requests.Request(),
audience=expected_audience,
certs_url="https://www.gstatic.com/iap/verify/public_key"
)
return {
"email": decoded_jwt["email"],
"sub": decoded_jwt["sub"],
"access_levels": decoded_jwt.get("google", {}).get(
"access_levels", []
)
}
except Exception as e:
print(f"JWT verification failed: {e}")
return None
# 접근 레벨 기반 정책 적용
def check_access_policy(user_info, resource):
"""사용자의 접근 레벨과 리소스 정책을 비교"""
required_levels = get_resource_policy(resource)
user_levels = set(user_info.get("access_levels", []))
if required_levels.issubset(user_levels):
return True
return False
3.4 BeyondCorp 마이그레이션 단계
Google의 BeyondCorp 전환 과정 (약 8년):
Phase 1: 가시성 확보 (Visibility)
├── 모든 디바이스 인벤토리 구축
├── 모든 사용자 접근 패턴 분석
└── 기존 VPN 트래픽 모니터링
Phase 2: 접근 프록시 구축
├── Identity-Aware Proxy 배포
├── 내부 애플리케이션을 프록시 뒤로 이동
└── 인증서 기반 디바이스 인증
Phase 3: 정책 엔진 구축
├── 동적 접근 정책 정의
├── 디바이스 신뢰도 점수 시스템
└── 컨텍스트 기반 접근 제어
Phase 4: VPN 제거
├── 점진적 VPN 트래픽 감소
├── 모든 앱을 프록시 기반으로 전환
└── VPN 완전 폐기
Phase 5: 지속적 개선
├── ML 기반 이상 탐지
├── 실시간 리스크 평가
└── 자동 대응 (SOAR 통합)
4. Identity 중심 보안
4.1 IAM (Identity and Access Management) 아키텍처
현대적 IAM 아키텍처:
┌─────────────────────────────────────────┐
│ Identity Provider (IdP) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────┐│
│ │ User │ │ Directory│ │ MFA ││
│ │ Store │ │ Service │ │ Engine ││
│ │ (DB) │ │ (LDAP/ │ │ ││
│ │ │ │ SCIM) │ │ ││
│ └──────────┘ └──────────┘ └────────┘│
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────┐│
│ │ SSO │ │ OAuth2/ │ │ Risk ││
│ │ Engine │ │ OIDC │ │ Engine ││
│ │ (SAML) │ │ Server │ │ ││
│ └──────────┘ └──────────┘ └────────┘│
└─────────────────────────────────────────┘
│ │
┌────┴────┐ ┌───┴────┐
▼ ▼ ▼ ▼
[SaaS] [Internal] [Cloud] [API]
Apps Apps Infra Services
4.2 Conditional Access Policy
# Conditional Access 정책 엔진 구현 예시
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional
class RiskLevel(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class AccessContext:
user_id: str
user_role: str
device_compliant: bool
device_managed: bool
mfa_completed: bool
mfa_method: str # "phishing_resistant", "push", "sms"
location: str # "corporate", "home", "unknown"
ip_reputation: str # "trusted", "suspicious", "malicious"
risk_score: float # 0.0 - 1.0
resource_sensitivity: str # "public", "internal", "confidential", "restricted"
class ConditionalAccessEngine:
def evaluate(self, ctx: AccessContext) -> dict:
"""접근 요청을 평가하여 결정을 반환"""
# Rule 1: 악성 IP는 무조건 차단
if ctx.ip_reputation == "malicious":
return self._deny("Malicious IP detected")
# Rule 2: 고위험 리소스 접근
if ctx.resource_sensitivity == "restricted":
if not ctx.mfa_completed:
return self._step_up("Require MFA for restricted resource")
if ctx.mfa_method != "phishing_resistant":
return self._step_up("Require phishing-resistant MFA (FIDO2)")
if not ctx.device_managed:
return self._deny("Managed device required for restricted access")
# Rule 3: 위험 점수 기반 동적 정책
if ctx.risk_score > 0.8:
return self._deny("Risk score too high")
elif ctx.risk_score > 0.5:
if not ctx.mfa_completed:
return self._step_up("Elevated risk - MFA required")
return self._allow_limited(session_duration="1h")
# Rule 4: 비관리 디바이스
if not ctx.device_managed:
if ctx.resource_sensitivity in ["confidential", "restricted"]:
return self._deny("Managed device required")
return self._allow_limited(
session_duration="4h",
block_download=True
)
return self._allow()
def _allow(self):
return {"decision": "allow", "session_duration": "8h"}
def _allow_limited(self, **kwargs):
return {"decision": "allow_limited", **kwargs}
def _deny(self, reason: str):
return {"decision": "deny", "reason": reason}
def _step_up(self, reason: str):
return {"decision": "step_up_auth", "reason": reason}
4.3 Multi-Factor Authentication (MFA) 전략
MFA 강도 피라미드:
가장 강력 ▲
│ ┌─────────────────────────┐
│ │ FIDO2/WebAuthn │ ← 하드웨어 키 (YubiKey)
│ │ (피싱 방지) │ 패스키 (Passkey)
│ └─────────────────────────┘
│ ┌─────────────────────────┐
│ │ 인증서 기반 │ ← 디바이스 인증서
│ │ (Certificate-based) │ 스마트카드
│ └─────────────────────────┘
│ ┌─────────────────────────┐
│ │ 앱 기반 Push/TOTP │ ← Authenticator 앱
│ │ │ 시간 기반 OTP
│ └─────────────────────────┘
│ ┌─────────────────────────┐
│ │ SMS/Email OTP │ ← SIM 스와핑 취약
가장 약함 │ │ (피싱 가능) │ 이메일 탈취 시 무력화
▼ └─────────────────────────┘
# Okta Conditional MFA 설정 예시
authentication_policies:
- name: "High Security Resources"
conditions:
applications:
- "production-admin"
- "financial-systems"
- "customer-data-platform"
actions:
require_mfa: true
allowed_factors:
- "fido2_webauthn"
- "okta_verify_push"
factor_lifetime: "1h"
re_authentication_frequency: "every_request"
- name: "Standard Resources"
conditions:
applications:
- "email"
- "chat"
- "wiki"
actions:
require_mfa: true
allowed_factors:
- "fido2_webauthn"
- "okta_verify_push"
- "okta_verify_totp"
factor_lifetime: "12h"
re_authentication_frequency: "every_sign_on"
- name: "Unknown Location Policy"
conditions:
network_zones:
exclude:
- "corporate_network"
- "known_vpn_endpoints"
actions:
require_mfa: true
allowed_factors:
- "fido2_webauthn"
session_lifetime: "4h"
5. Device Trust: 디바이스 신뢰도 평가
5.1 디바이스 포스처 평가 아키텍처
Device Trust 평가 흐름:
[디바이스] → 에이전트가 상태 수집
│
▼
┌──────────────────────────────────┐
│ Device Trust Signal │
│ │
│ OS 버전/패치 상태 ─────── 20% │
│ 디스크 암호화 ────────── 15% │
│ 방화벽 활성화 ────────── 10% │
│ EDR 설치/실행 ────────── 20% │
│ MDM 관리 상태 ────────── 15% │
│ 인증서 유효성 ────────── 10% │
│ 최근 보안 스캔 ───────── 10% │
│ │
│ → Trust Score: 0-100 │
└──────────────────────────────────┘
│
▼
접근 정책에 Trust Score 반영
Score >= 80 → Full Access
Score >= 60 → Limited Access
Score < 60 → Block + 안내
5.2 디바이스 인증서 기반 인증
# 디바이스 인증서 검증 로직
import ssl
from cryptography import x509
from cryptography.x509.oid import NameOID
class DeviceCertificateValidator:
def __init__(self, ca_cert_path: str, crl_url: str):
self.ca_cert = self._load_cert(ca_cert_path)
self.crl_url = crl_url
def validate_device(self, client_cert_pem: bytes) -> dict:
"""디바이스 인증서를 검증하고 디바이스 정보를 반환"""
try:
cert = x509.load_pem_x509_certificate(client_cert_pem)
# 1. 유효기간 확인
self._check_validity(cert)
# 2. CA 서명 확인
self._verify_signature(cert)
# 3. CRL (인증서 폐기 목록) 확인
self._check_revocation(cert)
# 4. 디바이스 정보 추출
device_info = {
"device_id": cert.subject.get_attributes_for_oid(
NameOID.COMMON_NAME
)[0].value,
"org": cert.subject.get_attributes_for_oid(
NameOID.ORGANIZATION_NAME
)[0].value,
"serial": str(cert.serial_number),
"not_after": cert.not_valid_after_utc.isoformat(),
"verified": True
}
return device_info
except Exception as e:
return {"verified": False, "error": str(e)}
5.3 EDR/MDM 통합
# Microsoft Intune 컴플라이언스 정책 예시
compliance_policy:
name: "Zero Trust Device Compliance"
platforms:
- windows
- macos
- ios
- android
windows_rules:
os_minimum_version: "10.0.19045" # Windows 10 22H2+
bitlocker_required: true
secure_boot_required: true
tpm_required: true
firewall_required: true
antivirus_required: true
antivirus_signatures_up_to_date: true
defender_for_endpoint_risk_level: "medium_or_below"
macos_rules:
os_minimum_version: "14.0" # Sonoma+
filevault_required: true
firewall_required: true
gatekeeper_required: true
system_integrity_protection: true
non_compliance_actions:
- action: "notify_user"
grace_period_hours: 0
message: "디바이스가 보안 정책을 충족하지 않습니다"
- action: "mark_non_compliant"
grace_period_hours: 24
- action: "block_access"
grace_period_hours: 72
- action: "retire_device"
grace_period_hours: 720 # 30일
6. 마이크로세그멘테이션
6.1 네트워크 세그멘테이션 진화
세그멘테이션 진화:
1. 전통적: VLAN 기반
┌──────────┐ ┌──────────┐ ┌──────────┐
│ VLAN 10 │ │ VLAN 20 │ │ VLAN 30 │
│ (개발) │ │ (운영) │ │ (DB) │
└──────────┘ └──────────┘ └──────────┘
→ 같은 VLAN 내 자유 통신 (문제!)
2. 방화벽 기반: Zone 세그멘테이션
┌──────────┐ ┌──────────┐
│ Trust │─FW─▶│ DMZ │─FW─▶ Internet
│ Zone │ │ Zone │
└──────────┘ └──────────┘
→ Zone 간 제어, Zone 내 자유 (부족)
3. 마이크로세그멘테이션: 워크로드 수준
┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
│A │─│B │ │C │─│D │ │E │
└──┘ └──┘ └──┘ └──┘ └──┘
│ │
└────X────┘ ← A와 C 간 통신 차단
→ 워크로드 간 개별 정책 (이상적)
6.2 Kubernetes NetworkPolicy
# 1. 기본 정책: 모든 트래픽 차단 (Default Deny)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 2. 프론트엔드 → 백엔드 API만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: backend-api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# 3. 백엔드 API → DB만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend-api
ports:
- protocol: TCP
port: 5432
---
# 4. DNS 접근 허용 (모든 Pod)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
6.3 Service Mesh mTLS (Istio)
# Istio PeerAuthentication: 전체 메시에 mTLS 강제
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT # mTLS 필수. 평문 트래픽 거부
---
# AuthorizationPolicy: 서비스 간 접근 제어
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: payment-service-policy
namespace: production
spec:
selector:
matchLabels:
app: payment-service
rules:
# Rule 1: order-service만 결제 API 호출 허용
- from:
- source:
principals:
- "cluster.local/ns/production/sa/order-service"
to:
- operation:
methods: ["POST"]
paths: ["/api/v1/payments", "/api/v1/payments/*"]
# Rule 2: 모니터링 서비스는 health check만 허용
- from:
- source:
principals:
- "cluster.local/ns/monitoring/sa/prometheus"
to:
- operation:
methods: ["GET"]
paths: ["/health", "/metrics"]
# 나머지 모든 접근은 암묵적으로 거부됨
7. ZTNA vs VPN 비교
7.1 근본적 차이점
VPN (전통적):
[사용자] ──VPN 터널──▶ [회사 네트워크 전체에 접근]
│
모든 내부 리소스 노출
(불필요한 서버도 보임)
ZTNA (Zero Trust):
[사용자] ──암호화 채널──▶ [허가된 앱 A만 접근]
│
나머지 네트워크는 보이지 않음
(Dark Cloud 원칙)
7.2 상세 비교표
| 항목 | VPN | ZTNA |
|---|---|---|
| 접근 범위 | 네트워크 전체 (과도한 접근) | 특정 애플리케이션만 (최소 권한) |
| 인증 | 초기 1회 인증 | 지속적 인증/검증 |
| 디바이스 검사 | 제한적 또는 없음 | 디바이스 포스처 실시간 평가 |
| 사용자 경험 | 느림, VPN 클라이언트 필요 | 빠름, 투명한 접근 |
| 확장성 | VPN 서버 병목 | 클라우드 기반 무제한 확장 |
| 네트워크 가시성 | 내부 네트워크 노출 | 앱 수준만 노출 (Dark Cloud) |
| Lateral Movement | 가능 (네트워크 접근) | 불가능 (앱 격리) |
| 성능 | 모든 트래픽이 VPN 경유 | 직접 접근 (Split Tunnel) |
| 관리 복잡도 | 높음 (HW/SW 관리) | 낮음 (SaaS 기반) |
| 비용 | HW 어플라이언스 + 라이선스 | 사용자 기반 구독 |
7.3 ZTNA 구현 예시 (Cloudflare Access)
# Cloudflare Access 정책 예시
application:
name: "Internal Dashboard"
domain: "dashboard.company.com"
type: "self_hosted"
identity_providers:
- name: "Okta"
type: "saml"
- name: "GitHub"
type: "oauth"
policies:
- name: "Allow Engineering"
decision: "allow"
include:
- group: "engineering@company.com"
require:
- mfa: true
- device_posture:
- serial_number_check: true
- disk_encryption: true
- os_version:
operator: ">="
version: "14.0"
- name: "Block Countries"
decision: "block"
include:
- country:
- "KP"
- "IR"
- "SY"
session_duration: "12h"
cors_headers:
allowed_origins: ["https://dashboard.company.com"]
allowed_methods: ["GET", "POST"]
8. SASE (Secure Access Service Edge) 아키텍처
8.1 SASE 개요
SASE = 네트워크(SD-WAN) + 보안(SSE)을 클라우드에서 통합
┌─────────────────────────────────────────────────────┐
│ SASE Platform │
│ │
│ ┌─────────────────┐ ┌──────────────────────────┐ │
│ │ SD-WAN │ │ SSE (Security) │ │
│ │ │ │ │ │
│ │ - WAN 최적화 │ │ - ZTNA │ │
│ │ - 트래픽 제어 │ │ - CASB (Cloud Access │ │
│ │ - QoS │ │ Security Broker) │ │
│ │ - 멀티링크 │ │ - SWG (Secure Web GW) │ │
│ │ │ │ - FWaaS (FW as Service) │ │
│ │ │ │ - DLP (Data Loss Prev.) │ │
│ └─────────────────┘ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 공통 기능: 통합 정책, 통합 콘솔, API 통합 │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ 본사 │ │ 지사 │ │ 원격 │
│ (HQ) │ │(Branch) │ │ (Remote)│
└─────────┘ └─────────┘ └─────────┘
8.2 SASE 구성 요소 상세
ZTNA (Zero Trust Network Access):
├── 사용자/디바이스 인증
├── 앱 수준 접근 제어
├── 컨텍스트 기반 정책
└── VPN 대체
CASB (Cloud Access Security Broker):
├── Shadow IT 발견
├── SaaS 데이터 보호 (DLP)
├── 이상 행동 탐지 (UEBA)
└── 컴플라이언스 모니터링
SWG (Secure Web Gateway):
├── URL 필터링
├── 멀웨어 차단
├── SSL/TLS 검사
└── 콘텐츠 필터링
FWaaS (Firewall as a Service):
├── L3-L7 방화벽
├── IPS/IDS
├── DNS 보안
└── 클라우드 기반 확장
8.3 SASE 벤더 비교
| 벤더 | 강점 | ZTNA | CASB | SWG | SD-WAN |
|---|---|---|---|---|---|
| Zscaler | 보안 전문, 글로벌 엣지 | O | O | O | 파트너 |
| Palo Alto (Prisma) | 통합 보안 플랫폼 | O | O | O | O |
| Cloudflare One | 개발자 친화적, 글로벌 네트워크 | O | O | O | O |
| Netskope | CASB/DLP 최강 | O | O | O | 파트너 |
| Cisco (Umbrella + Viptela) | 엔터프라이즈 네트워크 강점 | O | O | O | O |
9. Zero Trust for Kubernetes
9.1 K8s Zero Trust 아키텍처
Kubernetes Zero Trust 계층:
Layer 1: Cluster Access
├── RBAC (Role-Based Access Control)
├── OIDC 인증 (kubectl + IdP)
├── Admission Control (OPA/Kyverno)
└── API Server Audit Logging
Layer 2: Pod-to-Pod Communication
├── NetworkPolicy (기본 L3/L4)
├── Service Mesh mTLS (L7)
├── DNS Policy
└── Egress Control
Layer 3: Workload Identity
├── ServiceAccount Token (Projected)
├── SPIFFE/SPIRE
├── Workload Identity Federation
└── Secret Management (Vault)
Layer 4: Data Protection
├── Encryption at Rest (etcd)
├── Encryption in Transit (TLS)
├── Secret Encryption (KMS)
└── PodSecurity Standards
9.2 OPA/Gatekeeper 정책
# OPA Gatekeeper: Pod Security 강제
# ConstraintTemplate 정의
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredsecuritycontext
spec:
crd:
spec:
names:
kind: K8sRequiredSecurityContext
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredsecuritycontext
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf(
"Container '%v' must set runAsNonRoot to true",
[container.name]
)
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.readOnlyRootFilesystem
msg := sprintf(
"Container '%v' must set readOnlyRootFilesystem to true",
[container.name]
)
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.privileged
msg := sprintf(
"Container '%v' must not be privileged",
[container.name]
)
}
---
# Constraint 적용
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredSecurityContext
metadata:
name: must-have-security-context
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
- "staging"
enforcementAction: deny
9.3 Kyverno 정책
# Kyverno: 이미지 서명 검증 + 레지스트리 제한
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signatures
spec:
validationFailureAction: Enforce
background: false
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.company.com/*"
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----
- name: restrict-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Only approved registries are allowed"
pattern:
spec:
containers:
- image: "registry.company.com/* | gcr.io/company-project/*"
9.4 SPIFFE/SPIRE Workload Identity
SPIFFE/SPIRE 아키텍처:
┌──────────────────────────────┐
│ SPIRE Server │
│ │
│ - CA (인증서 발급) │
│ - Registration API │
│ - Node/Workload Attestation │
└──────────┬───────────────────┘
│
┌────────┴────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ SPIRE │ │ SPIRE │
│ Agent │ │ Agent │
│ (Node 1) │ │ (Node 2) │
└────┬─────┘ └────┬─────┘
│ │
┌──┴──┐ ┌──┴──┐
│Pod A│ │Pod C│
│Pod B│ │Pod D│
└─────┘ └─────┘
각 Pod는 SVID (SPIFFE Verifiable Identity Document)를 받음:
spiffe://company.com/ns/production/sa/payment-service
# SPIRE Registration 예시
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
name: payment-service-id
spec:
spiffeIDTemplate: >-
spiffe://company.com/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}
podSelector:
matchLabels:
app: payment-service
namespaceSelector:
matchLabels:
environment: production
dnsNameTemplates:
- "{{ .PodSpec.ServiceAccountName }}.{{ .PodMeta.Namespace }}.svc.cluster.local"
ttl: "1h"
jwtTTL: "5m"
10. Zero Trust 구현 로드맵 (5단계)
10.1 전체 로드맵
Phase 1: 가시성 확보 (1-3개월)
├── 자산 인벤토리 (사용자, 디바이스, 앱, 데이터)
├── 네트워크 흐름 매핑
├── 접근 패턴 분석
├── 현재 보안 갭 평가
└── 성공 지표(KPI) 정의
Phase 2: Identity Foundation (3-6개월)
├── 중앙화된 IdP 구축/통합
├── SSO 구현 (SAML/OIDC)
├── MFA 전체 적용
├── Conditional Access 정책
└── 디바이스 등록 및 관리
Phase 3: 네트워크 세그멘테이션 (6-12개월)
├── 마이크로세그멘테이션 설계
├── East-West 트래픽 제어
├── DNS 보안
├── 암호화 통신 (mTLS)
└── ZTNA 파일럿 (VPN 대체 시작)
Phase 4: 워크로드 보안 (12-18개월)
├── 애플리케이션 수준 접근 제어
├── API 보안 (인증, 레이트 리밋)
├── 데이터 분류 및 DLP
├── CI/CD 파이프라인 보안
└── 런타임 보안 (CWPP)
Phase 5: 자동화 및 최적화 (18-24개월)
├── SOAR 통합 (자동 대응)
├── ML 기반 이상 탐지
├── 지속적 컴플라이언스 모니터링
├── 자동 정책 최적화
└── VPN 완전 폐기
10.2 각 단계별 핵심 활동
# Phase 1 상세 체크리스트
phase_1_visibility:
asset_inventory:
- action: "모든 사용자 계정 식별"
tools: ["IdP export", "AD/LDAP query"]
kpi: "식별률 >= 99%"
- action: "모든 디바이스 식별"
tools: ["MDM", "NAC", "네트워크 스캔"]
kpi: "관리 디바이스 비율 >= 90%"
- action: "모든 애플리케이션 매핑"
tools: ["CASB discovery", "네트워크 분석"]
kpi: "Shadow IT 발견율"
- action: "데이터 흐름 매핑"
tools: ["DLP 스캔", "네트워크 탭"]
kpi: "민감 데이터 위치 파악률"
network_mapping:
- action: "East-West 트래픽 분석"
tools: ["NetFlow", "Service Mesh 텔레메트리"]
- action: "외부 통신 패턴 분석"
tools: ["방화벽 로그", "프록시 로그"]
- action: "의존성 그래프 생성"
tools: ["서비스 디스커버리", "APM"]
gap_assessment:
- "현재 인증 방식 감사"
- "네트워크 세그멘테이션 수준 평가"
- "암호화 적용 범위 확인"
- "로깅/모니터링 커버리지 평가"
11. 도구 비교: Zscaler vs Cloudflare vs Tailscale
11.1 상세 비교
| 항목 | Zscaler | Cloudflare Zero Trust | Tailscale |
|---|---|---|---|
| 유형 | Enterprise SASE | Developer-friendly SASE | WireGuard mesh VPN |
| ZTNA | Zscaler Private Access | Cloudflare Access | Tailscale SSH/ACL |
| SWG | Zscaler Internet Access | Cloudflare Gateway | N/A |
| CASB | O (인라인 + API) | O (기본) | N/A |
| 글로벌 엣지 | 150+ 데이터센터 | 310+ 도시 | P2P (DERP relay) |
| 에이전트 | Zscaler Client Connector | WARP Client | Tailscale Client |
| 가격 | 엔터프라이즈 (높음) | 무료 50명, 이후 사용자당 | 무료 3명, 이후 사용자당 |
| 설정 복잡도 | 높음 | 중간 | 낮음 |
| K8s 통합 | O | O (Tunnel) | O (Operator) |
| 적합 대상 | 대기업 | 중소기업-대기업 | 스타트업-중소기업 |
11.2 Tailscale ACL 정책
{
"acls": [
{
"action": "accept",
"src": ["group:engineering"],
"dst": [
"tag:dev-server:22",
"tag:staging-server:*",
"tag:monitoring:3000,9090"
]
},
{
"action": "accept",
"src": ["group:sre"],
"dst": [
"tag:production-server:*",
"tag:database:5432",
"tag:monitoring:*"
]
},
{
"action": "accept",
"src": ["group:data-team"],
"dst": [
"tag:data-warehouse:5439",
"tag:jupyter:8888"
]
}
],
"groups": {
"group:engineering": ["user1@company.com", "user2@company.com"],
"group:sre": ["sre1@company.com", "sre2@company.com"],
"group:data-team": ["analyst@company.com"]
},
"tagOwners": {
"tag:production-server": ["group:sre"],
"tag:dev-server": ["group:engineering"],
"tag:staging-server": ["group:engineering"],
"tag:database": ["group:sre"],
"tag:monitoring": ["group:sre"],
"tag:data-warehouse": ["group:data-team"],
"tag:jupyter": ["group:data-team"]
},
"ssh": [
{
"action": "accept",
"src": ["group:sre"],
"dst": ["tag:production-server"],
"users": ["root", "ubuntu"]
},
{
"action": "accept",
"src": ["group:engineering"],
"dst": ["tag:dev-server"],
"users": ["autogroup:nonroot"]
}
]
}
11.3 Twingate 설정 예시
# Twingate Terraform 설정
resource "twingate_remote_network" "production" {
name = "Production Network"
}
resource "twingate_connector" "prod_connector" {
remote_network_id = twingate_remote_network.production.id
name = "prod-connector-1"
}
resource "twingate_resource" "prod_api" {
name = "Production API"
address = "api.internal.company.com"
remote_network_id = twingate_remote_network.production.id
protocols {
allow_icmp = false
tcp {
policy = "RESTRICTED"
ports = ["443", "8443"]
}
udp {
policy = "DENY_ALL"
}
}
access {
group_ids = [twingate_group.engineering.id]
}
}
resource "twingate_group" "engineering" {
name = "Engineering Team"
}
12. 도전 과제와 함정
12.1 일반적인 실수
Zero Trust 구현 시 흔한 실수:
1. "VPN을 ZTNA로 교체하면 끝" 사고
→ Zero Trust는 제품이 아니라 전략
→ 네트워크, ID, 디바이스, 앱, 데이터 모든 계층 필요
2. 한 번에 모든 것을 바꾸려는 시도
→ 점진적 전환이 필수
→ 가장 높은 위험부터 우선 적용
3. 사용자 경험 무시
→ 보안이 너무 불편하면 우회 시도 발생
→ SSO + 패스키로 보안과 편의성 양립
4. "내부 = 신뢰" 가정이 코드에 박혀 있음
→ IP 기반 접근 제어를 ID 기반으로 전환 필요
→ 레거시 앱 마이그레이션 계획 수립
5. 가시성 없이 정책 적용
→ 먼저 모니터링 모드로 트래픽 파악
→ 이후 점진적으로 차단 정책 적용
6. DevOps/CI/CD 파이프라인 간과
→ 서비스 계정, API 키도 Zero Trust 대상
→ Workload Identity 도입
12.2 성공 지표 (KPI)
zero_trust_kpis:
identity:
- metric: "MFA 적용률"
target: "100%"
current_industry_avg: "64%"
- metric: "피싱 방지 MFA (FIDO2) 비율"
target: ">= 80%"
- metric: "SSO 적용 앱 비율"
target: ">= 95%"
- metric: "고아 계정 수"
target: "0"
device:
- metric: "관리 디바이스 비율"
target: ">= 95%"
- metric: "패치 적용 SLA 준수율"
target: ">= 90%"
- metric: "디바이스 컴플라이언스 비율"
target: ">= 90%"
network:
- metric: "마이크로세그멘테이션 적용률"
target: ">= 80%"
- metric: "mTLS 적용 서비스 비율"
target: ">= 95%"
- metric: "VPN 사용자 수"
target: "0 (ZTNA로 완전 전환)"
incident:
- metric: "Lateral Movement 탐지 시간"
target: "< 1시간"
- metric: "침해 시 영향 범위"
target: "단일 마이크로세그먼트 이하"
- metric: "MTTD (Mean Time To Detect)"
target: "< 24시간"
13. 퀴즈
Q1. Zero Trust의 3가지 핵심 원칙은 무엇인가요?
답: Zero Trust의 3가지 핵심 원칙은 다음과 같습니다:
-
명시적 검증 (Verify Explicitly): 모든 접근 요청에 대해 사용자, 디바이스, 위치, 행동 패턴 등을 항상 인증하고 인가합니다.
-
최소 권한 (Least Privilege Access): 필요한 최소한의 권한만 부여합니다. Just-In-Time(JIT)과 Just-Enough-Access(JEA)를 적용합니다.
-
침해 가정 (Assume Breach): 이미 내부가 침해되었다고 가정하고, 폭발 반경(Blast Radius)을 최소화하기 위해 마이크로세그멘테이션을 적용합니다.
Q2. ZTNA와 VPN의 핵심 차이점은 무엇인가요?
답: 핵심 차이점은 접근 범위와 인증 방식입니다.
-
VPN: 인증 후 네트워크 전체에 접근을 제공합니다. 한 번 연결되면 내부 리소스에 자유롭게 이동할 수 있어 Lateral Movement 위험이 있습니다.
-
ZTNA: 개별 애플리케이션 수준에서만 접근을 허용합니다(Dark Cloud 원칙). 지속적으로 사용자와 디바이스를 검증하며, 나머지 네트워크는 보이지 않습니다.
ZTNA는 성능(직접 접근), 보안(앱 격리), 확장성(클라우드 기반) 면에서 우수합니다.
Q3. Google BeyondCorp의 핵심 아이디어와 기존 보안과의 차이점은?
답: BeyondCorp의 핵심 아이디어는 "네트워크 위치가 신뢰를 결정하지 않는다"는 것입니다.
기존 모델에서는 사무실 네트워크에 연결되면 내부 리소스에 접근할 수 있었지만, BeyondCorp에서는 사무실이든 카페든 동일한 검증을 거칩니다.
핵심 구성 요소:
- Identity-Aware Proxy: 모든 요청의 진입점으로 신원 확인
- Device Inventory Service: 디바이스 상태를 실시간으로 관리
- Access Control Engine: 사용자 + 디바이스 + 컨텍스트로 접근 결정
- Trust Evaluation: 동적 Trust Score 기반 의사 결정
Google은 약 8년에 걸쳐 VPN을 완전히 제거하고 BeyondCorp로 전환했습니다.
Q4. 마이크로세그멘테이션이란 무엇이며, Kubernetes에서 어떻게 구현하나요?
답: 마이크로세그멘테이션은 네트워크를 워크로드 수준의 세밀한 단위로 분리하여, 각 워크로드 간 최소 필요 통신만 허용하는 기술입니다.
Kubernetes에서의 구현 방법:
- NetworkPolicy: 기본 L3/L4 수준의 Pod 간 트래픽 제어. Default Deny 정책을 먼저 적용하고, 필요한 통신만 명시적으로 허용합니다.
- Service Mesh (Istio): L7 수준의 제어. PeerAuthentication으로 mTLS를 강제하고, AuthorizationPolicy로 서비스 간 접근을 세밀하게 제어합니다.
- OPA/Gatekeeper 또는 Kyverno: 정책을 코드로 관리하여 보안 표준을 강제합니다.
Q5. SASE의 핵심 구성 요소와 각각의 역할은?
답: SASE(Secure Access Service Edge)는 네트워크와 보안을 클라우드에서 통합합니다.
핵심 구성 요소:
- SD-WAN: WAN 최적화, 트래픽 제어, QoS 관리. 여러 링크를 지능적으로 활용합니다.
- ZTNA: 사용자/디바이스 인증 후 앱 수준 접근 제어. VPN 대체합니다.
- CASB: Shadow IT 발견, SaaS 데이터 보호, 이상 행동 탐지, 컴플라이언스 모니터링을 수행합니다.
- SWG: URL 필터링, 멀웨어 차단, SSL/TLS 검사, 콘텐츠 필터링을 수행합니다.
- FWaaS: L3-L7 방화벽, IPS/IDS, DNS 보안을 클라우드에서 제공합니다.
- DLP: 민감 데이터 유출 방지를 수행합니다.
이 모든 구성 요소가 통합 정책과 콘솔로 관리됩니다.
14. 참고 자료
- NIST SP 800-207: Zero Trust Architecture
- Google BeyondCorp Papers
- CISA Zero Trust Maturity Model
- Forrester Zero Trust eXtended Framework
- Cloudflare Zero Trust Documentation
- Zscaler Zero Trust Exchange
- Tailscale Documentation
- Istio Security Documentation
- SPIFFE/SPIRE Documentation
- Kubernetes Network Policies
- OPA Gatekeeper
- Kyverno Documentation
- Microsoft Zero Trust Deployment Guide
- Gartner SASE Framework
현재 단락 (1/1094)
전통적인 네트워크 보안은 "성과 해자(Castle and Moat)" 모델을 기반으로 했습니다. 방화벽 안쪽은 신뢰하고, 바깥쪽은 불신하는 단순한 구조였습니다.