Självstudie: Skapa en säker n-nivåapp i Azure App Service
Många program har mer än en enda komponent. Du kan till exempel ha en klientdel som är offentligt tillgänglig och ansluter till ett serverdels-API eller en webbapp som i sin tur ansluter till en databas, ett lagringskonto, ett nyckelvalv, en annan virtuell dator eller en kombination av dessa resurser. Den här arkitekturen utgör ett N-nivåprogram. Det är viktigt att program som detta utformas för att skydda serverdelsresurser i största möjliga utsträckning.
I den här självstudien får du lära dig hur du distribuerar ett säkert N-nivåprogram med en klientwebbapp som ansluter till en annan nätverksisolerad webbapp. All trafik isoleras i ditt virtuella Azure-nätverk med integrering av virtuella nätverk och privata slutpunkter. Mer omfattande vägledning som innehåller andra scenarier finns i:
Scenariots arkitektur
Följande diagram visar den arkitektur som du skapar under den här självstudien.
- Virtuellt nätverk Innehåller två undernät, ett är integrerat med klientdelswebbappen och det andra har en privat slutpunkt för serverdelswebbappen. Det virtuella nätverket blockerar all inkommande nätverkstrafik, förutom klientdelsappen som är integrerad med den.
- Klientwebbappen integrerad i det virtuella nätverket och tillgänglig från det offentliga Internet.
- ServerdelswebbappEn är endast tillgänglig via den privata slutpunkten i det virtuella nätverket.
- Privat slutpunkt Integreras med serverdelswebbappen och gör webbappen tillgänglig med en privat IP-adress.
- Privat DNS zon Gör att du kan matcha ett DNS-namn till den privata slutpunktens IP-adress.
Kommentar
Integrering av virtuella nätverk och privata slutpunkter är tillgängliga hela vägen ned till Basic-nivån i App Service. Den kostnadsfria nivån stöder inte dessa funktioner. Med den här arkitekturen:
- Offentlig trafik till serverdelsappen blockeras.
- Utgående trafik från App Service dirigeras till det virtuella nätverket och kan nå serverdelsappen.
- App Service kan utföra DNS-matchning till serverdelsappen.
Det här scenariot visar ett av de möjliga N-nivåscenarierna i App Service. Du kan använda de begrepp som beskrivs i den här självstudien för att skapa mer komplexa N-nivåappar.
Detta får du får lära dig:
- Skapa ett virtuellt nätverk och undernät för integrering av virtuella App Service-nätverk.
- Skapa privata DNS-zoner.
- Skapa privata slutpunkter.
- Konfigurera integrering av virtuella nätverk i App Service.
- Inaktivera grundläggande autentisering i App Service.
- Distribuera kontinuerligt till en låst serverdelswebbapp.
Förutsättningar
Självstudien använder två exempel Node.js appar som finns på GitHub. Om du inte redan har ett GitHub-konto skapar du ett konto kostnadsfritt.
Om du inte har en Azure-prenumeration skapar du ett kostnadsfritt Azure-konto innan du börjar.
För att slutföra den här kursen behöver du:
Använd Bash-miljön i Azure Cloud Shell. Mer information finns i Snabbstart för Bash i Azure Cloud Shell.
Om du föredrar att köra CLI-referenskommandon lokalt installerar du Azure CLI. Om du kör i Windows eller macOS kan du köra Azure CLI i en Docker-container. Mer information finns i Så här kör du Azure CLI i en Docker-container.
Om du använder en lokal installation loggar du in på Azure CLI med hjälp av kommandot az login. Slutför autentiseringsprocessen genom att följa stegen som visas i terminalen. Andra inloggningsalternativ finns i Logga in med Azure CLI.
När du uppmanas att installera Azure CLI-tillägget vid första användningen. Mer information om tillägg finns i Använda tillägg med Azure CLI.
Kör az version om du vill hitta versionen och de beroende bibliotek som är installerade. Om du vill uppgradera till den senaste versionen kör du az upgrade.
1. Skapa två instanser av en webbapp
Du behöver två instanser av en webbapp, en för klientdelen och en för serverdelen. Du måste använda minst Basic-nivån för att kunna använda integrering av virtuella nätverk och privata slutpunkter. Du konfigurerar integreringen av det virtuella nätverket och andra konfigurationer senare.
Skapa en resursgrupp för att hantera alla resurser som du skapar i den här självstudien.
# Save resource group name and region as variables for convenience groupName=myresourcegroup region=eastus az group create --name $groupName --location $region
Skapa en App Service-plan. Ersätt
<app-service-plan-name>
med ett unikt namn. Ändra parametern--sku
om du behöver använda en annan SKU. Se till att du inte använder den kostnadsfria nivån eftersom den SKU:n inte stöder de nätverksfunktioner som krävs.# Save App Service plan name as a variable for convenience aspName=<app-service-plan-name> az appservice plan create --name $aspName --resource-group $groupName --is-linux --location $region --sku P1V3
Skapa webbapparna. Ersätt
<frontend-app-name>
och<backend-app-name>
med två globalt unika namn (giltiga tecken ära-z
,0-9
och-
). I den här självstudien får du exempel på Node.js appar. Om du vill använda dina egna appar ändrar du parametern i enlighet med detta--runtime
. Köraz webapp list-runtimes
för listan över tillgängliga körningar.az webapp create --name <frontend-app-name> --resource-group $groupName --plan $aspName --runtime "NODE:18-lts" az webapp create --name <backend-app-name> --resource-group $groupName --plan $aspName --runtime "NODE:18-lts"
2. Skapa nätverksinfrastruktur
Du skapar följande nätverksresurser:
- Ett virtuellt nätverk.
- Ett undernät för integrering av det virtuella nätverket i App Service.
- Ett undernät för den privata slutpunkten.
- En privat DNS-zon.
- En privat slutpunkt.
Skapa ett virtuellt nätverk. Ersätt
<virtual-network-name>
med ett unikt namn.# 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
Skapa ett undernät för integreringen av det virtuella Nätverket i App Service.
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
För App Service rekommenderar vi att det virtuella nätverksintegreringsundernätet har ett CIDR-block
/26
på minst./24
är mer än tillräckligt.--delegations Microsoft.Web/serverfarms
anger att undernätet är delegerat för integrering av virtuella App Service-nätverk.Skapa ett annat undernät för de privata slutpunkterna.
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
För privata slutpunktsundernät måste du inaktivera nätverksprinciper för privata slutpunkter genom att ange
--disable-private-endpoint-network-policies
tilltrue
.Skapa den privata DNS-zonen.
az network private-dns zone create --resource-group $groupName --name privatelink.azurewebsites.net
Mer information om de här inställningarna finns i DNS-konfiguration för privata slutpunkter i Azure.
Kommentar
Om du skapar den privata slutpunkten med hjälp av portalen skapas en privat DNS-zon automatiskt åt dig och du behöver inte skapa den separat. För att få konsekvens med den här självstudien skapar du den privata DNS-zonen och den privata slutpunkten separat med hjälp av Azure CLI.
Länka den privata DNS-zonen till det virtuella nätverket.
az network private-dns link vnet create --resource-group $groupName --name myDnsLink --zone-name privatelink.azurewebsites.net --virtual-network $vnetName --registration-enabled False
Skapa en privat slutpunkt för serverdelswebbappen i det privata undernätet för det virtuella nätverket. Ersätt
<backend-app-name>
med namnet på serverdelswebbappen.# Get backend web app resource ID resourceId=$(az webapp show --resource-group $groupName --name <backend-app-name> --query id --output tsv) az network private-endpoint create --resource-group $groupName --name myPrivateEndpoint --location $region --connection-name myConnection --private-connection-resource-id $resourceId --group-id sites --vnet-name $vnetName --subnet private-endpoint-subnet
Länka den privata slutpunkten till den privata DNS-zonen med en DNS-zongrupp för den privata serverdelswebbappens privata slutpunkt. Den här DNS-zongruppen hjälper dig att automatiskt uppdatera den privata DNS-zonen när det finns en uppdatering av den privata slutpunkten.
az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name myPrivateEndpoint --name myZoneGroup --private-dns-zone privatelink.azurewebsites.net --zone-name privatelink.azurewebsites.net
När du skapar en privat slutpunkt för en App Service inaktiveras den offentliga åtkomsten implicit. Om du försöker komma åt serverdelswebbappen med dess standard-URL nekas din åtkomst. Från en webbläsare går du till för att
<backend-app-name>.azurewebsites.net
bekräfta det här beteendet.Mer information om åtkomstbegränsningar för App Service med privata slutpunkter finns i Åtkomstbegränsningar för Azure App Service.
3. Konfigurera integrering av virtuella nätverk i klientdelswebbappen
Aktivera integrering av virtuella nätverk i din app. Ersätt <frontend-app-name>
med klientdelswebbappens namn.
az webapp vnet-integration add --resource-group $groupName --name <frontend-app-name> --vnet $vnetName --subnet vnet-integration-subnet
Med integrering av virtuella nätverk kan utgående trafik flöda direkt till det virtuella nätverket. Som standard dirigeras endast lokal IP-trafik som definieras i RFC-1918 till det virtuella nätverket, vilket är vad du behöver för de privata slutpunkterna. Information om hur du dirigerar all trafik till det virtuella nätverket finns i Hantera routning för integrering av virtuella nätverk. Routning av all trafik kan också användas om du vill dirigera Internettrafik via ditt virtuella nätverk, till exempel via en NAT för virtuellt Azure-nätverk eller en Azure-brandvägg.
4. Aktivera distribution till serverdelswebbapp från Internet
Eftersom serverdelswebbappen inte är offentligt tillgänglig måste du låta verktyget för kontinuerlig distribution nå din app genom att göra SCM-webbplatsen offentligt tillgänglig. Själva huvudwebbappen kan fortsätta att neka all trafik.
Aktivera offentlig åtkomst för serverdelswebbappen.
az webapp update --resource-group $groupName --name <backend-app-name> --set publicNetworkAccess=Enabled
Ange den omatchade regelåtgärden för huvudwebbappen för att neka all trafik. Den här inställningen nekar offentlig åtkomst till huvudwebbappen även om den allmänna inställningen för appåtkomst är inställd på att tillåta offentlig åtkomst.
az resource update --resource-group $groupName --name <backend-app-name> --namespace Microsoft.Web --resource-type sites --set properties.siteConfig.ipSecurityRestrictionsDefaultAction=Deny
Ange den omatchade regelåtgärden för SCM-webbplatsen så att all trafik tillåts.
az resource update --resource-group $groupName --name <backend-app-name> --namespace Microsoft.Web --resource-type sites --set properties.siteConfig.scmIpSecurityRestrictionsDefaultAction=Allow
5. Lås FTP- och SCM-åtkomst
Nu när SCM-webbplatsen för serverdelen är offentligt tillgänglig måste du låsa den med bättre säkerhet.
Inaktivera FTP-åtkomst för både klient- och serverdelswebbappar. Ersätt
<frontend-app-name>
och<backend-app-name>
med dina appnamn.az resource update --resource-group $groupName --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<frontend-app-name> --set properties.allow=false az resource update --resource-group $groupName --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<backend-app-name> --set properties.allow=false
Inaktivera grundläggande autentiseringsåtkomst till WebDeploy-portarna och SCM/avancerade verktygswebbplatser för båda webbapparna. Ersätt
<frontend-app-name>
och<backend-app-name>
med dina appnamn.az resource update --resource-group $groupName --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<frontend-app-name> --set properties.allow=false az resource update --resource-group $groupName --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<backend-app-name> --set properties.allow=false
Om du inaktiverar grundläggande autentisering i App Service begränsas åtkomsten till FTP- och SCM-slutpunkterna till användare som backas upp av Microsoft Entra-ID, vilket ytterligare skyddar dina appar. Mer information om hur du inaktiverar grundläggande autentisering, inklusive hur du testar och övervakar inloggningar, finns i Inaktivera grundläggande autentisering i App Service.
6. Konfigurera kontinuerlig distribution med GitHub Actions
Gå till exempelappen Node.js serverdel. Den här appen är en enkel Hello World-app.
Välj knappen Förgrening längst upp till höger på GitHub-sidan.
Välj Ägare och lämna standardnamnet för lagringsplatsen.
Välj Skapa förgrening.
Upprepa samma process för Node.js klientdelsexempelapp. Den här appen är en grundläggande webbapp som har åtkomst till en fjärr-URL.
Skapa ett huvudnamn för tjänsten. Ersätt
<subscription-id>
,<frontend-app-name>
och<backend-app-name>
med dina värden.az ad sp create-for-rbac --name "myApp" --role contributor --scopes /subscriptions/<subscription-id>/resourceGroups/$groupName/providers/Microsoft.Web/sites/<frontend-app-name> /subscriptions/<subscription-id>/resourceGroups/$groupName/providers/Microsoft.Web/sites/<backend-app-name> --sdk-auth
Utdata är ett JSON-objekt med autentiseringsuppgifterna för rolltilldelning som ger åtkomst till dina App Service-appar. Kopiera det här JSON-objektet för nästa steg. Den innehåller din klienthemlighet, som bara visas just nu. Det är alltid en bra idé att bevilja minsta möjliga åtkomst. Omfånget i det här exemplet är begränsat till bara apparna, inte hela resursgruppen.
Om du vill lagra tjänstens huvudnamns autentiseringsuppgifter som GitHub-hemligheter går du till en av de förgrenade exempellagringsplatserna i GitHub och går till Inställningar> Säkerhetshemligheter>>och variabler Åtgärder.
Välj Ny lagringsplatshemlighet och skapa en hemlighet för vart och ett av följande värden. Värdena finns i json-utdata som du kopierade tidigare.
Name Värde AZURE_APP_ID <application/client-id>
AZURE_PASSWORD <client-secret>
AZURE_TENANT_ID <tenant-id>
AZURE_SUBSCRIPTION_ID <subscription-id>
Upprepa den här processen för den andra förgrenade exempellagringsplatsen.
Om du vill konfigurera kontinuerlig distribution med GitHub Actions loggar du in på Azure-portalen.
Gå till sidan Översikt för klientwebbappen.
I den vänstra rutan väljer du Distributionscenter. Välj sedan Inställningar.
I rutan Källa väljer du "GitHub" från CI/CD-alternativen.
Om du distribuerar från GitHub för första gången väljer du Auktorisera och följer auktoriseringsanvisningarna. Om du vill distribuera från en annan användares lagringsplats väljer du Ändra konto.
Om du använder den Node.js exempelapp som förgrenades som en del av förhandskraven använder du följande inställningar för Organisation, Lagringsplats och Gren.
Inställning Värde Organisation <your-GitHub-organization>
Lagringsplats nodejs-frontend Filial huvud- Välj Spara.
Upprepa samma steg för serverdelswebbappen. Inställningarna för Distributionscenter anges i följande tabell.
Inställning Värde Organisation <your-GitHub-organization>
Lagringsplats nodejs-backend Filial huvud-
7. Använda tjänstens huvudnamn för GitHub Actions-distribution
Konfigurationen av Distributionscenter har skapat en standardarbetsflödesfil i var och en av dina exempellagringsplatser, men den använder en publiceringsprofil som standard, som använder grundläggande autentisering. Eftersom du har inaktiverat grundläggande autentisering ser du att den automatiskt utlösta distributionen resulterar i ett fel om du markerar fliken Loggar i Distributionscenter. Du måste ändra arbetsflödesfilen så att tjänstens huvudnamn används för att autentisera med App Service. Exempelarbetsflöden finns i Lägga till arbetsflödesfilen till din GitHub-lagringsplats.
Öppna en av dina förgrenade GitHub-lagringsplatser och gå till
<repo-name>/.github/workflows/
katalogen.Välj den automatiskt genererade arbetsflödesfilen och välj sedan knappen "penna" längst upp till höger för att redigera filen. Ersätt innehållet med följande text, som förutsätter att du skapade GitHub-hemligheterna tidigare för dina autentiseringsuppgifter. Uppdatera platshållaren för
<web-app-name>
under avsnittet "env" och checka sedan in direkt till huvudgrenen. Den här incheckningen utlöser GitHub-åtgärden för att köras igen och distribuera din kod, den här gången med tjänstens huvudnamn för att autentisera.name: Build and deploy Node.js app to Azure Web App on: push: branches: - main workflow_dispatch: env: AZURE_WEBAPP_NAME: <web-app-name> # set this to your application's name NODE_VERSION: '18.x' # set this to the node version to use AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Node.js version uses: actions/setup-node@v1 with: node-version: ${{ env.NODE_VERSION }} - name: npm install, build run: | npm install npm run build --if-present - name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app path: . deploy: runs-on: ubuntu-latest needs: build environment: url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} steps: - name: Download artifact from build job uses: actions/download-artifact@v2 with: name: node-app - uses: azure/login@v1 with: creds: | { "clientId": "${{ secrets.AZURE_APP_ID }}", "clientSecret": "${{ secrets.AZURE_PASSWORD }}", "subscriptionId": "${{ secrets.AZURE_SUBSCRIPTION_ID }}", "tenantId": "${{ secrets.AZURE_TENANT_ID }}" } - name: 'Deploy to Azure Web App' id: deploy-to-webapp uses: azure/webapps-deploy@v2 with: app-name: ${{ env.AZURE_WEBAPP_NAME }} package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} - name: logout run: | az logout
Upprepa den här processen för arbetsflödesfilen i din andra förgrenade GitHub-lagringsplats.
De nya GitHub-incheckningarna utlöser en annan distribution för var och en av dina appar. Den här gången bör distributionen lyckas eftersom arbetsflödet använder tjänstens huvudnamn för att autentisera med apparnas SCM-webbplatser.
Detaljerad vägledning om hur du konfigurerar kontinuerlig distribution med leverantörer som GitHub Actions finns i Kontinuerlig distribution till Azure App Service.
8. Verifiera anslutningar och appåtkomst
Bläddra till klientwebbappen med dess URL:
https://<frontend-app-name>.azurewebsites.net
.I textrutan anger du URL:en för serverdelswebbappen:
https://<backend-app-name>.azurewebsites.net
. Om du konfigurerar anslutningarna korrekt bör du få meddelandet "Hello from the backend web app!", som är hela innehållet i serverdelswebbappen. All utgående trafik från klientwebbappen dirigeras via det virtuella nätverket. Klientdelswebbappen ansluter säkert till serverdelswebbappen via den privata slutpunkten. Om något är fel med dina anslutningar kraschar klientdelswebbappen.Prova att navigera direkt till serverdelswebbappen med dess URL:
https://<backend-app-name>.azurewebsites.net
. Du bör se meddelandetWeb App - Unavailable
. Om du kan nå appen kontrollerar du att du har konfigurerat den privata slutpunkten och att åtkomstbegränsningarna för din app är inställda på att neka all trafik för huvudwebbappen.För att ytterligare verifiera att klientdelswebbappen når serverdelswebbappen via privat länk, SSH till en av klientdelens instanser. Kör följande kommando för SSH, som upprättar en SSH-session till webbcontainern för din app och öppnar ett fjärrgränssnitt i webbläsaren.
az webapp ssh --resource-group $groupName --name <frontend-app-name>
När gränssnittet öppnas i webbläsaren kör du
nslookup
för att bekräfta att serverdelswebbappen nås med hjälp av den privata IP-adressen för serverdelswebbappen. Du kan också köracurl
för att verifiera webbplatsinnehållet igen. Ersätt<backend-app-name>
med namnet på serverdelswebbappen.nslookup <backend-app-name>.azurewebsites.net curl https://<backend-app-name>.azurewebsites.net
Bör
nslookup
matcha den privata IP-adressen för serverdelswebbappen. Den privata IP-adressen ska vara en adress från ditt virtuella nätverk. Bekräfta din privata IP-adress genom att gå till sidan Nätverk för serverdelswebbappen.Upprepa samma
nslookup
curl
och kommandon från en annan terminal (en som inte är en SSH-session på klientdelens instanser).nslookup
Returnerar den offentliga IP-adressen för serverdelswebbappen. Eftersom offentlig åtkomst till serverdelswebbappen är inaktiverad får du ett felmeddelande om nekad åtkomst om du försöker nå den offentliga IP-adressen. Det här felet innebär att den här webbplatsen inte är tillgänglig från det offentliga Internet, vilket är det avsedda beteendet. Matcharnslookup
inte den privata IP-adressen eftersom det bara kan matchas inifrån det virtuella nätverket via den privata DNS-zonen. Endast klientdelswebbappen finns i det virtuella nätverket. Om du försöker köracurl
på serverdelswebbappen från den externa terminalen innehållerWeb App - Unavailable
HTML-koden som returneras . Det här felet visar HTML för felsidan som du såg tidigare när du försökte navigera till serverdelswebbappen i webbläsaren.
9. Rensa resurser
I de föregående stegen skapade du Azure-resurser i en resursgrupp. Om du inte tror att du behöver dessa resurser i framtiden tar du bort resursgruppen genom att köra följande kommando i Cloud Shell.
az group delete --name myresourcegroup
Det kan ett par minuter att köra kommandot.
Vanliga frågor och svar
- Finns det något alternativ till distribution med hjälp av ett huvudnamn för tjänsten?
- Vad händer när jag konfigurerar GitHub Actions-distribution i App Service?
- Är det säkert att lämna serverdels-SCM offentligt tillgänglig?
- Finns det något sätt att distribuera utan att öppna serverdels-SCM-platsen alls?
- Hur distribuerar jag den här arkitekturen med ARM/Bicep?
Finns det något alternativ till distribution med hjälp av ett huvudnamn för tjänsten?
Eftersom du i den här självstudien har inaktiverat grundläggande autentisering kan du inte autentisera med SCM-webbplatsen i serverdelen med ett användarnamn och lösenord, och du kan inte heller använda en publiceringsprofil. I stället för tjänstens huvudnamn kan du också använda OpenID-Anslut.
Vad händer när jag konfigurerar GitHub Actions-distribution i App Service?
Azure genererar automatiskt en arbetsflödesfil på lagringsplatsen. Nya incheckningar i den valda lagringsplatsen och grenen distribueras nu kontinuerligt till din App Service-app. Du kan spåra incheckningar och distributioner på fliken Loggar .
En standardarbetsflödesfil som använder en publiceringsprofil för att autentisera till App Service läggs till på din GitHub-lagringsplats. Du kan visa den här filen genom att gå till <repo-name>/.github/workflows/
katalogen.
Är det säkert att lämna serverdels-SCM offentligt tillgänglig?
När du låser FTP- och SCM-åtkomsten säkerställer det att endast Microsoft Entra-säkerhetskopierade huvudkonton kan komma åt SCM-slutpunkten även om den är offentligt tillgänglig. Den här inställningen bör försäkra dig om att serverdelswebbappen fortfarande är säker.
Finns det något sätt att distribuera utan att öppna serverdels-SCM-platsen alls?
Om du är orolig för att aktivera offentlig åtkomst till SCM-platsen, eller om du är begränsad av principen, kan du överväga andra Distributionsalternativ för App Service som att köra från ett ZIP-paket.
Hur distribuerar jag den här arkitekturen med ARM/Bicep?
De resurser som du skapade i den här självstudien kan distribueras med hjälp av en ARM/Bicep-mall. Med den app som är ansluten till en Bicep-mall för serverdelswebbappen kan du skapa en säker N-nivåapplösning.
Information om hur du distribuerar ARM/Bicep-mallar finns i Distribuera resurser med Bicep och Azure CLI.