If you’ve found this post then you’ve probably been through the Microsoft documentation. Although that documentation is great for getting you started it’s very generic and often I end up with more questions that answers. In this post I am going to go through the steps of building a Azure Web Application Firewall (WAF) and configuring it for multi-sites with both SSL offload and SSL end-to-end.
I’ve already built a Azure VM running Windows 2016 Server that has IIS running on it, IIS has been configured with a host header (billy.ctldev.co.uk) that initially is configured for HTTP/80 only. This will be the web service that the WAF will be protecting. To ensure that all data is sent through the WAF there is a NSG on the VM that is blocking all inbound traffic from the internet. The WAF will be deployed to the same Virtual Network as the VM is residing in, however it will be sat on a different subnet to the VM. If I am reading the MS documentation correctly when using VMs as the end point targets everything needs to be in the same VNet or the VNets must be connected so traffic can pass from the WAF to the VMs.
I am not going to cover the setup of the probe or the diagnostics as the Microsoft documentation covers this quite well, and to be honest it’s very straightforward to configure, particularly when compared to configuring the WAF.
It is a reasonably complicated process with a number of steps, I’ve tried to keep things easy to follow but if you do have questions please post them in the comments below.
Initial Provisioning and Configuration
A couple of points worth mentioning. When you make a change to a listener or rule the provisioning can take 5 minutes to save, during this time connectivity to the back end servers can be disrupted. It also means making changes can take a looooong time. Secondly, when changes are made it can take a couple of minutes for these changes to take effect, so for example if you are getting an error when trying to connect to a backend web site and you make a change, give it a few refreshes before continuing to troubleshoot.
Ok, lets start
Jump onto your Azure subscription and click the “Create a resource” button. In the search box type “Application Gateway” and select the “Application Gateway” from the list.
Click on “Create”
In section 1 we need to:
- Set the name of the WAF
- Set the tier to WAF
- Select the SKU
- The instance count
- Create the resource group
- Set the location, this needs to be the same as the virtual network were you are going to install the WAF
In section 2 we need to do the following:
- Select the virtual network where we want the WAF to be provisioned to
- Select the sub net, as mentioned above I’ve created a new subnet in my VNet address space for the WAF to use
- Create a public IP address
- Configure a DNS name, you don’t need to do this and Azure will create a random one for you. I am a bit fussy so I like to create my own. Later we’ll use this name in our public DNS as the target for a CNAME.
- Leave the listener set to HTTP, I’ll explain why later
- I’ve left HTTP2 disabled for this test
- Ensure the Firewall is enabled (should be by default)
- Choose the mode you want the firewall to be running in, for this test I’ve left it as “Detection”
Ok, click on “Create” and go and get a cuppa as this will take about 15 minutes to provision.
So now you should have a WAF provisioned within your Azure subscription. The next step is to configure the backend pools. The WAF also acts as a NLB so you can target a number of VMs within an availability set to provide a fully resilient web service. As this is a test I’ve only got the one VM, let’s add that to the pool.
Open the Web Application Firewall properties and find “Backend pools” in the navigation.
Click on “Backend Pools” and you’ll see that there is a default pool created called “appGatewayBackendPool“, we’ll use this for our pool
Click on “appGatewayBackendPool”
Change the targets to “Virtual Machine” then select the virtual machine that is hosting the web service along with it’s NIC.
Click “Save” when done. The provision takes a little while to process, it’s worth noting here that if you change this pool setting on a live environment it will become unavailable while the provisioning process is running.
As mentioned at the start this configuration is to support multi-site. Although this is different to single (basic) site most of the information can be used for setting up a single (basic) site. However I think that multi-site support is going to be more relevant because you are more likely to use a WAF to protect a number of web sites rather than just one. The biggest difference is that multi-site you need to specify the host header of the site in the configuration.
The next step is to create a listener for the site (host header).
First thing we need to do is create a new “Listener“, from the WAF select “Listeners” from the navigation and then click on “Multi-Site”
Add the following detail
- Host name, this will match the host header of the site i.e. billy.ctldev.co.uk
- Protocol HTTP
Click “OK” to save the listener, wait for the listener to be provisioned before continuing.
Select “Rules” from the navigation
- Add a name for the rule
- Select the listener you’ve just created
- Select the backend pool (there will only be one to choose from)
- Leave the HTTP setting as default
Click “OK” to save, again wait for the update to finish.
You can now go back into the “Listeners” section and delete the default listener as this is no longer required. Click ok to the warning around rules.
We now need to updated the public DNS and create a CNAME record that redirects “billy.ctldev.co.uk” to the DNS alias of the WAF. In the early steps of creating the WAF we set the DNS alias as we were provisioning the WAF. If you can’t remember what you set it to, then you can find it on the public IP address overview pane. After you’ve updated your DNS you can now test your WAF by opening a browser and typing in the URL to your IIS server.
NOTE: I did have an issue getting this to work, then I found a random note in the Microsoft documentation that said the default IIS binding had to be in place for the WAF to work. In my testing I did find this to be the case so if you find that your WAF isn’t working just check the default bindings are present i.e.
I am note sure why this is the case and it does pose some other questions on how to configure additional host headers on the same IIS service but I’ll let you guys work that one out 🙂
Right so at this stage you should be able to browse to your HTTP web page. Next we are going to look at SSL. There are a couple of options available with WAF, these are:
- SSL Termination/SSL Off-loading – this is where the gateway has the SSL certificate and encrypts traffic between it and the client. The traffic between the gateway and the backend servers is done over HTTP.
- End-to-End SSL – this ensure that all traffic from the client through gateway to the backend is encrypted.
For testing I’ve used self-signed certs rather than CA’s, this worked (apart from the usual certificate errors in the browser) so if you have any issues I urge you to double check your configuration as the issue most likely lies there.
So first off I’ve created a self-signed certificate from IIS on my VM, the certificate has a common name of “billy.ctldev.co.uk” (aka FQDN of the web site). This certificated has then been exported with a key (PFX file) and also exported without the key (CER file). I’ve copied both of these files to my PC as I am going to need them to import into the WAF.
SSL Off loading
First off let’s create a new Listener, as before select “Multi-site”
- Add a name
- Click the drop down in “Frontend Port” and select “New“
- Create a name for the frontend port
- Set the Port to 443
- Add the hostname of the website
- Change the protocol to HTTPS
- Browse for the certificate PFX file created earlier
- Enter a name for the Certificate, this is just a name to identify the certificate
- Enter the password for the certificate
Click “OK” to save, wait for the update to complete.
Now go to the “Rules” section and click on “Basic”
- Add a name
- Select the HTTPS listener you’ve just created
Click “OK” to save
Now we need to add a redirect so that any traffic that comes in on HTTP gets redirected to HTTPS
Go back to the “Rules” and this time click on the non-HTTPS rule you created earlier.
- Check the “Configure redirection“
- Set the redirection type to “Permanent“
- Set the redirection target to “Listener”
- Select the HTTPS listener you created above
Now test via a browser, if all’s well when you go to the HTTP URL of the site it will automatically redirect to HTTPS (of course the browser will complain about the self-signed cert, but you should still be able to get to the site). If it doesn’t redirect make sure you’ve removed the default rule as explained above.
This process builds on the SSL Offload instructions above, so before you start follow the instruction above and get SSL Offloading working. When you’re done come back here and I’ll show you the last few steps needed to create the SSL End-to-End setup.
Once that is done go back to the WAF in the Azure portal and select “HTTP Setting” from the navigation.
Select “HTTP Setting” from the navigation
- Set the name
- Change the protocol to HTTPS
- Add a name to identify the certificate
- Browser to the certificate CER file
Click “OK” to save
Now go to “Rules” and edit the HTTPS rule you created earlier and change the “HTTP Setting” to the HTTPS Setting you just created
Now test by browsing to your web page, this should fail:
This is because we are now doing an end-to-end SSL connection and at this stage the IIS server isn’t configured with SSL.
Ok, now you need to go to your IIS server and create a new binding using the same host header but this time making it HTTPS and selecting the self-signed certificate you create earlier.
You also need to add a default HTTPS binding to the IIS server using that certificate like so:
Now test by browsing to your web page and you should be in business!
Ok, you’ve now setup a Web Application Firewall in Azure using multi-site configuration and secure with SSL with HTTP->HTTPS redirection for good measure. All you need to do now is setup the probes and diagnostics