NSG vs Azure Firewall vs WAF: 트래픽 경로에 배치해보면 선택이 아니라 조합이다

Azure 네트워크 보안 비교 - NSG, Azure Firewall, WAF

NSG, Azure Firewall, WAF는 셋 다 “트래픽을 막는” 것처럼 보여서 어느 하나를 고르는 문제로 오해하기 쉽습니다. 실제로는 서로 다른 위치에서 서로 다른 것을 보는 도구들이고, 대체 관계가 아니라 보완 관계입니다.

이 글은 셋을 트래픽이 지나가는 경로 위에 배치해서 각각 어디서 무엇을 거르는지 정리합니다. 그리고 소규모에서 무엇부터 도입할지, 비용 대비 우선순위도 함께 봅니다.

트래픽 경로 위에 놓고 보기

외부 사용자가 웹 애플리케이션에 접속할 때 트래픽이 지나가는 순서입니다.

[ 인터넷 ]
     │
     ▼
[ WAF (App Gateway / Front Door) ]  ← L7: HTTP 내용을 검사
     │                                  SQL 인젝션, XSS, 봇
     ▼
[ NSG (서브넷/NIC) ]                ← L3-L4: IP·포트만 검사
     │                                  "누가 어디로" 만 판단
     ▼
[ 애플리케이션 VM / 파드 ]
     │
     ▼ (아웃바운드)
[ Azure Firewall ]                  ← L3-L7: 나가는 트래픽 통제
     │                                  FQDN 필터링, 위협 인텔리전스
     ▼
[ 인터넷 / 온프레미스 ]

이 그림에서 핵심은 WAF는 들어오는 것, Firewall은 나가는 것에 주로 쓰인다는 점입니다. 이걸 알면 “둘 다 방화벽인데 왜 두 개나 필요한가”라는 의문이 풀립니다.

NSGAzure FirewallWAF
계층L3-L4L3-L7L7 (HTTP/S)
판단 근거IP, 포트, 프로토콜IP, 포트, FQDN요청 본문·헤더
주 방향양방향아웃바운드인바운드
막는 것허용 안 된 포트 접근악성 도메인 통신, 데이터 유출SQL 인젝션, XSS, 봇
비용무료시간당 고정 + 데이터App GW/Front Door 요금
상태 저장

비용 행이 실무 판단에서 결정적입니다. NSG만 무료이고 나머지 둘은 배포만 해도 시간당 요금이 나갑니다. 그래서 도입 순서가 정해집니다.

NSG — 여기서부터 시작한다

무료이고, 대부분의 기본적인 노출을 막습니다. NSG를 제대로 쓰지 않으면서 Firewall을 도입하는 건 순서가 틀렸습니다.

NSG에서 실무적으로 중요한 건 서비스 태그입니다. IP 주소 대신 Storage, Sql, AzureMonitor 같은 이름을 쓸 수 있고, Azure가 IP 목록을 알아서 관리합니다.

# 애플리케이션 서브넷: Storage로 나가는 것만 허용
az network nsg rule create \
  --nsg-name nsg-app-prod -g rg-prod-network \
  --name allow-storage-out \
  --priority 100 --direction Outbound --access Allow \
  --protocol Tcp \
  --source-address-prefixes VirtualNetwork \
  --destination-address-prefixes Storage.koreacentral \
  --destination-port-ranges 443

# 나머지 인터넷 아웃바운드는 차단
az network nsg rule create \
  --nsg-name nsg-app-prod -g rg-prod-network \
  --name deny-internet-out \
  --priority 4000 --direction Outbound --access Deny \
  --protocol '*' \
  --source-address-prefixes VirtualNetwork \
  --destination-address-prefixes Internet \
  --destination-port-ranges '*'

이 두 규칙만으로 “스토리지 말고는 인터넷으로 못 나감”이 구현됩니다. Azure Firewall 없이도 아웃바운드 통제의 상당 부분이 됩니다.

NSG의 한계도 여기서 드러납니다. 서비스 태그는 Azure 서비스에만 있습니다. “github.com으로만 나가게 하고 싶다” 같은 요구는 NSG로 안 됩니다. IP가 계속 바뀌기 때문입니다. 그때 Azure Firewall이 필요해집니다.

Azure Firewall — FQDN이 필요할 때

Azure Firewall의 핵심 가치는 도메인 이름으로 아웃바운드를 통제하는 것입니다. NSG가 못 하는 일입니다.

왜 필요한가를 구체적으로 보면, AKS 클러스터가 이미지를 당기고 패키지를 설치하려면 특정 도메인으로 나가야 합니다. IP로 관리하는 건 불가능합니다.

# 애플리케이션 규칙: 허용할 FQDN만 지정
az network firewall application-rule create \
  --firewall-name afw-prod-krc-01 -g rg-prod-network \
  --collection-name app-allow \
  --name allow-required-fqdn \
  --protocols Https=443 Http=80 \
  --source-addresses 10.10.0.0/16 \
  --target-fqdns \
      "*.azurecr.io" \
      "*.blob.core.windows.net" \
      "mcr.microsoft.com" \
      "*.data.mcr.microsoft.com" \
      "management.azure.com" \
      "*.ubuntu.com" \
  --action Allow \
  --priority 100

# FQDN 태그로 묶어서 지정하는 방법도 있음 (AKS, WindowsUpdate 등)
az network firewall application-rule create \
  --firewall-name afw-prod-krc-01 -g rg-prod-network \
  --collection-name aks-required \
  --name allow-aks \
  --source-addresses 10.10.1.0/24 \
  --fqdn-tags AzureKubernetesService \
  --action Allow --priority 110

--fqdn-tags가 편리합니다. AKS가 필요로 하는 엔드포인트 목록을 Microsoft가 관리해주므로, 하나하나 찾아 넣을 필요가 없습니다.

도입 전 반드시 알아야 할 두 가지

  • 배포만 해도 시간당 요금이 나갑니다. 트래픽이 0이어도 마찬가지입니다. 소규모 구독에서 이것 하나가 전체 비용의 상당 부분을 차지하는 경우를 자주 봅니다. 도입 전에 월 비용을 계산해보세요
  • 강제 터널링 설정이 까다롭습니다. 모든 아웃바운드를 Firewall로 보내려면 사용자 정의 경로(UDR)를 걸어야 하는데, 여기서 비대칭 라우팅이 생겨 통신이 끊기는 사고가 흔합니다. 특히 로드밸런서 인바운드 응답 경로가 Firewall로 빠지면 연결이 안 됩니다

두 번째 문제 때문에, 인바운드가 있는 서브넷은 UDR에서 인터넷 응답 경로를 예외 처리해야 합니다. 이 부분이 Firewall 도입에서 가장 자주 막히는 지점입니다.

WAF — 웹 애플리케이션이 있다면

WAF는 HTTP 요청의 내용을 봅니다. NSG나 Firewall은 “443 포트로 들어오는 정상 트래픽”으로 판단하지만, WAF는 그 안의 ' OR 1=1-- 같은 패턴을 잡아냅니다.

배치 위치가 두 가지입니다.

Application Gateway WAFFront Door WAF
범위리전 내글로벌 엣지
차단 지점리전에 도착한 뒤사용자와 가까운 엣지
DDoS 흡수제한적엣지에서 분산
적합단일 리전 서비스다중 리전·글로벌 서비스

둘을 함께 쓰는 구성도 흔합니다. Front Door에서 광범위한 공격을 걸러내고, Application Gateway에서 애플리케이션에 특화된 규칙을 적용하는 방식입니다.

반드시 탐지 모드로 시작하세요

WAF 도입에서 가장 중요한 실무 지침입니다. 관리형 규칙 집합(OWASP Core Rule Set)은 정상 요청을 차단하는 오탐이 반드시 발생합니다.

# 1) 탐지(Detection) 모드로 시작 - 기록만 하고 차단하지 않음
az network application-gateway waf-policy create \
  --name waf-api-prod -g rg-prod-network \
  --type OWASP --version 3.2

az network application-gateway waf-policy policy-setting update \
  --policy-name waf-api-prod -g rg-prod-network \
  --mode Detection --state Enabled

# 2) 최소 2주 관찰 후 Prevention으로 전환
az network application-gateway waf-policy policy-setting update \
  --policy-name waf-api-prod -g rg-prod-network \
  --mode Prevention

관찰 기간에는 어떤 규칙이 무엇을 잡았는지 확인합니다.

// 탐지 모드에서 걸린 요청 분석
AzureDiagnostics
| where TimeGenerated > ago(14d)
| where Category == "ApplicationGatewayFirewallLog"
| summarize Hits = count(), Paths = dcount(requestUri_s)
        by ruleId_s, Message
| sort by Hits desc
| take 20

여기서 많이 잡히는데 실제로는 정상인 규칙을 찾아 예외 처리합니다. 파일 업로드, 리치 텍스트 에디터, JSON 본문이 큰 API가 흔한 오탐 원인입니다. 이 과정 없이 바로 Prevention으로 켜면 서비스가 멈춥니다.

도입 우선순위: 무엇부터 할 것인가

비용과 효과를 함께 놓고 보면 순서가 나옵니다.

순위조치비용막는 것
1NSG로 관리 포트(22/3389) 차단무료무차별 대입 공격
2NSG 서비스 태그로 아웃바운드 제한무료기본적인 데이터 유출
3웹 앱 앞에 WAF (탐지 → 차단)App GW 요금SQL 인젝션, XSS
4Private Endpoint로 PaaS 공용 접근 차단엔드포인트당 요금스토리지·DB 직접 노출
5Azure Firewall로 FQDN 통제시간당 고정악성 도메인 통신

1~2번은 돈이 안 들면서 효과가 가장 큽니다. 이걸 안 하고 5번부터 검토하는 경우가 있는데, 순서가 반대입니다. 관리 포트 차단은 Bastion으로 22번 포트 닫기에, PaaS 접근 차단은 Private Endpoint와 Service Endpoint에 정리해두었습니다.

5번 Azure Firewall은 규정 요구사항이 있거나 여러 구독을 중앙 통제해야 할 때 도입하는 게 합리적입니다. 소규모에서는 1~4번으로 상당한 수준까지 갈 수 있습니다.

NSG에서 흔히 하는 실수 3가지

서브넷과 NIC에 이중으로 걸기

NSG는 서브넷과 NIC 양쪽에 붙일 수 있습니다. 둘 다 붙이면 인바운드는 서브넷 → NIC 순으로 둘 다 통과해야 하고, 아웃바운드는 반대 순서입니다. 한쪽에서 막고 있는데 다른 쪽만 보다가 몇 시간을 쓰는 경우가 생깁니다.

특별한 이유가 없으면 서브넷에만 붙이는 것을 권합니다. 관리 지점이 하나가 됩니다.

기본 규칙을 잊는 것

NSG에는 보이지 않는 기본 규칙이 있습니다. AllowVnetInBound(VNet 내부는 전부 허용)가 대표적입니다. 서브넷 간 격리를 하려면 이보다 낮은 우선순위 번호로 명시적 Deny를 넣어야 합니다. “NSG를 걸었으니 격리됐다”고 생각하면 착각입니다.

흐름 로그를 안 켜는 것

NSG 흐름 로그가 꺼져 있으면 무엇이 차단됐는지 알 수 없습니다. 통신이 안 될 때 원인 파악이 추측이 됩니다. 켜두면 아래처럼 확인됩니다.

// 어떤 규칙이 무엇을 차단했는지
AzureNetworkAnalytics_CL
| where TimeGenerated > ago(1h)
| where FlowStatus_s == "D"          // D = Denied
| summarize Count = count()
        by NSGRule_s, SrcIP_s, DestIP_s, DestPort_d
| sort by Count desc

정리

  1. 셋은 대체재가 아니라 서로 다른 위치의 도구다 — WAF는 인바운드 L7, NSG는 L3-L4, Firewall은 아웃바운드 FQDN
  2. NSG부터 제대로 쓴다. 무료이고 효과가 가장 크다
  3. 서비스 태그로 아웃바운드를 제한하면 Firewall 없이도 상당 부분 커버된다
  4. WAF는 반드시 탐지 모드로 2주 관찰 후 차단 전환한다
  5. Azure Firewall은 FQDN 통제가 실제로 필요할 때 도입한다 (고정 비용 주의)
  6. NSG 흐름 로그를 켜둔다. 없으면 원인 파악이 추측이 된다

보안 구성은 한 번에 완성하는 게 아니라 무료로 할 수 있는 것부터 쌓아 올리는 편이 현실적입니다. 비싼 도구를 먼저 사는 것보다 NSG 규칙을 정리하는 쪽이 대개 더 큰 개선을 만듭니다.

댓글 남기기