Wednesday, June 9, 2021

Troubleshoot HTTPS 502 error when Application Gateway in front of API management self-hosted gateway

We will go through the below topics in the blog:

  1. Introduction on APIM self-hosted gateway and how do we configure custom domain for it.
  2. Case Study: 502 error returned by V1 Application gateway when using HTTPS protocol.
  3. V2 Application gateway’s difference between V1 when verify server cert.

 

*In this blog, AG = Application Gateway. SH-gateway = self-hosted gateway.

 

If you are not familiar with AG and APIM integration, here are two well composed blogs that let us know how to work with AGv1, AGv2 and Managed APIM.

 

APIM with Application Gateway v1 - Microsoft Tech Community

Integrating API Management with App Gateway V2 - Microsoft Tech Community

 

Introduction on APIM self-hosted gateway and how do we configure custom domain for it.

 

To describe in brief, self-hosted gateway is APIM packaged in a Linux Docker image and can be deploy to any VM or on-prem machines.

More information here: Self-hosted gateway overview | Microsoft Docs

The blog will not include deploying the self-hosted gateway as the thesis is to explain some common issues that we will get when an App gateway is in front of it.

One easy way to find out if your self-hosted gateway is pulling API configurations from Azure is to check this ‘Status’.

 

Yixuan_Wang_0-1623209739153.png

 

A green light means the heartbeat connectivity is successfully established.

Configure the custom domain here at the ‘Hostname’ blade.

 

Yixuan_Wang_1-1623209739174.png

 

We will need to upload the pfx format first to the ‘Certificate’ blade of the APIM. So we can list it out here.

 

Yixuan_Wang_2-1623209739199.png

 

Yixuan_Wang_3-1623209739211.png

 

 

Once we made the hostname change, if we are following the docker container log for the self-hosted gateway, we can see an event being created. That means the hostname has taken effect.

 

Yixuan_Wang_4-1623209739233.png

 

Case Study: 502 errors returned by V1 Application gateway when using HTTPS

 

Background:

 

My V1 AG’s backend setting is targeting my SH-gateway’s hosting VM’s public IP.

Yixuan_Wang_5-1623209739237.png

 

I used a self-signed certificate for my SH-gateway’s domain. And have uploaded the cer format of this certificate to the AG.

 

Yixuan_Wang_6-1623209739239.png

 

Yixuan_Wang_7-1623209739241.png

 

 

I have over-written the hostname in http setting and custom probe.

 

Yixuan_Wang_8-1623209739248.png

 

 

Yixuan_Wang_9-1623209739258.png

 

 

Test HTTPS with postman, got 502 error.

 

Yixuan_Wang_10-1623209739279.png

 

 

HTTP however is working as expected, so I am suspecting the issue could be with the certificate. However, I have already uploaded the cer format to AG.

Yixuan_Wang_11-1623209739288.png

 

 

To narrow down and test HTTPS connectivity, I bypassed the AG and accessed the SH-gateway directly with IP:port. The IP is the docker container hosting VM’s public IP.

openssl s_client -connect XX.XX.XX.XX:443 -showcerts

 

Yixuan_Wang_12-1623209739309.png

 

 

As in the screenshot, the certificate that the server returned is not the custom domain certificate I configured for the SH-gateway. It is returning test.apim.net, the default self-signed cert.

I realized that when we access the APIM with IP, there is no SNI header in the request. Based on the APIM documentation:

 

Yixuan_Wang_13-1623209739321.png

 

 

In other words, for Managed APIM, we need to choose a default custom certificate for APIM to return, and the catch here is that SH-gateway will not let us choose defaultSslBinding. So, if there is no SNI header in the requests, SH-gateway always return the default test.apim.net cert.

 

But I was expecting the AG overwrites the hostname header and the SNI supposed to be set. After some research, I found the answer in AG’s documentation.

 

Yixuan_Wang_14-1623209739337.png

 

In conclusion, V1 AG set requests’ SNI uses backend pool setting, which means the hostname overwrites does not modify the SNI header, hence if we put IP as a backend pool target, SH-gateway’s server cert always mismatches with the cert we uploaded to the AG.

 

There are two solution options for this issue with AGv1:

  • Use FQDN as a backend target. Don’t use IP.
  • Use IP as a backend target, and download the test.apim.net cert, upload it to AG’s http setting. We need to give up custom domain with this solution.

 

For the solution No.2, I navigated to SH-gateway by IP with browser and downloaded the certificate from the browser.

 

Yixuan_Wang_17-1623209963825.png

 

V2 AG’s difference when verify server certificate

 

Since the AG will verify server cert’s root cert, and the test.apim.net does not have a root cert. The HTTPS requests will get 502 even if we uploaded this cert to APIM.

Yixuan_Wang_16-1623209739346.png

 

Therefore, if we configure custom domain for SH-gateway and use V2 AG in front of it,

1)The custom domain cert needs to be issued with well-known CA

2)Or it can be self-signed with a root cert, with the root cert uploaded to AG.

 

Hope this blog will help you identify the reason we get 502 when configure AG with APIM SH-gateway.

 

Appendix:

 

Enabling end to end TLS on Azure Application Gateway | Microsoft Docs

What is SNI? How TLS server name indication works | Cloudflare

Posted at https://sl.advdat.com/3x9JrFJ