방화벽 뒤에서 Microsoft Teams 채널 봇 및 웹앱 보호 가능

Azure App Service
Azure 웹 애플리케이션 방화벽

이 시나리오 예를 통해 Azure Private Link 및 Azure 프라이빗 엔드포인트를 사용하여 Microsoft Teams 채널 봇의 웹앱에 대한 연결을 보호할 수 있습니다. 동시에 Teams 클라이언트의 채널이 Azure Firewall 인스턴스를 통해 노출되는 IP를 통해 봇과 통신할 수 있습니다.

아키텍처

Teams-to-Azure Firewall 순서도를 보여 주는 다이어그램.

이 아키텍처의 Visio 파일을 다운로드합니다.

데이터 흐름

  • Azure Virtual Network를 사용하면 Azure 리소스 간의 통신이 가능합니다. 이 예의 가상 네트워크는 10.0.0.0/16의 주소 공간을 사용하며 시나리오의 필수 구성 요소에서 사용할 세 개의 서브넷을 포함합니다.

    • Azure Firewall 서브넷(10.0.1.0/26).

    • 봇의 프라이빗 엔드포인트에서 방화벽으로 트래픽을 라우팅하는 데 사용되는 Virtual Network 통합 서브넷(10.0.2.0/24).

    • 프라이빗 엔드포인트 서브넷(10.0.3.0/24): 방화벽에서 봇의 프라이빗 엔드포인트로 트래픽을 라우팅하는 데 사용됩니다.

  • Azure Firewall은 클라이언트가 기본 봇 서비스와 통신하는 데 사용할 수 있는 단일 공용 IP 주소를 노출합니다. 일반적으로 방화벽은 허브 및 스포크 아키텍처의 일반적인 패턴인 자체 가상 네트워크에 배치되지만 이 간단한 예에서는 전체 서비스와 리소스를 단일 가상 네트워크에 배포합니다. Azure Firewall 인스턴스는 자체 서브넷에 배치됩니다.

  • 경로 테이블은 가상 네트워크 내에서 트래픽이 사용하는 경로를 정의합니다. 봇과 주고받는 트래픽이 방화벽을 통과하도록 합니다.

    • 0.0.0.0/0 주소 접두사가 있는 기본 경로는 다른 경로의 주소 접두사 내에 없는 트래픽을 Azure Firewall 인스턴스가 배포된 서브넷으로 라우팅하도록 Azure에 지시합니다. 이 예에서는 유일한 경로입니다.

    • Virtual Network 통합 서브넷프라이빗 엔드포인트 서브넷은 경로 테이블과 연결되어 이를 통과하는 모든 트래픽이 방화벽을 통해 라우팅되도록 합니다.

  • Bot Service는 봇 App Service 요금제, App Service봇 채널 등록으로 구성됩니다.

    • App Service에는 방화벽의 IP 주소를 가리키는 등록된 사용자 지정 도메인이 있습니다. 이렇게 하면 방화벽을 통해서만 App Service에 액세스할 수 있습니다.
  • Azure Private Link 서비스는 Azure 프라이빗 엔드포인트를 통해 봇 App Service에 대한 인바운드 액세스를 제공합니다.

  • 가상 네트워크 통합은 App Service를 가상 네트워크에 연결하여 봇 App Service의 아웃바운드 트래픽이 방화벽을 통과하도록 합니다.

구성 요소

대안

  • App Service Environment는 App Service 앱을 대규모로 안전하게 실행하기 위해 완전히 격리된 전용 환경을 제공할 수 있습니다. 이 예에서는 비용 절감을 위해 App Service Environment를 사용하지 않지만 샘플 아키텍처는 수정을 통해 이를 지원할 수 있습니다.

시나리오 정보

봇을 사용하면 Teams 사용자가 텍스트, 대화형 카드 및 작업 모듈을 통해 웹 서비스와 상호 작용할 수 있습니다. Microsoft Bot Framework 및 Azure Bot Services는 이러한 봇을 만들고 관리하기 위한 사용하기 쉬운 도구 집합을 제공합니다.

C#, JavaScript, Python 등 다양한 언어를 사용하여 봇을 개발할 수 있습니다. 개발 후 Azure에 배포할 수 있습니다. 봇의 핵심 구성 요소는 사용자가 통신하는 핵심 논리 및 인터페이스를 포함하는 웹앱입니다. 봇이 작동하기 위한 주요 요구 사항 중 하나는 공용적으로 액세스 가능한 HTTPS 엔드포인트를 노출해야 한다는 것입니다.

InfoSec 정책은 일반적으로 웹앱으로 들어오는 모든 트래픽이 회사 방화벽을 통과하도록 요구합니다. 즉, 봇으로 가는 모든 트래픽과 봇의 응답은 다른 웹앱과 마찬가지로 회사 방화벽을 통해 라우팅되어야 합니다.

잠재적인 사용 사례

조직은 모바일 및 데스크톱 사용자를 위해 봇을 활용할 수 있습니다. 일부 사례:

  • 단순 쿼리. 봇은 명확성을 돕기 위해 쿼리 또는 관련 일치 그룹에 대한 정확한 일치를 제공할 수 있습니다.
  • 멀티 턴 상호 작용. 봇은 가능한 다음 단계를 예상하도록 하여 사용자가 작업 흐름을 훨씬 쉽게 완료할 수 있도록 합니다.
  • 사용자에게 다가갑니다. 봇은 문서에서 무언가가 변경되거나 작업 항목이 닫힐 때 메시지를 보낼 수 있습니다.

고려 사항

모니터링

이 시나리오 예에서는 모니터링이 구현되지 않았지만 봇의 App Service는 Azure Monitor 서비스를 활용하여 가용성과 성능을 모니터링할 수 있습니다.

확장성

이 시나리오에서 사용되는 봇은 Azure App Service에서 호스팅됩니다. 결과적으로 표준 App Service 자동 크기 조정 기능을 사용하여 봇을 실행하는 인스턴스 수를 자동으로 크기 조정하여 봇이 수요를 따라갈 수 있도록 할 수 있습니다. 자동 확장에 대한 자세한 내용은 자동 확장 모범 사례를 참조하세요.

다른 확장성 항목은 Azure 아키텍처 센터 성능 효율성 검사 목록을 참조하세요.

DevOps

지속적인 배포 파이프라인을 사용하여 웹앱, API 앱 및 모바일 앱을 Azure App Service 요금제에 배포하는 것이 일반적입니다. 보안 봇의 App Service는 프라이빗 엔드포인트로 보호되기 때문에 외부에서 호스트되는 빌드 에이전트에는 업데이트를 배포하는 데 필요한 액세스 권한이 없습니다. 이 문제를 해결하려면 Azure Pipeline 자체 호스팅 DevOps 에이전트와 같은 솔루션을 사용해야 할 수 있습니다.

보안

애플리케이션 설계 모범 사례와 결합된 Azure DDoS Protection은 향상된 DDoS 완화 기능을 제공하여 DDoS 공격에 대한 방어력을 높입니다. 경계 가상 네트워크에서 Azure DDOS Protection을 사용하도록 설정해야 합니다.

시나리오 배포

필수 구성 요소

기존 Azure 계정이 있어야 합니다. Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

연습

  1. Azure Cloud Shell 또는 기본 배포 셸에서 다음 Azure CLI 명령을 실행합니다.

    이 명령 집합은 이 연습에 필요한 필수 리소스 그룹, 가상 네트워크 및 서브넷을 만듭니다. Teams에서 사용하는 IP 범위는 52.112.0.0/14,52.122.0.0/15입니다.

    # Declare variables (bash syntax)
    export PREFIX='SecureBot'
    export RG_NAME='rg-'${PREFIX}
    export VNET_NAME='vnet-'${PREFIX}
    export SUBNET_INT_NAME='VnetIntegrationSubnet'
    export SUBNET_PVT_NAME='PrivateEndpointSubnet'
    export LOCATION='eastus'
    export TEAMS_IP_RANGE='52.112.0.0/14 52.122.0.0/15'
    export FIREWALL_NAME='afw-'${LOCATION}'-'${PREFIX}
    
    # Create a resource group
    az group create --name ${RG_NAME} --location ${LOCATION}
    
    # Create a virtual network with a subnet for the firewall
    az network vnet create \
    --name ${VNET_NAME} \
    --resource-group ${RG_NAME} \
    --location ${LOCATION} \
    --address-prefix 10.0.0.0/16 \
    --subnet-name AzureFirewallSubnet \
    --subnet-prefix 10.0.1.0/26
    
    # Add a subnet for the Virtual network integration
    az network vnet subnet create \
    --name ${SUBNET_INT_NAME} \
    --resource-group ${RG_NAME} \
    --vnet-name ${VNET_NAME} \
    --address-prefix 10.0.2.0/24
    
    # Add a subnet where the private endpoint will be deployed for the app service
    az network vnet subnet create \
    --name ${SUBNET_PVT_NAME} \
    --resource-group ${RG_NAME} \
    --vnet-name ${VNET_NAME} \
    --address-prefix 10.0.3.0/24
    

    프라이빗 엔드포인트 서브넷을 만들면 프라이빗 엔드포인트 정책이 기본적으로 사용하지 않도록 설정됩니다.

    배포가 완료되면 가상 네트워크 내에 다음 서브넷이 표시되어야 합니다.

    vnet-SecureBot

  2. 다음 CLI 명령을 실행하여 1단계에서 만든 방화벽 서브넷에 Azure Firewall 인스턴스를 배포합니다.

    # Create a firewall
    az network firewall create \
        --name ${FIREWALL_NAME} \
        --resource-group ${RG_NAME} \
        --location ${LOCATION}
    
    # Create a public IP for the firewall
    az network public-ip create \
        --name ${FIREWALL_NAME}-pip \
        --resource-group ${RG_NAME} \
        --location ${LOCATION} \
        --allocation-method static \
        --sku standard
    
    # Associate the IP with the firewall
    az network firewall ip-config create \
        --firewall-name ${FIREWALL_NAME} \
        --name ${FIREWALL_NAME}-Config \
        --public-ip-address ${FIREWALL_NAME}-pip \
        --resource-group ${RG_NAME} \
        --vnet-name ${VNET_NAME}
    
    # Update the firewall
    az network firewall update \
        --name ${FIREWALL_NAME} \
        --resource-group ${RG_NAME}
    
    # Get the public IP address for the firewall and take note of it for later use
    az network public-ip show \
        --name ${FIREWALL_NAME}-pip \
        --resource-group ${RG_NAME}
    

    방화벽 구성은 다음과 같아야 합니다.

    fw-SecureBot 방화벽 구성의 스크린샷.

  3. 기본 봇을 만듭니다.

  4. 1단계에서 만든 리소스 그룹에 기본 봇을 배포합니다.

    이 프로세스의 일부로 채널을 통해 봇과 상호 작용하는 데 필요한 앱 등록을 만듭니다. 이 프로세스 중에 필요한 App Service 요금제, App Service 및 웹앱 봇도 배포합니다.

    참고

    Azure Private Link를 지원하는 App Service 요금제를 선택합니다.

  5. 3단계에서 리소스 그룹에 배포된 App Service에 사용자 지정 도메인을 매핑합니다.

    이 단계에서는 도메인 등록 기관에 액세스해야 하며 2단계에서 만든 방화벽의 공용 IP를 가리키는 사용자 지정 도메인에 A 레코드를 추가해야 합니다.

  6. 도메인에 대한 기존 인증서를 업로드하거나 Azure에서 App Service Certificate를 구매하고 가져와서 매핑된 사용자 지정 도메인을 보호합니다. Azure App Service에서 TLS/SSL 바인딩을 사용하여 사용자 지정 DNS 이름 보안의 단계에 따라 이 작업을 수행할 수 있습니다.

    이제 Teams의 채널에 추가하거나 Bot Framework SDK 설명서에 있는 지침을 사용하여 웹 채팅을 통해 테스트할 수 있는 완전한 기능의 봇이 있어야 합니다.

    참고

    이 시점에서 봇의 App Service는 여전히 azurewebsites.net URL과 구성한 사용자 지정 URL을 통해 공개적으로 액세스할 수 있습니다. 다음 단계에서는 프라이빗 엔드포인트를 사용하여 공용 액세스를 사용하지 않도록 설정합니다. 또한 봇 서비스가 Teams 클라이언트와만 통신할 수 있도록 방화벽을 구성합니다.

  7. 다음 Azure CLI 스크립트를 실행하여 프라이빗 엔드포인트를 배포 및 구성합니다. 이 단계에서는 또한 가상 네트워크의 통합 서브넷에 연결하는 봇의 App Service에 대한 가상 네트워크 통합을 구현합니다.

    # Disable private endpoint network policies (this step is not required if you're using the Azure portal)
    az network vnet subnet update \
      --name ${SUBNET_PVT_NAME} \
      --resource-group ${RG_NAME} \
      --vnet-name ${VNET_NAME} \
      --disable-private-endpoint-network-policies true
    
    # Create the private endpoint, being sure to copy the correct resource ID from your deployment of the bot app service
    # The ID can be viewed by using the following CLI command:
    # az resource show --name wapp-securebot --resource-group rg-securebot --resource-type Microsoft.web/sites --query "id" 
    az network private-endpoint create \
      --name pvt-${PREFIX}Endpoint \
      --resource-group ${RG_NAME} \
      --location ${LOCATION} \
      --vnet-name ${VNET_NAME} \
      --subnet ${SUBNET_PVT_NAME} \
      --connection-name conn-${PREFIX} \
      --private-connection-resource-id /subscriptions/cad87d9e-c941-4519-a638-c9804a0577b9/resourceGroups/rg-securebot/providers/Microsoft.Web/sites/wapp-securebot \
      --group-id sites
    
    # Create a private DNS zone to resolve the name of the app service
    az network private-dns zone create \
      --name ${PREFIX}privatelink.azurewebsites.net \
      --resource-group ${RG_NAME}
    
    az network private-dns link vnet create \
      --name ${PREFIX}-DNSLink \
      --resource-group ${RG_NAME} \
      --registration-enabled false \
      --virtual-network ${VNET_NAME} \
      --zone-name ${PREFIX}privatelink.azurewebsites.net
    
    az network private-endpoint dns-zone-group create \
      --name chatBotZoneGroup \
      --resource-group ${RG_NAME} \
      --endpoint-name pvt-${PREFIX}Endpoint \
      --private-dns-zone ${PREFIX}privatelink.azurewebsites.net \
      --zone-name ${PREFIX}privatelink.azurewebsites.net
    
    # Establish virtual network integration for outbound traffic
    az webapp vnet-integration add \
      -g ${RG_NAME} \
      -n wapp-${PREFIX} \
      --vnet ${VNET_NAME} \
      --subnet ${SUBNET_INT_NAME}
    

    이러한 명령을 실행한 후에는 리소스 그룹에 다음 리소스가 표시되어야 합니다.

    리소스 그룹의 리소스 목록을 보여 주는 스크린샷.

    App Service의 네트워킹 섹션에 있는 VNet 통합 옵션은 다음과 같아야 합니다.

    wapp-securebot

    'VNet 통합' 옵션의 스크린샷.

    '프라이빗 엔드포인트 연결' 창의 스크린샷.

  8. 다음으로 각 서브넷에서 들어오고 나가는 트래픽이 방화벽을 통과하도록 경로 테이블을 만듭니다. 이전 단계에서 만든 방화벽의 개인 IP 주소가 필요합니다.

    # Create a route table
    az network route-table create \
      -g ${RG_NAME} \
      -n rt-${PREFIX}RouteTable
    
    # Create a default route with 0.0.0.0/0 prefix and the next hop as the Azure firewall virtual appliance to inspect all traffic. Make sure you use your firewall's internal IP address instead of 10.0.1.4
    az network route-table route create -g ${RG_NAME} \
      --route-table-name rt-${PREFIX}RouteTable -n default \
      --next-hop-type VirtualAppliance \
      --address-prefix 0.0.0.0/0 \
      --next-hop-ip-address 10.0.1.4
    
    # Associate the two subnets with the route table
    az network vnet subnet update -g ${RG_NAME} \
      -n ${SUBNET_INT_NAME} --vnet-name ${VNET_NAME} \
      --route-table rt-${PREFIX}RouteTable
    
    az network vnet subnet update -g ${RG_NAME} \
      -n ${SUBNET_PVT_NAME} \
      --vnet-name ${VNET_NAME} \
      --route-table rt-${PREFIX}RouteTable
    

    명령을 실행한 후 경로 테이블 리소스는 다음과 같아야 합니다.

    rt-SecureBotRouteTable 창의 스크린샷.

    경로 테이블을 만든 후에는 방화벽에 규칙을 추가하여 공용 IP에서 봇 App Service로 트래픽을 배달하고 Microsoft Teams 이외의 엔드포인트에서 오는 트래픽을 제한합니다. 또한 서비스 태그를 사용하여 가상 네트워크와 Azure Bot Services 또는 Microsoft Entra ID 간의 트래픽을 허용합니다.

  9. 다음 명령을 실행합니다.

    # Create a NAT rule collection and a single rule. The source address is the public IP range of Microsoft Teams
    # Destination address is that of the firewall. 
    # The translated address is that of the app service's private link.
    az network firewall nat-rule create \
      --resource-group ${RG_NAME} \
      --collection-name coll-${PREFIX}-nat-rules \
      --priority 200 \
      --action DNAT \
      --source-addresses ${TEAMS_IP_RANGE} \
      --dest-addr 23.100.26.84 \
      --destination-ports 443 \
      --firewall-name ${FIREWALL_NAME} \
      --name rl-ip2appservice \
      --protocols TCP \
      --translated-address 10.0.3.4 \
      --translated-port 443
    
    # Create a network rule collection and add three rules to it. 
    # The first one is an outbound network rule to only allow traffic to the Teams IP range.
    # The source address is that of the virtual network address space, destination is the Teams IP range.
    az network firewall network-rule create \
      --resource-group ${RG_NAME} \
      --collection-name coll-${PREFIX}-network-rules \
      --priority 200 \
      --action Allow \
      --source-addresses 10.0.0.0/16 \
      --dest-addr ${TEAMS_IP_RANGE} \
      --destination-ports 443 \
      --firewall-name ${FIREWALL_NAME} \
      --name rl-OutboundTeamsTraffic \
      --protocols TCP
    
    # This rule will enable traffic to all IP addresses associated with Azure AD service tag
    az network firewall network-rule create \
      --resource-group ${RG_NAME} \
      --collection-name coll-${PREFIX}-network-rules \
      --source-addresses 10.0.0.0/16 \
      --dest-addr AzureActiveDirectory \
      --destination-ports '*' \
      --firewall-name ${FIREWALL_NAME} \
      --name rl-AzureAD \
      --protocols TCP
    
    # This rule will enable traffic to all IP addresses associated with Azure Bot Services service tag
    az network firewall network-rule create \
      --resource-group ${RG_NAME} \
      --collection-name coll-${PREFIX}-network-rules \
      --source-addresses 10.0.0.0/16 \
      --dest-addr AzureBotService \
      --destination-ports '*' \
      --firewall-name ${FIREWALL_NAME} \
      --name rl-AzureBotService \
      --protocols TCP
    

    명령을 실행하면 방화벽 규칙이 다음과 같이 표시됩니다.

    'NAT 규칙 컬렉션 편집' 창의 스크린샷.

    '네트워크 규칙 컬렉션 편집' 창의 스크린샷.

  10. Teams의 채널에서만 봇에 액세스할 수 있는지 확인하고, 봇 App Service에서 들어오고 나가는 모든 트래픽이 방화벽을 통과하는지 확인합니다.

참가자

Microsoft에서 이 문서를 유지 관리합니다. 원래 다음 기여자가 작성했습니다.

보안 주체 작성자:

  • Ali Jafry | 클라우드 솔루션 설계자

다음 단계