I recently had the need to allow access to an on-premise Azure Devops Server instance over the internet. This had been attempted in the past using apache as the reverse proxy but due to ADS using NTLM Authentication ADS (or TFS as it was at the time) would constantly prompt for credentials without really getting anywhere. After a bit of research it looked like HAProxy might help with this so I decided to spin up a lab environment in Azure to test it out.
Before we start I would heavily suggest you don’t just reverse proxy ADS, ADS provides no 2 factor authentication capabilities so you’re going to be opening yourself up to credential stuffing and a whole host of other attacks by making it publicly accessible. Instead you probably want to be looking at migrating to Azure DevOps.
This tutorial assumes you already have Azure DevOps Server installed and configured.
There isn’t really a great deal to this so the first thing to do is create yourself a HAProxy server, I used Ubuntu 18.04 and then installed HAProxy.
sudo apt-get install haproxy
Now lets open up the HAProxy config file using nano and get to work!
sudo nano /etc/haproxy/haproxy.cfg
Below the defaults we need to add a backend to tell HAProxy where to send our traffic.
backend backend_tfs
server static adsip:80 check maxconn 3
mode http
balance roundrobin
option http-keep-alive
option prefer-last-server
timeout server 30s
timeout connect 4s
Substitute ‘adsip’ with your internal ADS/TFS IP address. Now let’s declare the frontend.
frontend frontend_tfs
bind :80 name frontend_tfs
mode http
option http-keep-alive
timeout client 30s
default_backend backend_tfs
The options which are doing the magic here are http-keep-alive and prefer-last-server. Save, exit and reload HAProxy and you’re all done!
sudo service haproxy restart
If you want to try this for yourself in Azure here is a resource template which will create vm’s for a domain controller, ads instance and HAProxy. The template also includes a vm for apache in case you want to see what happens when you try and use apache as the reverse proxy.