You can securely connect to your App Service from the internet using the Application Gateway when you integrate your Application Gateway with App Service behind Private Endpoint.
This article will illustrate and provide detailed steps about how to setup an Application Gateway with an App Service behind a Private Endpoint. We will use a test domain and self-signed certificate for the Application Gateway to simulate a live environment.
In the diagram below, your client will connect to the application gateway through the public Ip address. The application gateway will connect privately and securely to your App Service application using a private endpoint which is a network interface that uses a private IP address from your private network.
From Azure portal, click "Resource groups" icon, and then create a resource group.
Enter Resource group and create a Virtual network
Specify the VNET name.
You can keep the default value and confirm the IP addresses space.
Select Review + create to create the VNET, the VNET will be used for the Application Gateway and the Private Endpoint used to connect to the Azure App Service.
Navigate to the resource group created in the previous step.
Create resource and select "Web App"
Set the app service name and other parameters, select any Runtime stack. You will use the default page for testing purposes.
Keep other settings as default click "Review + create" button to create the App Service
View the default page. The default page is publicly accessible when the Azure App Service is created successfully.
Navigate to the App Service on Azure portal, visit "Networking" --> "Access restriction"
Un-check "Allow public access" and "Save" the changes in App Access to block all incoming traffic except traffic that comes from private endpoints.
Click "Networking" -> "Private Endpoints" and click "Add" -> "Express" button.
Fill the Private Endpoint name and select the Virtual Network and Subnet previously created. You will need to check "Yes" for Integrated with private DNS zone to resolve your app service FQDN to a private IP address.
And now when you visit the web site to test public access to the site, you will receive 403 error.
*If public network access is restricted through the default (public) endpoint, an Error 403-Forbidden will be shown when you visit the default page.
Navigate to the VNet you created in the earlier steps and create a new subnet for Application Gateway
Navigate to the resource group and click "New Resource" and select "Application Gateway"
On basic page, select the VNET/Subnet you created in the earlier steps.
On Frontends page, create a new Public IP for Application Gateway to allow internet resources to communicate inbound to the Application Gateway.
On backends page, create a new backend pool and select the App Service we created before.
On Configuration Page, add a "Routing Rule", fill the Listener as below
For backend targets, select the Backend Pool we created before and create new Backend Settings
On backend setting, select HTTPS and override the host name with App Service default FQDN
Click "Review + Create" button and create Application Gateway
Once Application Gateway created successfully.
Check the public IP of Application Gateway and visit the IP address
You should see the App Service page displayed successfully
Now you will create a self-signed certificate for Application Gateway and use "www.contoso.com " as an example.
You will use OpenSSL to sign certificate. Confirm OpenSSL from https://www.openssl.org/ is installed before running below scripts.
[ req ] distinguished_name = req_distinguished_name policy = policy_match x509_extensions = v3_ca # For the CA policy [ policy_match ] countryName = optional stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = IN countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) ## Print this message stateOrProvinceName_default = KARNATAKA ## This is the default value localityName = Locality Name (eg, city) ## Print this message localityName_default = BANGALORE ## This is the default value 0.organizationName = Organization Name (eg, company) ## Print this message 0.organizationName_default = GoLinuxCloud ## This is the default value organizationalUnitName = Organizational Unit Name (eg, section) ## Print this message organizationalUnitName_default = Admin ## This is the default value commonName = Common Name (eg, your name or your server hostname) ## Print this message commonName_max = 64 emailAddress = Email Address ## Print this message emailAddress_max = 64 [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical,CA:true nsComment = "OpenSSL Generated Certificate" [ user_crt ] nsCertType = client, server, email nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer [ v3_inter_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign extendedKeyUsage = critical,serverAuth,clientAuth,codeSigning,timeStamping,emailProtection,OCSPSigning,ipsecIKE,msCodeInd,msCodeCom,msCTLSign,msEFS [ v3_client ] authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alternate_names [ alternate_names ] DNS.1 = www.contoso.com
Write-Host "SelfSign Test" -ForegroundColor:Green $domainname = "www.contoso.com" $password = "Start123" rm *.csr , *.crt, *.key, *.pfx # ca.key , ca.csr , ca.crt # inter.key , inter.csr, inter.crt Write-Host "Create RootCA" -ForegroundColor:Green openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 3650 -subj='/O=MS/OU=CSS/CN=SelfSign Root CA' -config openssl.cnf -key ca.key -out ca.crt openssl x509 -text -noout -in ca.crt Write-Host "Create Inter Cert" -ForegroundColor:Green openssl genrsa -out inter.key 4096 openssl req -new -sha256 -key inter.key -subj='/O=MS/OU=CSS/CN=SelfSign Intermediate CA' -out inter.csr -config openssl.cnf openssl x509 -req -sha256 -in inter.csr -out inter.crt -CA ca.crt -CAkey ca.key -CAcreateserial -extfile openssl.cnf -extensions v3_inter_ca -days 3650 openssl x509 -text -noout -in inter.crt openssl verify -CAfile ca.crt inter.crt Write-Host "Create Client Cert" -ForegroundColor:Green openssl genrsa -out client.key 4096 openssl req -new -sha256 -key client.key -subj="/O=MS/OU=CSS/CN=$domainname" -out client.csr -config openssl.cnf openssl x509 -req -sha256 -in client.csr -out client.crt -CA inter.crt -CAkey inter.key -CAcreateserial -extfile openssl.cnf -extensions v3_client -days 3650 openssl x509 -text -noout -in client.crt openssl verify -CAfile ca.crt -untrusted inter.crt client.crt Write-Host "Put CA and Inter Cert together" $caContent = Get-Content ca.crt $interContent = Get-Content inter.crt Set-Content ".\cafile.crt" $caContent Add-Content ".\cafile.crt" $interContent Write-Host "Package PFX" openssl pkcs12 -export -passout "pass:$password" -out client.pfx -inkey client.key -in client.crt -CAfile cafile.crt
Run the powershell script, it will generate the CA cert, Intermediate Cert, and the client cert for custom domain
Double click ca.crt and click "Install Certificate", click "Current User" and click "Next" button
Then Browse and select "Trusted Root Certificate Authorities", click "Next" install the certificate
Follow the same steps and install inter.crt to "Intermediate Certification Authorities" store
Now you client has trusted the root ca and intermediate ca, and will trust the self-signed certificate as well.
# Copyright (c) 1993-2009 Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. # # This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # # 184.108.40.206 rhino.acme.com # source server # 220.127.116.11 x.acme.com # x client host # localhost name resolution is handled within DNS itself. # 127.0.0.1 localhost # ::1 localhost x.x.x.x www.contoso.com
Create a HTTPS Listener for Appliation Gateway
Update the Routing Rule and select the httpsListner
You should able to visit https://www.consoto.com successfully, and certificate is also working.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.