Azure App Service, Private Endpoint, and Application Gateway/WAF

In this post, I will share how to configure an Azure Web App (or App Service) with Private Endpoint, and securely share that HTTP/S service using the Azure Application Gateway, with the optional Web Application Firewall (WAF) feature. Whew! That’s lots of feature names!


Azure Application (App) Services or Web Apps allows you to create and host a web site or web application in Azure without (directly) dealing with virtual machines. This platform service makes HTTP/S services easy. By default, App Services are shared behind a public/ & shared frontend (actually, load-balanced frontends) with public IP addresses.

Earlier this year, Microsoft released Private Link, a service that enables an Azure platform resource (or service shared using a Standard Tier Load Balancer) to be connected to a virtual network subnet. The resource is referred to as the linked resource. The linked resource connects to the subnet using a Private Endpoint. There is a Private Endpoint resource and a special NIC; it’s this NIC that shares the resource with a private IP address, obtained from the address space of the subnet. You can then connect to the linked resource using the Private Endpoint IPv4 address. Note that the Private Endpoint can connect to many different “subresources” or services (referred to as serviceGroup in ARM) that the linked resource can offer. For example, a storage account has serviceGroups such as file, blob, and web.

Notes: Private Link is generally available. Private Endpoint for App Services is still in preview. App Services Premium V2 is required for Private Endpoint.

The Application Gateway allows you to share/load balance a HTTP/S service at the application layer with external (virtual network, WAN, Internet) clients. This reverse proxy also offers an optional Web Application Firewall (WAF), at extra cost, to protect the HTTP/S service with the OWASP rule set and bot protection. With the Standard Tier of DDoS protection enabled on the Application Gateway virtual network, the WAF extends this protection to Layer-7.

Design Goal

The goal of this design is to ensure that all HTTP/S (HTTPS in this example) traffic to the Web App must:

  • Go through the WAF.
  • Reverse proxy to the App Service via the Private Endpoint private IPv4 address only.

The design will result in:

  • Layer-4 protection by an NSG associated with the WAF subnet. NSG Traffic Analytics will send the data to Log Analytics (and optionally Azure Sentinel for SIEM) for logging, classification, and reporting.
  • Layer-7 protection by the WAF. If the Standard Tier of DD0S protection is enabled, then the protection will be at Layer-4 (Application Gateway Public IP Address) and Layer-7 (WAF). Logging data will be sent to Log Analytics (and optionally Azure Sentinel for SIEM) for logging and reporting.
  • Connections directly to the web app will fail with a “HTTP Error 403 – Forbidden” error.

Note: If you want to completely prevent TCP connections to the web app then you need to consider App Service Environment/Isolated Tier or a different Azure platform/IaaS solution.


Here is the design – you will want to see the original image:

There are a number of elements to the design:

Private DNS Zone

You must be able to resolve the FQDNs of your services using the per-resource type domain names. App Services use a private DNS zone called There are hacks to get this to work. The best solution is to create a central Azure Private DNS Zone called

If you have DNS servers configured on your virtual network(s), associate the Private DNS Zone with your DNS servers’ virtual network(s). Create a conditional forwarder on the DNS servers to forward all requests to to ( This will result in:

  1. A network client sending a DNS resolution request to your DNS servers for *
  2. The DNS servers forwarding the requests for * to
  3. The Azure Private DNS Zone will receive the forwarded request and respond to the DNS servers.
  4. The DNS servers will respond to the client with the answer.

App Service

As stated before the App Service must be hosted on a Premium v2 tier App Service Plan. In my example, the app is called myapp with a default URI of A virtual network access rule is added to the App Service to permit access from the subnet of the Application Gateway. Don’t forget to figure out what to do with the SCM URI for DevOps/GitHub integration.

Private Endpoint

A Private Endpoint was added to the App Service. The service/subresource/serviceGroup is sites. Automatically, Microsoft will update their DNS to modify the name resolution of to resolve to In the above example, the NIC for the Private Endpoint gets an IP address of from the AppSubnet that the App Service is now connected to.

Add an A record to the Private DNS Zone for the App Service, resolving to the IPv4 address of the Private Endpoint NIC. In my case, will resolve to This in turn means that > >

Application Gateway/WAF

  1. Add a new Backend Pool with the IPv4 address of the Private Endpoint NIC, which is in my example.
  2. Create a multisite HTTPS:443 listener for the required public URI, which will be in my example, adding the certificate, ideally from an Azure Key Vault. Use the public IP address (in my example) as the frontend.
  3. Set up a Custom Probe to test (using the hostname option) with acceptable responses of 200-399.
  4. Create an HTTP Setting (the reverse proxy) to forward traffic to (using the hostname option) using a well-known certificate (accepting the default cert of the App Service) for end-to-end encryption.
  5. Bind all of the above together with a routing rule.

Public DNS

Now you need to get traffic for to go to the (public, in my example) frontend IP address of the Application Gateway/WAF. There are lots of ways to do this, including Azure Front Door, Azure Traffic Manager, and third-party solutions. The easy way is to add an A record to your public DNS zone (, in my example) that resolves to the public IP address of the Application Gateway.

The Result

  1. A client browses
  2. The client name resolution goes to public DNS which resolves to the public IP address of the Application Gateway.
  3. The client connects to the Application Gateway, requesting
  4. The Listener on the Application Gateway receives the connection.
    • Any WAF functionality inspects and accepts/rejects the connection request.
  5. The Routing Rule in the Application Gateway associates the request to with the HTTP Setting and Custom Probe for
  6. The Application Gateway routes the request for to at the IPv4 address of the Private Endpoint (documented in the Application Gateway Backend Pool).
  7. The App Service receives and accepts the request for and responds to the Application Gateway.
  8. The Application Gateway reverse-proxies the response to the client.

For Good Measure

If you really want to secure things:

  • Deploy the Application Gateway as WAFv2 and store SSL certs in a Key Vault with limited Access Policies
  • The NSG on the WAF subnet must be configured correctly and only permit the minimum traffic to the WAF.
  • All resources will send all logs to Log Analytics.
  • Azure Sentinel is associated with the Log Analytics workspace.
  • Azure Security Center Standard Tier is enabled on the subscription and the Log Analytics Workspace.
  • If you can justify the cost, DDoS Standard Tier is enabled on the virtual network with the public IP address(es).

And that’s just the beginning 🙂

Why Use Azure DNS?

There are lots of reasons to use Azure DNS. But I’ll explain my fave in a few moments.

What is Azure DNS?

You cannot buy DNS domains from Azure, but you can host your domains (delegation) there. For example, you can buy your domain on GoDaddy (or whatever), and then change the Name Server (NS) records of the domain from the registrar’s name servers to Azure’s name servers (4 of them). Once you set up the zone, (PowerShell or Azure Portal), your zone/records are stored in in the global network of Azure DNS servers.

When a DNS client does a lookup of your zone, DNS will use Anycast to find the closest available DNS server to resolve the name.


I’ve seen first-hand and remotely how local name servers having an outage can cause much bigger damage to Internet services than you might imagine. Having your DNS servers in one small area creates a possibility where DNS goes offline and your services, which are still online, cannot be found by clients.

By having your DNS records hosted around the world, you can avoid this issue.


Once you’ve changed the Name Servers for your zone at the registrar, all of your DNS management is done in the Azure Portal or via PowerShell. DNS management in the Azure Portal is super-easy. The benefit is that Azure customers can reduce the number of tools that they need to use.


Imagine you need to automate changing or creating DNS records. Can you do that with your registrar? Azure DNS can be managed using PowerShell, which opens up some very interesting possibilities via Azure Automation.


By having your DNS records hosted all around the world (36 GA regions at the moment), your customers are going to be closer to your DNS servers, and therefore they can resolve your DNS names faster … and thus get to your service/content more quickly.

BTW, when you combine delegating the DNS for your Azure-hosted service to Azure DNS with a CDN such as Azure CDN then you should see massive improvements in the performance of your online services.

Was This Post Useful?

If you found this information useful, then imagine what 2 days of training might mean to you. I’m delivering a 2-day course in Amsterdam on April 19-20, teaching newbies and experienced Azure admins about Azure Infrastructure. There’ll be lots of in-depth information, covering the foundations, best practices, troubleshooting, and advanced configurations. You can learn more here.

Cannot Verify A DNS Domain In Azure Because You Used .LOCAL or .INTERNAL

A lot of companies have used a non-public domain name for their Active Directory. This meant that they didn’t have to buy an public domain name (but they probably did eventually for email), they had company politics issues, or they wanted to separate public from private (making resolution of external services easier). But this causes a problem when you are trying to federate or sync with Azure Active Directory, and I’ll explain a way to solve that issue here.

The Issue

When we connect a legacy Windows Server AD (LAD) to AAD we need to have both domain names matching. So if the company has an AD called joeelway.internal then they cannot sync or federate that domain to an Azure AD called (the public DNS domain for the company) or (a default domain name for an Azure subscription). This is because is we have a user, Barbara, then her UPNs would mismatch:

  • barbara@joeelway.internal VS OR
  • barbara@joeelway.internal VS


Method one is extreme and disruptive:

  • Rename the domain and deal with any consequences (eek!)
  • Configure internal DNS to resolve names of company-owned external services
  • Re-educate people about their UPNs if they’ve been using UPN to log in

I think we can agree that method 1 is too disruptive. There is a softer approach that you can use:

  • Configure an additional DNS suffix for your domain
  • Change the UPN of users to use the new DNS suffix
  • Re-educate people about their UPNs if they’ve been using UPN to log in

Adding a suffix is easy:

  1. Launch AD Domains and Trusts
  2. Right-click on Active Directory Domains And Trusts (not the domain name) and select Properties
  3. Enter the desired domain name in Alternative UPS Suffixes and click Add


Next you’ll change the UPN of the users. You can do this in AD Users and Computers (very slowly) or Google some PowerShell to do it near instantly at scale.

image #

Users will now have a single UPN for LAD (Azure, Office 365, etc), AAD, (hopefully) their email, and any third party SaaS if you federate your AAD.

A Demo Lab

I bought for my demo lab so I can show the real world solution in classes. If you’re just experimenting, learning, or doing a quick demo, then you can use the Azure default domain name. The default domain name is based on the name of your Azure subscription, for example Use this domain name as the additional suffix in your LAD, and set the UPNs to use this, e.g.; use this UPN for logging into cloud services.

Technorati Tags: ,,

Creating & Verifying Your DNS Domain in Azure AD

This post explains how to configure the DNS requirements to configure single sign-on (ADFS) or shared sign-on (synchronisation) in Azure AD (AAD) – you need to create a domain name in Azure AD and prove ownership of the domain to Microsoft.

Why Do You Need Matching Domain Names?

Imagine you have a “legacy” AD (LAD) running on one or more domain controllers called If you have a user called Mary then her user name might be joeelway\Mary. On the Internet, we’re more likely to use a UPN (user principal name), and in Mary’s case that would be

Let’s say that we create an Azure subscription called joeelwayazure. Any user that we create in there will be given a UPN with a suffix of For example, Mary would have This would be both confusing for Mary and for Azure because it doesn’t know that the two UPNs are actually for the same user.

If we want to configure single sign-on using Azure AD, use RemoteApp, or whatever, then we need to make sure that the UPN of the on-premise user account will match that of the in-cloud user account. And we can only accomplish this by creating a domain in AAD that matches the domain name of the LAD. So if my LAD domain name is then I need to make a domain in AAD called

Create The Domain

Do the following:

1) Sign into the Azure management portal

2) Browse to Active Directory > Default Directory > Domains

3) Click Add A Custom Domain

4) Enter the name of the domain name. Check the “I plan to configure this domain …” box if you plan to use ADFS for single sign-on.

5) Click Add and then proceed to the next screen.


5) Note the verification details.


Verify (Prove Ownership Of) Your Domain

You can only use a domain in AAD if you own it. This prevents any Joe from using for the UPNs. You will need to sign into your domain registrar where you manage the DNS domain name (e.g. In my case, that’s a company called Blacknight.

I logged in, browsed to the domain, and created a new TXT record using the details from the still-open verification screen in the management portal.


Now I can return to the Azure management portal, and click Verify. It can take a little time for the record (thanks to the fun of DNS) to be available so you can close the dialog in the management portal. The domain remains in an “Unverified” and unusable state. You can return to the domain, select it, and click Verify at a later time.

Tip: if you are in a lab scenario, you might have old TXT verification records that could prevent verification – make sure you delete these first.


With this done, you now have a verified domain ready for single or shared sign-on. Users can be created in your AAD default directory with a UPN suffix that matches your LAD domain name.

Question: what if your on-permises domain name is something like joeelway.local or joeelway.internal? You can’t host those domains on the Internet so you cannot verify them. I’ll deal with this in a later post.

Technorati Tags: ,,

Microsoft News – 29 June 2015

As you might expect, there’s lots of Azure news. Surprisingly, there is still not much substantial content on Windows 10.


Windows Server

Windows Client



Office 365