목록으로

Programming Notes

Azure 방화벽과 서비스 엔드포인트

최근 블로그 시리즈 Private Link 현실 점검 에서 Azure 방화벽으로 서비스 엔드포인트를 검사하는 가능성을 간략하게 언급했는데, 많은 분들이 해당 구성에 대한 자세한 내용을 요청하셨습니다. 자, 이제 시작합니다! 우선, 제가 무슨 말을 하고 있는지부터 설명하겠습니다....

최근 블로그 시리즈 Private Link 현실 점검에서 Azure 방화벽으로 서비스 엔드포인트를 검사하는 가능성을 간략하게 언급했는데, 많은 분들이 해당 구성에 대한 자세한 내용을 요청하셨습니다. 자, 이제 시작합니다!

우선, 제가 무슨 말을 하고 있는지부터 설명하겠습니다. Azure Storage, Azure SQL 등 대부분의 Azure 서비스는 공용 인터넷을 통해 직접 액세스할 수 있습니다. 하지만 Microsoft 백본을 통해 이러한 서비스에 액세스할 수 있는 두 가지 대안이 있습니다. 바로 Private LinkVNet 서비스 엔드포인트입니다. Microsoft는 일반적으로 Private Link를 권장하지만, 일부 조직에서는 서비스 엔드포인트를 활용하는 것을 선호합니다. 두 가지를 비교한 이 게시물을 읽어보시면 도움이 될 것입니다.

서비스 엔드포인트를 활용하는 트래픽을 포함하여 네트워크 방화벽으로 Azure 서비스로의 트래픽을 검사하고 싶을 수 있습니다. 그렇게 하기 전에, 고대역폭 트래픽을 방화벽을 통해 보내는 것은 비용에 영향을 미치고 전체 애플리케이션 지연 시간에 영향을 줄 수 있다는 점을 고려하십시오. 그래도 계속 진행하고 싶다면 이 게시물에서는 그 방법을 설명합니다.

설계

서비스 엔드포인트는 두 가지 구성 요소로 구성됩니다.

  • 대상 서비스로 트래픽을 터널링하는 소스 서브넷 구성
  • 소스 서브넷에서 오는 트래픽을 수락하는 대상 서비스 구성

핵심 개념은 클라이언트의 트래픽이 Azure 서비스로 가기 전에 방화벽에 의해 검사되는 경우, 소스 서브넷은 실제로 원래 클라이언트의 서브넷이 아니라 Azure 방화벽의 서브넷이라는 것입니다.

[이미지: 방화벽을 통해 서비스 엔드포인트 트래픽이 라우팅되는 아키텍처 다이어그램. 클라이언트 서브넷 -> Azure 방화벽 서브넷 -> 서비스 엔드포인트 -> Azure 서비스 순서로 트래픽이 흐름]

포털, Terraform, Bicep, PowerShell 또는 Azure CLI를 사용하여 특정 Azure 서비스에 대한 서비스 엔드포인트를 서브넷에 구성할 수 있습니다. 포털에서는 다음과 같은 모습입니다.

[이미지: Azure 포털에서 서비스 엔드포인트 구성 화면]

Azure CLI의 경우, 모든 지역에서 Azure Storage 계정에 대해 서비스 엔드포인트를 활성화하는 방법은 다음과 같습니다.

❯ subnet_name=AzureFirewallSubnet
❯ az network vnet subnet update -n $subnet_name --vnet-name $vnet_name -g $rg --service-endpoints Microsoft.Storage.Global -o none --only-show-errors

그런 다음 Azure 방화벽 서브넷에서 오는 트래픽을 수락하도록 Azure 서비스를 구성합니다. 예를 들어 Azure Storage 계정의 경우 포털에서 다음과 같이 표시됩니다.

[이미지: Azure Storage 계정에서 네트워크 설정 구성 화면]

네트워크 규칙인가, 애플리케이션 규칙인가?

이상적으로는 워크로드가 올바른 Azure 서비스에 액세스하고 있는지 확인하기 위해 방화벽에서 애플리케이션 규칙을 사용해야 합니다. 그렇지 않으면 다른 사람이 소유하고 동일한 IP 주소를 가질 수 있는 불량 데이터 서비스로 데이터가 유출될 수 있습니다.

다음은 모든 Azure Storage 계정에 대한 액세스를 허용하는 별표 규칙의 예이지만, 자신의 규칙을 지정해야 합니다.

[이미지: Azure 방화벽 애플리케이션 규칙 구성 화면]

클라이언트(이 경우 Azure 방화벽)와 동일한 지역과 다른 지역에 있는 두 개의 스토리지 계정으로 테스트했습니다. 두 스토리지 계정에 대한 액세스가 모두 작동하며, 두 액세스 모두 스토리지 계정과 Azure 방화벽에 기록된 것을 확인할 수 있습니다(스토리지 계정 이름에서 일부 문자를 제거하여 가렸습니다).

❯ ssh $vm_pip "curl -s4 $storage_blob_fqdn1"
Hello world!
❯ ssh $vm_pip "curl -s4 $storage_blob_fqdn2"
Hello world!
❯ query='StorageBlobLogs | where TimeGenerated > ago(15m) | project AccountName, StatusCode, CallerIpAddress'
❯ az monitor log-analytics query -w $logws_customerid --analytics-query $query -o table
AccountName              CallerIpAddress     StatusCode
----------------------   -----------------   ----------
storagetest????eastus2   10.13.76.72:10066   200
storagetest????westus2   10.13.76.72:11880   200
❯ query='AzureDiagnostics | where TimeGenerated > ago(15m) | where Category == "AZFWApplicationRule" | project SourceIP, Fqdn_s, Protocol_s, Action_s'
❯ az monitor log-analytics query -w $logws_customerid --analytics-query $query -o table
Action_s  Fqdn_s                                       Protocol_s SourceIP
--------- -------------------------------------------- ---------- ----------
Allow     storagetest????eastus2.blob.core.windows.net HTTPS      10.13.76.4
Allow     storagetest????westus2.blob.core.windows.net HTTPS      10.13.76.4

스토리지 계정은 Azure 방화벽의 IP(서브넷 10.13.76.64/26)를 클라이언트 IP로 인식하고, Azure 방화벽 로그는 실제 클라이언트 IP(워크로드 서브넷 10.13.76.0/26)를 보여줍니다.

네트워크 규칙을 사용하는 경우 FQDN 기반 규칙을 사용하더라도 Azure 방화벽의 유연성을 많이 잃게 됩니다. 그 이유는 동일한 IP 주소를 공유하는 FQDN이 다른 2개의 스토리지 계정이 있고, 동일한 클라이언트가 두 FQDN을 모두 확인하는 경우, Azure 방화벽이 패킷을 볼 때 각 특정 패킷이 어떤 스토리지 계정에 속하는지 추측할 수 없기 때문입니다. 하지만 공용 IP 주소가 관련된 경우 IP 주소를 변환하는 Azure 방화벽의 기본 SNAT 설정을 사용하는 한 라우팅 관점에서는 여전히 작동합니다.

[이미지: Azure 방화벽 SNAT 구성 화면]

결론

Private Link 대신 VNet 서비스 엔드포인트를 선택해야 하는 몇 가지 이유가 있을 수 있습니다(비용이 그 중 하나일 수 있음). 그렇다면 Azure 서비스를 통해 방화벽으로 트래픽을 보내는 데에는 장단점이 있습니다. Azure 방화벽으로 VNet 서비스 엔드포인트로의 트래픽을 검사하기로 결정했다면, 이 게시물이 그 방법을 보여주었기를 바랍니다.

이것에 대해 어떻게 생각하십니까?