Esercitazione: Isolare le comunicazioni back-end in Servizio app di Azure con l'integrazione di Rete virtuale

In questo articolo verrà configurata un'app servizio app con comunicazioni sicure e isolate dalla rete ai servizi back-end. Lo scenario di esempio usato è illustrato in Esercitazione: Proteggere la connessione a Servizi cognitivi da servizio app usando Key Vault. Al termine, è disponibile un'app servizio app che accede sia ai servizi di Key Vault che ai servizi di intelligenza artificiale di Azure tramite una rete virtuale di Azure e nessun altro traffico può accedere a tali risorse back-end. Tutto il traffico verrà isolato all'interno della rete virtuale usando l'integrazione della rete virtuale e gli endpoint privati.

Come servizio multi-tenant, il traffico di rete in uscita dall'app servizio app ad altri servizi di Azure condivide lo stesso ambiente con altre app o anche altre sottoscrizioni. Anche se il traffico stesso può essere crittografato, alcuni scenari possono richiedere un livello di sicurezza aggiuntivo isolando la comunicazione back-end da altri traffico di rete. Questi scenari sono in genere accessibili alle grandi aziende con un elevato livello di esperienza, ma servizio app lo mette in contatto con l'integrazione della rete virtuale.

architettura dello scenario

Con questa architettura:

  • Il traffico pubblico verso i servizi back-end è bloccato.
  • Il traffico in uscita da servizio app viene instradato alla rete virtuale e può raggiungere i servizi back-end.
  • servizio app è in grado di eseguire la risoluzione DNS ai servizi back-end tramite le zone DNS private.

Contenuto dell'esercitazione:

  • Creare una rete virtuale e subnet per l'integrazione della rete virtuale servizio app
  • Creare zone DNS private
  • Creare endpoint privati
  • Configurare l'integrazione della rete virtuale in servizio app

Prerequisiti

L'esercitazione presuppone che sia stata seguita l'esercitazione Esercitazione: Proteggere la connessione a Servizi cognitivi da servizio app usando Key Vault e aver creato l'app di rilevamento della lingua.

L'esercitazione continua a usare le variabili di ambiente seguenti dell'esercitazione precedente. Assicurarsi di impostarli correttamente.

    groupName=myKVResourceGroup
    region=westeurope
    csResourceName=<cs-resource-name>
    appName=<app-name>
    vaultName=<vault-name>

Creare la rete virtuale e le subnet

  1. Creare una rete virtuale. Sostituire <virtual-network-name> con un nome univoco.

    # Save vnet name as variable for convenience
    vnetName=<virtual-network-name>
    
    az network vnet create --resource-group $groupName --location $region --name $vnetName --address-prefixes 10.0.0.0/16
    
  2. Creare una subnet per l'integrazione della rete virtuale servizio app.

    az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name vnet-integration-subnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Web/serverfarms --disable-private-endpoint-network-policies false
    

    Per servizio app, è consigliabile che la subnet di integrazione della rete virtuale abbia almeno un blocco /26 CIDR.Vedere Requisiti della subnet di integrazione della rete virtuale. /24 è più che sufficiente. --delegations Microsoft.Web/serverfarmsspecifica che la subnet è delegata per servizio app'integrazione della rete virtuale.

  3. Creare un'altra subnet per gli endpoint privati.

    az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name private-endpoint-subnet --address-prefixes 10.0.1.0/24 --disable-private-endpoint-network-policies true
    

    Per le subnet degli endpoint privati, è necessario disabilitare i criteri di rete degli endpoint privati.

Creare zone DNS private

Poiché le risorse Key Vault e dei servizi di intelligenza artificiale di Azure si troveranno dietro endpoint privati, è necessario definire le zone DNS private per tali endpoint. Queste zone vengono usate per ospitare i record DNS per gli endpoint privati e consentire ai client di trovare i servizi back-end in base al nome.

  1. Creare due zone DNS private, una per la risorsa dei servizi di intelligenza artificiale di Azure e una per l'insieme di credenziali delle chiavi.

    az network private-dns zone create --resource-group $groupName --name privatelink.cognitiveservices.azure.com
    az network private-dns zone create --resource-group $groupName --name privatelink.vaultcore.azure.net
    

    Per altre informazioni su queste impostazioni, vedere Configurazione DNS dell'endpoint privato di Azure

  2. Collegare le zone DNS private alla rete virtuale.

    az network private-dns link vnet create --resource-group $groupName --name cognitiveservices-zonelink --zone-name privatelink.cognitiveservices.azure.com --virtual-network $vnetName --registration-enabled False
    az network private-dns link vnet create --resource-group $groupName --name vaultcore-zonelink --zone-name privatelink.vaultcore.azure.net --virtual-network $vnetName --registration-enabled False
    

Creare endpoint privati

  1. Nella subnet dell'endpoint privato della rete virtuale creare un endpoint privato per il servizio cognitivo.

    # Get Cognitive Services resource ID
    csResourceId=$(az cognitiveservices account show --resource-group $groupName --name $csResourceName --query id --output tsv)
    
    az network private-endpoint create --resource-group $groupName --name securecstext-pe --location $region --connection-name securecstext-pc --private-connection-resource-id $csResourceId --group-id account --vnet-name $vnetName --subnet private-endpoint-subnet
    
  2. Creare un gruppo di zone DNS per l'endpoint privato dei servizi di intelligenza artificiale di Azure. Il gruppo di zone DNS è un collegamento tra la zona DNS privata e l'endpoint privato. Questo collegamento consente di aggiornare automaticamente la zona DNS privata quando è presente un aggiornamento all'endpoint privato.

    az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name securecstext-pe --name securecstext-zg --private-dns-zone privatelink.cognitiveservices.azure.com --zone-name privatelink.cognitiveservices.azure.com
    
  3. Bloccare il traffico pubblico verso la risorsa dei servizi di intelligenza artificiale di Azure.

    az rest --uri $csResourceId?api-version=2021-04-30 --method PATCH --body '{"properties":{"publicNetworkAccess":"Disabled"}}' --headers 'Content-Type=application/json'
    
    # Repeat following command until output is "Succeeded"
    az cognitiveservices account show --resource-group $groupName --name $csResourceName --query properties.provisioningState
    

    Nota

    Assicurarsi che lo stato di provisioning della modifica sia "Succeeded". È quindi possibile osservare la modifica del comportamento nell'app di esempio. È comunque possibile caricare l'app, ma se si prova a fare clic sul pulsante Rileva , viene visualizzato un HTTP 500 errore. L'app ha perso la connettività alla risorsa dei servizi di intelligenza artificiale di Azure tramite la rete condivisa.

  4. Ripetere i passaggi precedenti per l'insieme di credenziali delle chiavi.

    # Create private endpoint for key vault
    vaultResourceId=$(az keyvault show --name $vaultName --query id --output tsv)
    az network private-endpoint create --resource-group $groupName --name securekeyvault-pe --location $region --connection-name securekeyvault-pc --private-connection-resource-id $vaultResourceId --group-id vault --vnet-name $vnetName --subnet private-endpoint-subnet
    # Create DNS zone group for the endpoint
    az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name securekeyvault-pe --name securekeyvault-zg --private-dns-zone privatelink.vaultcore.azure.net --zone-name privatelink.vaultcore.azure.net
    # Block public traffic to key vault
    az keyvault update --name $vaultName --default-action Deny
    
  5. Forzare un refetch immediato dei riferimenti all'insieme di credenziali delle chiavi nell'app reimpostando le impostazioni dell'app .Per altre informazioni, vedere Rotazione.

    az webapp config appsettings set --resource-group $groupName --name $appName --settings CS_ACCOUNT_NAME="@Microsoft.KeyVault(SecretUri=$csResourceKVUri)" CS_ACCOUNT_KEY="@Microsoft.KeyVault(SecretUri=$csKeyKVUri)"
    

    Nota

    Anche in questo caso, è possibile osservare la modifica del comportamento nell'app di esempio. Non è più possibile caricare l'app perché non può più accedere ai riferimenti all'insieme di credenziali delle chiavi. L'app ha perso la connettività all'insieme di credenziali delle chiavi tramite la rete condivisa.

I due endpoint privati sono accessibili solo ai client all'interno della rete virtuale creata. Non è nemmeno possibile accedere ai segreti nell'insieme di credenziali delle chiavi tramite la pagina Segreti nella portale di Azure, perché il portale li accede tramite Internet pubblico (vedere Gestire le risorse bloccate).

Configurare l'integrazione della rete virtuale nell'app

  1. Ridimensionare l'app fino a un piano tariffario supportato (vedere Integrare l'app con una rete virtuale di Azure).

    az appservice plan update --name $appName --resource-group $groupName --sku S1
    
  2. Non correlato allo scenario, ma anche importante, applicare HTTPS per le richieste in ingresso.

    az webapp update --resource-group $groupName --name $appName --https-only
    
  3. Abilitare l'integrazione della rete virtuale nell'app.

    az webapp vnet-integration add --resource-group $groupName --name $appName --vnet $vnetName --subnet vnet-integration-subnet
    

    L'integrazione della rete virtuale consente al traffico in uscita di fluire direttamente nella rete virtuale. Per impostazione predefinita, solo il traffico IP locale definito in RFC-1918 viene instradato alla rete virtuale, ovvero ciò che è necessario per gli endpoint privati. Per instradare tutto il traffico alla rete virtuale, vedere Gestire il routing di integrazione della rete virtuale. Il routing di tutto il traffico può essere usato anche se si vuole instradare il traffico Internet attraverso la rete virtuale, ad esempio tramite un Rete virtuale NAT di Azure o un Firewall di Azure.

  4. Nel browser passare di nuovo a <app-name>.azurewebsites.net e attendere che l'integrazione venga applicata. Se viene visualizzato un errore HTTP 500, attendere alcuni minuti e riprovare. Se è possibile caricare la pagina e ottenere i risultati del rilevamento, ci si connette all'endpoint di Servizi di intelligenza artificiale di Azure con riferimenti all'insieme di credenziali delle chiavi.

    Nota

    Se si verificano errori HTTP 500 dopo molto tempo, può essere utile forzare nuovamente un refetch dei riferimenti all'insieme di credenziali delle chiavi, come illustrato di seguito:

    az webapp config appsettings set --resource-group $groupName --name $appName --settings CS_ACCOUNT_NAME="@Microsoft.KeyVault(SecretUri=$csResourceKVUri)" CS_ACCOUNT_KEY="@Microsoft.KeyVault(SecretUri=$csKeyKVUri)"
    

Gestire le risorse bloccate

A seconda degli scenari, potrebbe non essere possibile gestire le risorse protette dall'endpoint privato tramite la portale di Azure, l'interfaccia della riga di comando di Azure o Azure PowerShell (ad esempio, Key Vault). Questi strumenti effettuano tutte chiamate API REST per accedere alle risorse tramite Internet pubblico e vengono bloccati dalla configurazione. Ecco alcune opzioni per accedere alle risorse bloccate:

  • Per Key Vault, aggiungere l'indirizzo IP pubblico del computer locale per visualizzare o aggiornare i segreti protetti dall'endpoint privato.
  • Se la rete locale viene estesa alla rete virtuale di Azure tramite un gateway VPN o ExpressRoute, è possibile gestire le risorse protette dall'endpoint privato direttamente dalla rete locale.
  • Gestire le risorse protette dall'endpoint privato da un jump server nella rete virtuale.
  • Distribuire Cloud Shell nella rete virtuale.

Pulire le risorse

Nei passaggi precedenti sono state create risorse di Azure in un gruppo di risorse. Se si ritiene che queste risorse non saranno necessarie in futuro, eliminare il gruppo di risorse eseguendo questo comando in Cloud Shell:

az group delete --name $groupName

L'esecuzione del comando può richiedere un minuto.

Passaggi successivi