Azure App Services (Web Apps) are publicly exposed to the Internet by default, accessible with their *.azurewebsites.net URL. This means that anyone in the world can access your site simply by knowing its URL, including hackers and spammers.
We can secure our site by using an Application Gateway as a frontend. Azure App Gateway is an HTTP load balancer that allows you to manage traffic to your web apps. App Gateway operates at layer 7 (application layer) and can scan incoming requests using OWASP common vulnerabilities rule set and/or route based on URL syntax. The App Gateway offers many other features including DDoS protection: https://docs.microsoft.com/en-us/azure/application-gateway/overview.
Application Gateway v2 is currently in public preview with upcoming general availability. Organizations and individuals concerned with security/compliance in the cloud can leverage these services for an isolated environment where their backend Web App is entirely secured.
Here’s what it looks like:
SSL Termination vs End to End SSL
It’s also important to understand the role of SSL in this scenario. There are two options, either SSL termination at the App Gateway or end to end SSL all the way through to the backend. With SSL termination the PFX is uploaded directly to the App Gateway, traffic flows unencrypted to the backend, if the resources exist in the same datacenter the traffic never egresses but it is still unencrypted which is vulnerable. The benefit of SSL termination is that the backend is unburdened by the additional overhead.
With end to end SSL, the App Gateway terminates SSL sessions at the gateway and decrypts client traffic. It then applies the configured rules to target the appropriate backend pool. A new SSL connection is initiated to the backend server and re-encrypted using the backend server’s public key certificate. This connectivity between the App Gateway and the backend server occurs securely over port 443. Each individual’s security requirements or paranoia will determine which is a better option.
Create Application Gateway V2
To start off we will deploy an App Gateway V2, selecting Standard V2 as the tier, and Central US as the location. It’s worth noting that the App Gateway is free of charge until GA.
Create backend Web App
Next we will deploy a regular Web App with a Free tier App Service Plan in Location: Central US.
Now I will edit the default homepage of my Web App to dump out all of the request headers, which is useful for understanding how the App Gateway works, relying on Host header and others like x-forwarded-for.
- Access the Kudu site at https://<webAppName>.scm.azurewebsites.net/DebugConsole and navigate into the \site\wwwroot\ directory
- Delete the hostingstart.html file
- On the command line type: touch default.aspx
- Click the pencil icon to edit the file, and paste in this source code: https://pastebin.com/d6XXASiK
- Save the file
- Test the site directly now by going to https://<webAppName>.azurewebsites.net and you will see all the request headers dumped out
Configure the Custom Hostname DNS and create the HTTPS Listener
Now I need to decide what custom hostname I want to access the site on and I will need to have a matching SSL certificate. For this test I will use my valid SSL certificate for www.patrickob.com, but for testing purposes you can create a self-signed cert and export the PFX.
- I don’t want to interrupt the active routing of my site so I’m going to edit my Hosts file to point at my new App Gateway’s public IP, or use a fake domain for testing
- We can see this in the Azure Portal from the Overview blade of the App Gateway
- Update my local machine’s Hosts file to include this entry
- I need to have the PFX file for the SSL certificate that matches this custom hostname, because it needs to be uploaded to the App Gateway to serve to clients
- Open the App Gateway in the Azure Portal and click on the Listeners blade, create a new Multi-Site Listener
- Set the host name property appropriately and upload the matching PFX
Create HTTPS Health Probe
- Open the Health Probes blade of the App Gateway
- Create a new HTTPS health probe, which will be used to verify the backend health
Create an HTTP Setting with End to End SSL enabled
- Open the HTTP Settings blade of the App Gateway
- Create a new HTTP Setting, which is what will be used to configure our connection to the backend pool
- In this case we want to use end to end SSL for maximum security, the backend Web App certificates are trusted by default
- Select HTTPS protocol, Use for App Service, and select the custom probe created previously
Create a Backend Pool
- Open the Backend Pools blade of the Application Gateway
- Add a new backend pool and target our previously created App Service
Create a Routing Rule
- Open the Rules blade of the Application Gateway
- Add a new Basic rule and select our previously created Listener, Backend Pool, and HTTP Setting
Configure IP Restrictions on the Web App to restrict access to only the App Gateway
- We want to block all direct access to the backend Web App except from the client IP of our App Gateway, which is static and same as the frontend IP found previously
- Open the Web App in the Azure portal and click on the Networking blade, then Access Restrictions
- Add a rule that allows the App Gateway’s IP address, with the /32 subnet block
- You can now test the site using its default *.azurewebsites.net URL to confirm that direct access is denied
Test the Site and confirm Solution
- Click on the Backend Health blade of the App Gateway, here we can confirm our new probe is receiving a healthy status from the backend over port 443
- We can now test accessing the site through the Application Gateway by using the custom domain we setup previously, in my case www.patrickob.com
- Note several important headers, including the Host header which shows that we have reached the backend over its default hostname and port 443
My backend is now isolated and all clients must route through my Application Gateway, which protects me from common vulnerabilities and DDoS. This is only an elementary introduction to App Gateway and it offers many powerful features.
I hope this example is helpful~!
7 replies on “App Service with Application Gateway v2: High Security in Azure PaaS”
[…] I use my previously created App Gateway and Web App from here: https://www.patrickob.com/2019/02/20/app-service-w-app-gateway-v2-high-security-in-azure-paas/. […]
It is not correct that this protects you from DDoS attacks, as the IP filtering is taken care of in the web app and not at network level.
Thanks for your comment. Per the documentation, the DDoS protection feature offered through Azure is supported on the App Gateway: https://docs.microsoft.com/en-us/azure/virtual-network/ddos-protection-overview. This is a factual statement.
Whether or not this provides realistic protection in the wild is another question.
Standard: Provides additional mitigation capabilities over the Basic service tier that are tuned specifically to Azure Virtual Network resources. DDoS Protection Standard is simple to enable, and requires no application changes. Protection policies are tuned through dedicated traffic monitoring and machine learning algorithms. Policies are applied to public IP addresses associated to resources deployed in virtual networks, such as Azure Load Balancer, Azure Application Gateway, and Azure Service Fabric instances, but this protection does not apply to App Service Environments.
I am curious, does this also require that traffic accessing the kudu console to come through the app gateway as well? Is it possible it to configure the application in this way?
Excellent question. There is no requirement to have the traffic for Kudu site route through App Gateway, even if you are using an App Gateway to frontend the application itself. It should not be a fundamental security requirement, because the Kudu site is already restricted with authentication/authorization.
For most regular App Services, it would simply not be possible. The Kudu site only responds on the default SCM URL, where as the application side can be configured to accept multiple different custom domains.
The only scenario where I have seen Kudu site accessed through App Gateway is using an ILB ASE, and updating the internal DNS to point the SCM URL to the App Gateway IP instead of the ILB VIP.
I cannot make this work if I enabled Azure AD authentication in the Web App. Appreciate if you can share any advice on th
Greetings and sorry for my late reply. You will probably be interested in my other post here about some of the common auth issues involved with this kind of setup: https://www.patrickob.com/2019/02/27/use-for-app-service-and-application-gateway-unexpected-consequences/.
I suspect the issue you are describing is the same as what I detail in that post. There are options to make this work, but it takes different settings in the App Gateway (HTTP Settings) which are not immediately obvious to a new user. If you are experiencing an unexpected redirect or auth failure and cannot solve it, I would encourage you to engage Azure Support or send me an email personally and I can give some help.