Application gateway to secure APIM (Internal mode)

If you have followed this article then you have successfully completed the internal setup of an APIM stV2. In order to access this in a control manner form the internet an application gateway is the best option. This set up is quite confusing and complicated when you have to follow your traffic all the way to an on premises network but trust me it is possible.

To start with and before implementing your application gateway we are going to create custom domains for all the APIM endpoints. In that way we can create listeners on the gateway in order to provide access to the APIM services. There a number of default endpoints that are created but there is no distinct control over them unless you customize them.

  1. Under the Settings section, navigate to the Custom Domains blade on your API Management service.
  2. As you click the Add button, a new window would allow you to choose the type of endpoint along with the custom domain name you would like to configure.
  3. For this setup, I have used the management, gateway and portal endpoints of the APIM service to be invoked with similar names

Upon adding each custom domain a certificate is required to validate the connection. Specifically for a Version 2 application gateway I used the PowerShell script script below to create a self signed certificate:

$param1 = @{

  Subject = "CN=azure-apim.net
 , C=UK"

  KeyLength = 2048

  KeyAlgorithm = 'RSA'

  HashAlgorithm = 'SHA256'

  KeyExportPolicy = 'Exportable'

  NotAfter = (Get-Date).AddYears(5)

  CertStoreLocation = 'Cert:\LocalMachine\My'

  KeyUsage = 'CertSign','CRLSign'

}

$rootCA = New-SelfSignedCertificate @param1


# Grab the thumbprint of the root certificate

$thumb = $rootCA.Thumbprint

$root = Get-Item -Path Cert:\LocalMachine\My\$($thumb)

#This is a path you want to download the .cer of the root certificate.

$path = "C:\cert\gateway\gatewayroot.crt"

 
# Export the root certificate in a Base64 encoded X.509 to the path created above

$base64certificate = @"

-----BEGIN CERTIFICATE-----

$([Convert]::ToBase64String($root.Export('Cert'), [System.Base64FormattingOptions]::InsertLineBreaks)))

-----END CERTIFICATE-----

"@

Set-Content -Path $path -Value $base64certificate -force


# Import the root certificate of the self-signed certificate to the local machine trusted root store

Import-Certificate -CertStoreLocation 'Cert:\CurrentUser\My' -FilePath "C:\cert\gateway\gatewayroot.crt"

 
# Create a new self-signed certificate and then link the root and the self-signed certificate

$param2 = @{

    DnsName = '*.azure-apim.net'

    Subject = "secapigateway.azure-apim.net"

    Signer = $rootCA

    KeyLength = 2048

    KeyAlgorithm = 'RSA'

    HashAlgorithm = 'SHA256'

    KeyExportPolicy = 'Exportable'

    CertStoreLocation = 'Cert:\LocalMachine\My'

    NotAfter = (Get-date).AddYears(25)

}

$selfCert = New-SelfSignedCertificate @param2

# Export the certificate in .pfx format for the application gateway listener and ASE ILB Cert.

Export-PfxCertificate -Cert $selfCert -FilePath "C:\cert\gateway\gateway.pfx" -Password (ConvertTo-SecureString -AsPlainText '<yourpassword>' -Force)

This procedure need to be repeated 3 times for every endpoint.

At this point its worth reminding that APIM on internal mode must use custom DNS. So if you have not followed the guide here it wont behave as expected.

Creating a private DNS zone is described here