Azure 기능을 API 관리를 위해 Terraform으로 제한

최근에 Azure 함수에서 호스팅되는 API에서 할당량 사용을 강제하는 작업이 수행되었습니다.
API 관리는 로컬 할당량 관리를 지원하기 때문에 Azure 생태계의 자연스러운 선택입니다.
APIM 인스턴스는 클라이언트가 기능 응용 프로그램으로 전달을 요청하기 전에 할당량 요구 사항을 충족하도록 구성됩니다.
그러나 기능 응용 프로그램은 여전히 인터넷에 개방되어 있으며, HTTP 노드를 알고 있다면 누구나 요청할 수 있다.
우리는 어떻게 권한이 부여되지 않은 원본 접근 기능 응용 프로그램(또는 응용 프로그램 서비스 응용 프로그램)을 방지하고 이를 API 관리 실례에 제한합니까?
인프라, 즉 Terraform 코드로 어떻게 정의합니까?
몇 가지 연구와 실험을 통해 Azure Active Directory 인증을 사용하는 효과적인 솔루션을 얻었습니다.
인터넷에 Azure Portal을 통해 설정하는 방법에 대한 글이 있지만 Terraform 구현에 대한 조언을 찾을 수 없습니다.
만약 당신에게 유사한 임무가 있다면, 당신은 알고 싶을 것이다.
  • Azure Active Directory 관련 개념 소개
  • 높은 수준의 보호가 어떻게 작동하는지
  • Terraform
  • 을 사용하여 Azure 함수에서 Azure AD auth를 구현하는 방법
  • 대체 안전 메커니즘
  • 이 문장에서 우리는 이 모든 요점을 되돌아볼 것이다.
    보호되지 않은 스택에서 시작하여 Terraform을 사용하여 위쪽에 AAD auth를 추가합니다.
    다음은 코드를 포함하는 Github 저장소에 대한 링크입니다.

    선결 조건


    코드를 따르려면 다음이 필요합니다.
  • Azure 계정.당신은 start for free

  • Azure CLI 2.4+. CLIlogged in에 접속해야 합니다
  • .

  • Terraform 클라우드의 인프라 관리

  • Azure Functions Core Tools v3 함수 코드 실행 및 배치
  • 2021년 1월까지 Linux Customer Program 기반 기능 애플리케이션에서는 AAD 인증이 지원되지 않습니다.

    기본(비보호) 설정


    Azure에서는 최소한 다음과 같은 리소스가 필요합니다.
  • 리소스 그룹
  • 스토리지 계정
  • 어플리케이션 서비스 계획
  • 기능 어플리케이션
  • APIM 인스턴스
  • APIM API 및 FA에 대한 작업 매핑
  • Code for the unprotected setup in Github .
    관련 강좌: How to Deploy Azure Functions with Terraform.
    infra 배포:
    cd terraform
    terraform init
    terraform apply
    
    배포 코드:
    func azure functionapp publish adauthfaapim-dev-function-app
    
    Azure에 인프라와 코드를 배포한 후 APIM 통합이 정상적으로 작동하는지 확인합니다.
    $ curl -D - https://adauthfaapim-dev-api-management.azure-api.net/hello-world?name=apim
    HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: text/plain; charset=utf-8
    Date: Sun, 10 Jan 2021 18:56:01 GMT
    
    Hello, apim. This HTTP triggered function executed successfully.
    
    FA에 대한 인터넷 액세스 확인:
    $ curl -D - https://adauthfaapim-dev-function-app.azurewebsites.net/api/hello-world?name=func-app
    HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: text/plain; charset=utf-8
    Server: Kestrel
    Date: Sun, 10 Jan 2021 18:54:42 GMT
    
    Hello, func-app. This HTTP triggered function executed successfully.
    
    이것은 우리가 현재 설정한 설명도입니다.

    보호된 설정:개요


    수신자 (function app) 에서, 우리는 AAD 인증을 사용하여 전송 요청의 영패를 검증할 것입니다.
    이를 위해, 우리는 function 프로그램에 AAD 프로그램을 만들어야 한다. (다음은 이에 대해 상세하게 설명할 것이다.)
    요청단(APIM)에서, 우리는 게이트웨이에 AAD 접근 영패를 가져오라고 지시하고, 이를 프록시 클라이언트 요청과 함께 보낼 것입니다.
    이렇게 하려면 APIM에서 AAD 관리 ID를 활성화해야 합니다.
    이것은 최신 도표다.

    관련 AAD 개념 101


    현재 우리는 필요한 설정에 대해 높은 차원의 개술을 가지고 있으며, 관련된 AAD 개념을 더욱 자세하게 살펴보자.

    수신자


    FA에서 활성화되면 인증 모듈이 들어오는 요청을 차단하고 AAD에서 발급한 액세스 토큰을 검증한다.
    액세스 영패가 유효하면 기능 프로그램으로 전송할 것을 요청합니다.
    이를 위해서는 AAD와 통합해야 한다.AD에서 응용 프로그램의 ID를 나타내는 객체를 만들어야 합니다. 이를 (AAD) 응용 프로그램 객체라고 합니다.

    응용 프로그램 개체


    응용 프로그램 대상(AO)이나 간단한 응용 프로그램은identity platform에서 응용 프로그램/코드의 정의입니다.
    일반적으로 이것은 또 다른 중요한 개념인 서비스 주체와 동시에 나타난다. 서비스 주체는 특정한 AAD 실례(세입자) 중의 응용 프로그램 실례이다.한 AO에는 한 개 이상의 SP가 있을 수 있으며, AO를 설치한 AD 임차인마다 한 개의 SP가 있을 수 있다.SP는 특정 AAD에서 해당 AO가 받을 권한을 정의합니다.
    우리의 예시에서 기능 응용 프로그램의 표지와 관련된 권한이 없습니다.
    그것의 유일한 임무는 두 가지를 확보함으로써 전송된 영패를 검증하는 것이다.
    a) 기호화폐와 기능 응용 프로그램 및 응용 프로그램이 같은 AAD에서 발행
    b) 토큰은 해당 기능 애플리케이션을 위해 특별히 발행됨
    응용 프로그램 객체에는 AAD 응용 프로그램의 글로벌 고유 ID인 응용 프로그램 ID(appId, 클라이언트 ID라고도 함)가 있습니다.

    요청자


    APIM은 AAD에서 액세스 토큰을 가져와 요청과 함께 기능 응용 프로그램에 보내야 합니다.
    이렇게 하려면 APIM이 AAD에 인증해야 합니다.따라서 AAD에 해당하는 신분이 있어야 한다.
    APIM이 AAD를 통해 인증하는 수동(비최적) 방법:
  • APIM의 응용 프로그램 객체와 해당하는 서비스 주체를 작성합니다.
  • SP에 대한 비밀 또는 인증서를 생성합니다.
  • APIM 인스턴스가 FA에 요청을 전달할 때마다 AAD에서 액세스 토큰을 받습니다.
  • 이 토큰을 받기 위해 APIM은 AAD에 인증된 요청을 보냅니다.
  • 토큰 요청 매개 변수는 다음과 같습니다.
  • AAD 세입자 ID
  • 시청자 ID(FA와 연결된 어플리케이션 객체의 클라이언트 ID)
  • 클라이언트 ID(APIM과 연결된 응용 프로그램 객체의 클라이언트 ID)
  • 고객 기밀 또는 인증서(APIM 관련 서비스 담당자의 자격 증명)
  • 여기서 몇 가지 중요한 질문을 드리겠습니다.
  • APIM에 AAD 고객 기밀을 안전하게 저장하는 방법은 무엇입니까?
  • 만기가 다가오면 나는 어떻게 비밀을 번갈아 가죠?
  • 비밀 기한이 지나면 반드시 번갈아야 한다는 것을 어떻게 기억할 수 있습니까?
  • 더 좋은 해결 방안이 있습니까?네, 관리 신분이라고 합니다.

    ID 관리


    관리형 ID(MI)를 만들 때마다 SP가 AAD에서 응용 프로그램의 ID임을 이미 알고 있는 서비스 주체가 만들어집니다.
    MI의 장점은 기밀이나 인증서를 걱정할 필요가 없고 플랫폼에서 자동으로 관리된다는 것입니다.
    AAD를 통한 APIM 인증 관리(최적) 방법:
  • APIM에서 관리형 ID를 활성화합니다.
  • APIM 인스턴스가 FA에 요청을 전달할 때마다 AAD에서 액세스 토큰을 받습니다.
  • 이 토큰을 받기 위해 APIM은 AAD에 인증된 요청을 보냅니다.
  • 토큰 요청 매개 변수는 다음과 같습니다.
  • 시청자 ID(FA와 연결된 어플리케이션 객체의 클라이언트 ID)
  • 좋은 점 보이시나요?우리는 더 이상 AAD의 비밀을 소문내지 않기 때문에 AAD의 비밀을 망칠 수 없다.
    APIM에서 AAD 토큰은 인바운드 규칙의 특수 정책을 통해 획득됩니다.
    업데이트된 구성도입니다.

    지형이 실현되다


    Azure AD Provider는 Terraform의 Resource Manager Provider와 달리 별도로 설정되어야 합니다.
    terraform {
      required_providers {
        ...
    
        azuread = {
          source = "hashicorp/azuread"
          version = "~>1.1.1"
        }
      }
    }
    
    provider "azuread" {
    }
    
    함수 응용 프로그램의 응용 프로그램 대상을 만듭니다.
    resource "azuread_application" "ad_application_function_app" {
        name                     = "${var.project}-${var.environment}-ad-application-function-app"
        type                     = "webapp/api"
        prevent_duplicate_names  = true
    }
    
    기능 응용 프로그램에서 AAD 인증을 활성화합니다.
    auth_settings {
      enabled = true
      issuer = "https://login.microsoftonline.com/${data.azurerm_client_config.current.tenant_id}"
      default_provider = "AzureActiveDirectory"
      active_directory {
        client_id = azuread_application.ad_application_function_app.application_id
      }
      unauthenticated_client_action = "RedirectToLoginPage"
    }
    
    issuer 매개 변수에 대한 빠른 설명.기능 응용 검증 모듈은 전송된 영패를 검증하기 위해 그것을 사용할 것이다.
    더 구체적으로 말하면 영패(JWT)의 iss 성명은 반드시 일치해야 한다.
    카드 발급 기구 URL이 대상 AAD 프로그램 (예시에서 function app) 의 설정과 일치하는지 확인해야 합니다.저는 앞으로의 댓글에서 저의 관찰 결과를 공유할 수 있을 것 같습니다. 이런 관찰 결과는 저에게 위의 발행인의 가치를 얻게 했습니다.
    이러한 변경 사항을 배치하고 예상한 결과를 확보합시다.
    함수 응용 프로그램에 대한 요청은 인증을 거쳐야 하기 때문에 함수 응용 프로그램을 직접 조회하든지 APIM을 통해 함수 응용 프로그램을 조회하든지 401개의 오류를 받을 수 있습니다.
    $ curl -D - https://adauthfaapim-dev-function-app.azurewebsites.net/api/hello-world?name=func-app
    HTTP/1.1 401 Unauthorized
    Server: Kestrel
    WWW-Authenticate: Bearer realm="adauthfaapim-dev-function-app.azurewebsites.net" authorization_uri="https://login.microsoftonline.com/bb19fab2-.../oauth2/v2.0/authorize" resource_id="67ff3941-3536-4feb-b69d-e179a06ce195"
    Date: Sun, 10 Jan 2021 18:57:07 GMT
    Content-Length: 0
    
    $ curl -D - https://adauthfaapim-dev-api-management.azure-api.net/hello-world?name=apim
    HTTP/1.1 401 Unauthorized
    Content-Length: 0
    WWW-Authenticate: Bearer realm="adauthfaapim-dev-function-app.azurewebsites.net" authorization_uri="https://login.microsoftonline.com/bb19fab2-.../oauth2/v2.0/authorize" resource_id="67ff3941-3536-4feb-b69d-e179a06ce195"
    Date: Sun, 10 Jan 2021 18:57:43 GMT
    
    그것은 실패했다. 이것은 예상한 것이다.
    그런 다음 APIM 인스턴스에서 관리된 ID를 활성화합니다.
    resource "azurerm_api_management" "api_management" {
      ...
    
      identity {
        type = "SystemAssigned"
      }
    }
    
    APIM 인스턴스에 인바운드 정책을 추가하여 기능 응용 프로그램에 대한 AAD 액세스 토큰을 가져오도록 지시합니다.
    resource "azurerm_api_management_api_policy" "api_management_api_policy_api_public" {
      api_name            = azurerm_api_management_api.api_management_api_public.name
      api_management_name = azurerm_api_management.api_management.name
      resource_group_name = azurerm_resource_group.resource_group.name
    
      xml_content = <<XML
    <policies>
      <inbound>
        <base />
        <authentication-managed-identity resource="${azuread_application.ad_application_function_app.application_id}" ignore-error="false" />
      </inbound>
    </policies>
    XML
    }
    
    마지막 변경 사항을 배치하고 FA에 직접 액세스할 수 없음을 확인하지만, APIM은 FA에 액세스할 수 있습니다.
    $ curl -D - https://adauthfaapim-dev-function-app.azurewebsites.net/api/hello-world?name=func-app
    HTTP/1.1 401 Unauthorized
    Server: Kestrel
    WWW-Authenticate: Bearer realm="adauthfaapim-dev-function-app.azurewebsites.net" authorization_uri="https://login.windows.net/common/oauth2/authorize" resource_id="67ff3941-3536-4feb-b69d-e179a06ce195"
    Date: Sun, 10 Jan 2021 19:06:23 GMT
    Content-Length: 0
    
    curl -D - https://adauthfaapim-dev-api-management.azure-api.net/hello-world?name=apim
    HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: text/plain; charset=utf-8
    Date: Sun, 10 Jan 2021 19:05:48 GMT
    
    Hello, apim. This HTTP triggered function executed successfully.
    

    대체 보안 메커니즘


    AAD 인증을 사용하는 것은 APIM 인스턴스 뒤에 있는 백엔드 API를 보호하는 유일한 방법이 아닙니다.추가 옵션은 다음과 같습니다.
  • 기능 어플리케이션
  • 의 APIM 공용 IP 화이트리스트
  • VNET에 FA와 APIM을 두고 APIM 사유IP
  • 를 화이트리스트에 올렸다.
  • APIM이 요청에 FA 액세스 키 보내기
  • mTLS 인증(고객 인증서)
  • 이러한 방법과 그 장단점에 대한 상세한 개요는 Vincent Philippe Lauzon의 비교API Management exclusive access to Azure Function를 참조하십시오.

    ...


    잘했어.Azure 기능을 따뜻하고 안전하게 유지합니다.
    당신이 가장 좋아하는 기초 구조를 코드 도구로 사용하여 변경 사항을 일치하게 응용하고 추적할 수 있습니다.
    최종 응용 프로그램 코드 here 를 찾을 수 있습니다.

    좋은 웹페이지 즐겨찾기