Azure MFA – ADFS Proxy Build

This post is part of a series, for the series contents see: Azure MFA

Things are starting to near completion now:

  • I’ve got an ADFS server configured
  • Testing shows that it works internally

Next up is to build up an ADFS proxy server to expose that to the outside world where it can be used so that I can authenticate against SaaS apps using my internal domain accounts.

So what I need to do is build up a web application proxy server in my DMZ, give it a public IP address, and then setup a public facing DNS record ( pointing to that public IP address.


Just as with the ADFS server you need to make sure you install your SSL certificate on the server before configuring it as an ADFS proxy so that it’s available for you to choose during the install wizard.  In my case, I just copied over my Let’s Encrypt SSL cert for, double-clicked to install it and then chose the local computer option when asked.

ADFS Proxy VM Build

The PowerShell to create the VM is:

# Setup Windows ADFS Proxy VM #

#Specify the resource group and location
$RGName = "dmz-rg"
$Location = "North Europe"

#First setup default credentials to use in provisioning by retrieving and decrypting our Key Vault password
$Username = "adminuser"
$SecurePwd = Get-AzureKeyVaultSecret -VaultName 'lab-vault' -Name 'ProvisionPassword'
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $SecurePwd.SecretValue

#Define VM basics
$VMName = "adfsproxy-vm"
$VMSize = "Standard_A1"
$OSDiskName = $VMName + "OSDisk"
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName $RGName -Name dmzvmstr
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name dmz-vnet

#Create a public IP
New-AzureRmPublicIpAddress -Name adfsproxy-vm-pip -ResourceGroupName $RGName `
-AllocationMethod Static -Location $Location

#Define VM network details
#Private IP
$NIC1 = New-AzureRmNetworkInterface -Name "adfsproxy-vm-eth0" -ResourceGroupName $RGName -Location $Location -SubnetId $vnet.Subnets[0].Id -PrivateIpAddress

#Public IP
$pip = Get-AzureRMPublicIPAddress -ResourceGroupName $RGName -Name adfsproxy-vm-pip
$NIC1.IPConfigurations[0].PublicIPAddress = $pip

#Confirm the details
Set-AzureRmNetworkInterface -NetworkInterface $NIC1

#Define the VM config
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -ComputerName $VMName -Windows -Credential $Credential
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2016-Datacenter" -Version "latest"
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id
$OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd"
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage

#Create the VM
New-AzureRmVM -ResourceGroupName $RGName -Location $Location -VM $VirtualMachine

Setting Up Name Resolution

The DNS zone for my domain ( is hosted in Azure DNS so I can also use PowerShell to update my public facing DNS record.  I say “update” because, of course, I already created an record pointing to my cert-vm’s public IP so that I could get my free Let’s Encrypt SSL cert.  This will re-point that existing record to my ADFS Proxy VM’s public IP instead:

#Update my sts DNS record to now use my ADFS Proxy public IP instead of the cert-vm public IP
$RGName = "hub-rg"

$RecordSet = Get-AzureRmDnsRecordSet -Name "sts" -RecordType A -ZoneName -ResourceGroupName $RGName

$RecordSet.Records[0].Ipv4Address = $pip.IpAddress
Set-AzureRmDnsRecordSet -RecordSet $RecordSet

The next step might seem a little odd but, when you think about it, it does make sense:  I need to create a hosts file entry on the ADFS proxy VM pointing at my internal ADFS server.

It comes down to the fact that ADFS makes use of split brain DNS:

  • Public DNS pointing to the ADFS proxy server
  • Internal DNS pointing the the ADFS server

The proxy server needs to offload to the ADFS server but because it is in the DMZ it won’t be using internal DNS, it will query public DNS and end up resolving to itself and getting stuck in a loop!  So, to stop that happening, I need to setup a hosts file entry on the server pointing it internally instead:

ADFS Proxy Hosts File

ADFS Proxy Configuration

The installation itself can just be done via “Add Roles and Features” but you won’t find an “ADFS Proxy” role, what you want is “Remote Access”:

ADFS Proxy Config Step 1

Then specify “Web Application Proxy”:

ADFS Proxy Config Step 2

Next up, specify some details about the ADFS service and an account with permissions to connect to the internal ADFS server:

ADFS Proxy Config Step 3

Before finally getting to the part of the wizard where you can choose the SSL cert you installed earlier:

ADFS Proxy Config Step 4

And then you should be done and have a working, publicly available ADFS infrastructure in place.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: