Is it possible to host ODK Central behind application gateway (SSL termination)

1. What is the issue? Please be detailed.
Exploring method to host ODK Central in Azure behind application gateway and SSL termination at application gateway. What are the changes need to make to .env and docker-compose.yml?

2. What steps can we take to reproduce this issue?

3. What have you tried to fix the issue?

4. Upload any forms or screenshots you can share publicly below.

Hi!

Yes, this seems to be possible. You can set up ODK Central behind a reverse proxy configuration [documentation reference], also Azure Application Gateway can be configured to entertain ODK Central and handle the SSL termination.

Hope this helps.. great day!

My setup is deploy a vm (private ip) behind application gateway.

I have try using upstream, change the .env and docker-compose.yml as suggested. I try additional step but nothing seem to work yet. 502 bad gateway

I stumble on a few issues with this setup. Thanks to the new AI integration in ODK docs, I manage to understand some aspect and try new ways that the AI have suggested. I hope some facts given by AI hold true and not make it worse.

The following are some trial and error:

  1. SSL terminate at application gateway (upstream) and there is no SSL between application gateway and backend pool.
    Attempt 1: Listerner (443) HTTPS--> Backend pool (8443) HTTPS
    Attempt 2: Listerner (443) HTTPS --> Backend pool (8080) HTTP probably will work (not confirmed yet)

Attempt 1 is not working. Still 502 bad gateway
Backed pool (8443), unlikely to work as there is no signed certificate according to AI.

  1. Another issue is since the VM is on private ip, the vm and container was unable to resolve dns.
    Check with nslookup and curl domain name not successful.

However, once configure hosts:
domain vm_ip
and
extra_host in docker-compose.yml for enketo,

Finally, able to curl with http://domain:8080 . but curl with https://domain:8443 in vm (host) will fail.
Perhaps this has verified my first point.
Not sure this tweak is acceptable for production. Or, a private dns zone should be used instead.

  1. My next attempt will be
    Listerner (443) HTTPS --> Backend pool (8080) HTTP

Can anyone shed some glimpse of light here?

Hmm.. this should work in general.

Are you using the UPSTREAM_HTTPS_PORT=443 variable?

I think a key thing here is that the user --> proxy route is HTTPS, while the proxy --> central route is HTTP (you don't want double SSL wrapping, and would need a second cert for that)

So the proxy (application gateway) should route traffic to http://machine_ip:8080.

Have you confirmed the Central service is running locally? curl http://localhost:8080/v1/?
(if running in a container, be sure port 8080 is bound to the host in the compose file, so the nginx service is accessible to the application gateway)