Azure Application Gateway와 Azure SignalR Service를 사용하는 방법

Application Gateway는 웹 애플리케이션에 대한 트래픽을 관리할 수 있는 웹 트래픽 부하 분산 장치입니다. SignalR Service와 Application Gateway를 사용하면 다음을 수행할 수 있습니다.

  • 일반적인 웹 취약성으로부터 애플리케이션을 보호합니다.
  • 확장 가능하고 가용성이 높은 애플리케이션에 대한 애플리케이션 수준 부하 분산을 실행합니다.
  • 엔드투엔드 보안을 설정합니다.
  • 도메인 이름을 사용자 지정합니다.

이 문서에는 다음과 같은 두 부분이 포함되어 있습니다.

  • 첫 번째 부분에서는 클라이언트가 Application Gateway를 통해 SignalR에 액세스할 수 있도록 Application Gateway를 구성하는 방법을 보여 줍니다.
  • 두 번째 부분에서는 SignalR Service에 액세스 제어를 추가하여 SignalR Service를 보호하고 Application Gateway에서 들어오는 트래픽만 허용하는 방법을 보여 줍니다.

Diagram that shows the architecture of using SignalR Service with Application Gateway.

Application Gateway 설정 및 구성

SignalR Service 인스턴스 만들기

  • 문서를 따라 SignalR Service 인스턴스 ASRS1 만들기

Application Gateway 인스턴스 만들기

포털에서 Application Gateway 인스턴스 AG1을 만듭니다.

  • Azure Portal에서 Application Gateway를 검색하고 만들기를 수행합니다.

  • 기본 사항 탭에서 다음 애플리케이션 게이트웨이 설정에 이러한 값을 사용합니다.

    • 구독리소스 그룹지역: SignalR Service에 대해 선택한 것과 동일합니다.

    • 애플리케이션 게이트웨이 이름: AG1

    • 가상 네트워크에서 새로 만들기를 선택하고 열리는 가상 네트워크 만들기 창에서 다음 값을 입력하여 가상 네트워크와 서브넷 2개(애플리케이션 게이트웨이용 하나, 백 엔드 서버용 하나)를 만듭니다.

      • 이름: 가상 네트워크 이름에 VN1을 입력합니다.

      • 서브넷: 서브넷 그리드를 2개 미만의 서브넷으로 업데이트합니다.

        서브넷 이름 주소 범위 참고 항목
        myAGSubnet (주소 범위) 애플리케이션 게이트웨이용 서브넷입니다. 애플리케이션 게이트웨이 서브넷은 애플리케이션 게이트웨이만 포함할 수 있습니다. 다른 리소스는 허용되지 않습니다.
        myBackendSubnet (다른 주소 범위) Azure SignalR 인스턴스용 서브넷입니다.
    • 다른 설정에 기본값을 적용한 다음, 다음: 프런트 엔드를 선택합니다.

    Screenshot of creating Application Gateway instance with Basics tab.

  • 프런트 엔드 탭에서 다음을 수행합니다.

    • 프런트 엔드 IP 주소 유형: 공용
    • 공용 IP 주소에 대해 새로 추가를 선택하고 공용 IP 주소 이름으로 myAGPublicIPAddress를 입력한 다음, 확인을 선택합니다.
    • 다음: 백 엔드Screenshot of creating Application Gateway instance with Frontends tab.를 선택합니다.
  • 백 엔드 탭에서 백 엔드 풀 추가를 선택합니다.

    • 이름: SignalR Service 리소스 백 엔드 풀에 signalr을 입력합니다.
    • 백 엔드 대상 대상: SignalR Service 인스턴스 ASRS1호스트 이름(예: asrs1.service.signalr.net)
    • 다음: 구성을 선택합니다.

    Screenshot of setting up the application gateway backend pool for the SignalR Service.

  • 구성 탭의 회람 규칙 열에서 회람 규칙 추가를 선택합니다.

    • 규칙 이름: myRoutingRule

    • 우선 순위: 1

    • 라우팅 규칙 추가 창 내의 수신기 탭에서 수신기에 대해 다음 값을 입력합니다.

      • 수신기 이름: 수신기 이름으로 myListener를 입력합니다.
      • 프런트 엔드 IP: 프런트 엔드용으로 만든 공용 IP를 선택하려면 공용을 선택합니다.
      • 프로토콜: HTTP
        • 이 문서에서는 모를 간소화하고 더 쉽게 시작할 수 있도록 Application Gateway에 HTTP 프런트 엔드 프로토콜을 사용합니다. 그러나 실제로는 프로덕션 시나리오에서 HTTPs 및 Custom Domain을 사용하도록 설정해야 할 수 있습니다.
      • 수신기Screenshot of setting up the application gateway routing rule listener tab for the SignalR Service.의 다른 설정에는 기본값을 적용합니다.
    • 백 엔드 대상 탭에서 다음 값을 사용합니다.

      • 대상 유형: 백 엔드 풀

      • 백 엔드 대상: 이전에 만든 signalr을 선택합니다.

      • 백 엔드 설정: 새 설정을 추가하려면 새로 추가를 선택합니다.

        • 백 엔드 설정 이름: mySetting
        • 백 엔드 프로토콜: HTTPS
        • 잘 알려진 CA 인증서 사용:
        • 새 호스트 이름으로 재정의:
        • 호스트 이름 재정의: 백 엔드 대상에서 호스트 이름 선택
        • 다른 설정은 기본값을 유지합니다.

        Screenshot of setting up the application gateway backend setting for the SignalR Service.

      Screenshot of creating backend targets for application gateway.

  • AG1Screenshot of reviewing and creating the application gateway instance.을 검토하고 만듭니다.

Application Gateway 상태 프로브 구성

AG1이 만들어지면 포털의 설정 섹션 아래에 있는 상태 프로브 탭으로 이동하고 상태 프로브 경로를 /api/health로 변경합니다.

Screenshot of setting up the application gateway backend health probe for the SignalR Service.

빠른 테스트

  • 잘못된 클라이언트 요청(https://asrs1.service.signalr.net/client)으로 시도하면 'hub' 쿼리 매개 변수는 필수입니다.라는 오류 메시지와 함께 400이 반환됩니다. 이는 요청이 SignalR Service에 도달했으며 요청 유효성 검사를 수행했음을 의미합니다.

    curl -v https://asrs1.service.signalr.net/client
    

    returns

    < HTTP/1.1 400 Bad Request
    < ...
    <
    'hub' query parameter is required.
    
  • AG1의 개요 탭으로 이동하여 프런트 엔드 공용 IP 주소를 확인합니다.

    Screenshot of quick testing SignalR Service health endpoint through Application Gateway.

  • AG1http://<frontend-public-IP-address>/client을 통해 상태 엔드포인트를 방문해도 'hub' 쿼리 매개 변수는 필수입니다.라는 오류 메시지와 함께 400이 반환됩니다. 이는 요청이 Application Gateway를 통과하여 SignalR Service에 도달했으며 요청 유효성 검사를 수행했음을 의미합니다.

    curl -I http://<frontend-public-IP-address>/client
    

    returns

    < HTTP/1.1 400 Bad Request
    < ...
    <
    'hub' query parameter is required.
    

Application Gateway를 통해 채팅 실행

이제 트래픽이 Application Gateway를 통해 SignalR Service에 도달할 수 있습니다. 고객은 Application Gateway 공용 IP 주소 또는 사용자 지정 도메인 이름을 사용하여 리소스에 액세스할 수 있습니다. 이 채팅 애플리케이션을 예로 들어 보겠습니다. 먼저 로컬로 실행해 보겠습니다.

  • 먼저 ASRS1의 연결 문자열을 가져옵니다.

    • ASRS1연결 문자열 탭에서
      • 클라이언트 엔드포인트: AG1의 프런트 엔드 공용 IP 주소를 사용하여 URL을 입력합니다(예: http://20.88.8.8). 이는 역방향 프록시를 사용할 때 연결 문자열 생성기이며, 다음에 이 탭으로 돌아올 때까지 값이 유지되지 않습니다. 값을 입력하면 연결 문자열이 ClientEndpoint 섹션을 추가합니다.
      • 연결 문자열 Screenshot of getting the connection string for SignalR Service with client endpoint.을 복사합니다.
  • GitHub 리포지토리(https://github.com/aspnet/AzureSignalR-samples)를 복제합니다.

  • samples/Chatroom 폴더로 이동합니다.

  • 복사한 연결 문자열을 설정하고 로컬에서 애플리케이션을 실행하면 ConnectionString에 ClientEndpoint 섹션이 있음을 확인할 수 있습니다.

    cd samples/Chatroom
    dotnet restore
    dotnet user-secrets set Azure:SignalR:ConnectionString "<copied-onnection-string-with-client-endpoint>"
    dotnet run
    
  • 브라우저에서 http://localhost:5000을 열고 F12 키를 사용하여 네트워크 추적을 확인합니다. AG1을 통해 WebSocket 연결이 설정된 것을 볼 수 있습니다.

    Screenshot of running chat application locally with App Gateway and SignalR Service.

SignalR Service 보호

이전 섹션에서는 SignalR Service를 Application Gateway의 백 엔드 서비스로 구성했습니다. 공용 네트워크에서 직접 또는 Application Gateway를 통해 SignalR Service를 호출할 수 있습니다.

이 섹션에서는 공용 네트워크의 모든 트래픽을 거부하고 Application Gateway의 트래픽만 허용하도록 SignalR Service를 구성해 보겠습니다.

SignalR Service 구성

프라이빗 액세스만 허용하도록 SignalR Service를 구성해 보겠습니다. SignalR Service에 프라이빗 엔드포인트 사용에서 자세한 내용을 확인할 수 있습니다.

  • 포털에서 SignalR Service 인스턴스 ASRS1로 이동합니다.

  • 네트워킹 탭으로 이동합니다.

    • 공용 액세스 탭에서 공용 네트워크 액세스사용 안 함으로 변경하고 저장을 선택하면 이제 공용 네트워크에서 SignalR Service에 더 이상 액세스할 수 없습니다.

      Screenshot of disabling public access for SignalR Service.

    • 개인 액세스 탭에서 + 프라이빗 엔드포인트를 선택합니다.

      • 기본 사항 탭에서
        • 이름: PE1
        • 네트워크 인터페이스 이름: PE1-nic
        • 지역: Application Gateway와 동일한 지역을 선택해야 합니다.
        • 다음: 리소스를 선택합니다.
      • 리소스 탭에서
        • 기본값을 유지합니다.
        • 다음: Virtual Network를 선택합니다.
      • Virtual Network 탭에서
        • 가상 네트워크: 이전에 만든 VN1을 선택합니다.
        • 서브넷: 이전에 만든 VN1/myBackendSubnet을 선택합니다.
        • 다른 항목은 기본 설정을 유지합니다.
        • 다음: DNS를 선택합니다.
      • DNS 탭에서
        • 프라이빗 DNS 영역과 통합:
      • 프라이빗 엔드포인트 검토 및 생성

    Screenshot of setting up the private endpoint resource for the SignalR Service.

Application Gateway 백 엔드 풀 새로 고침

Application Gateway가 사용할 프라이빗 엔드포인트보다 먼저 설정되었으므로 백 엔드 풀을 새로 고침하여 Application Gateway가 프라이빗 DNS 영역을 보고 공용 주소 대신 프라이빗 엔드포인트로 트래픽을 라우팅해야 한다는 것을 인식하도록 해야 합니다. 백 엔드 FQDN을 다른 값으로 설정한 다음, 다시 변경하여 새로 고침을 수행합니다.

AG1백 엔드 풀 탭으로 이동하고 signalr을 선택합니다.

  • 1단계: 대상(asrs1.service.signalr.net)을 다른 값(예: x.service.signalr.net)으로 변경하고 저장을 선택합니다.
  • 2단계: 대상을 asrs1.service.signalr.net으로 다시 변경합니다.

빠른 테스트

  • 이제 https://asrs1.service.signalr.net/client를 다시 방문해 보겠습니다. 공용 액세스를 사용하지 않도록 설정하면 403이 대신 반환됩니다.

    curl -v https://asrs1.service.signalr.net/client
    

    returns

    < HTTP/1.1 403 Forbidden
    
  • AG1http://<frontend-public-IP-address>/client을 통해 엔드포인트를 방문하면 'hub' 쿼리 매개 변수는 필수입니다.라는 오류 메시지와 함께 400이 반환됩니다. 이는 요청이 Application Gateway를 성공적으로 통과하여 SignalR Service에 도달했음을 의미합니다.

    curl -I http://<frontend-public-IP-address>/client
    

    returns

    < HTTP/1.1 400 Bad Request
    < ...
    <
    'hub' query parameter is required.
    

이제 채팅 애플리케이션을 로컬에서 다시 실행하면 Failed to connect to .... The server returned status code '403' when status code '101' was expected. 오류 메시지가 표시됩니다. 로컬 호스트 서버 연결이 SignalR Service에 더 오래 연결할 수 있도록 공용 액세스가 사용하지 않도록 설정되었기 때문입니다.

채팅 애플리케이션이 ASRS1과 통신할 수 있도록 ASRS1을 사용하여 동일한 VNet에 채팅 애플리케이션을 배포해 보겠습니다.

Azure에 채팅 애플리케이션 배포

  • Azure Portal에서 앱 서비스를 검색하고 만들기를 선택합니다.

  • 기본 사항 탭에서 다음 애플리케이션 게이트웨이 설정에 이러한 값을 사용합니다.

    • 구독리소스 그룹지역: SignalR Service에 대해 선택한 것과 동일합니다.
    • 이름: WA1
    • 게시: 코드
    • 런타임 스택: .NET 6(LTS)
    • 운영 체제: Linux
    • 지역: SignalR Service에 선택한 것과 동일한지 확인합니다.
    • 다음: Docker를 선택합니다.
  • 네트워킹 탭에서

    • 네트워크 삽입 사용: 켜기를 선택합니다.
    • Virtual Network: 이전에 만든 VN1을 선택합니다.
    • VNet 통합 사용: 켜기
    • 아웃바운드 서브넷: 새 서브넷 만들기
    • 검토 + 만들기를 선택합니다.

이제 Azure에 채팅 애플리케이션을 배포해 보겠습니다. 아래에서는 Azure CLI를 사용하여 웹앱을 배포합니다. 웹앱 게시 섹션에 따라 다른 배포 환경을 선택할 수도 있습니다.

samples/Chatroom 폴더에서 아래 명령을 실행합니다.

# Build and publish the assemblies to publish folder
dotnet publish --os linux -o publish
# zip the publish folder as app.zip
cd publish
zip -r app.zip .
# use az CLI to deploy app.zip to our webapp
az login
az account set -s <your-subscription-name-used-to-create-WA1>
az webapp deployment source config-zip -n WA1 -g <resource-group-of-WA1> --src app.zip

이제 웹앱이 배포되었습니다. WA1용 포털로 이동하여 다음 업데이트를 수행해 보겠습니다.

  • 구성 탭에서:

    • 새 애플리케이션 설정:

      속성
      WEBSITE_DNS_SERVER 168.63.129.16
      WEBSITE_VNET_ROUTE_ALL 1
    • 새 연결 문자열:

      속성 유형
      AzureSignalRConnectionString ClientEndpoint 값이 있는 복사된 연결 문자열 사용자 지정 선택

    Screenshot of configuring web app connection string.

  • TLS/SSL 설정 탭에서

    • HTTPS만: 끄기 데모를 단순화하기 위해 Application Gateway에 HTTP 프런트 엔드 프로토콜을 사용했습니다. 따라서 HTTP URL을 자동으로 HTTPs로 변경하지 않도록 이 옵션을 꺼야 합니다.
  • 개요 탭으로 이동하고 WA1의 URL을 확인합니다.

  • URL을 확인하고 체계 https를 http로 바꿉니다(예: http://wa1.azurewebsites.net). 브라우저에서 URL을 엽니다. 이제 채팅을 시작할 수 있습니다. F12 키를 사용하여 네트워크 추적을 열면 SignalR 연결이 AG1을 통해 설정된 것을 볼 수 있습니다.

    참고 항목

    경우에 따라 URL이 HTTPS로 자동으로 리디렉션되지 않도록 브라우저의 자동 https 리디렉션 및 브라우저 캐시를 사용하지 않도록 설정해야 합니다.

    Screenshot of running chat application in Azure with App Gateway and SignalR Service.

다음 단계

이제 SignalR Service를 사용하여 실시간 채팅 애플리케이션을 성공적으로 빌드하고, Application Gateway를 사용하여 애플리케이션을 보호하고 엔드투엔드 보안을 설정했습니다. SignalR Service에 대한 자세한 정보