Reverse proxy for Azure DevOps Server (NTLM)

1. Caddy version (caddy version):

Docker from hotio/caddy - hotio.dev
On Docker, lastest version builded (9 days ago) => v2.4.1

2. How I run Caddy:

docker run -d --name=‘caddy’ --net=‘bridge’ -e TZ=“Europe/Paris” -e HOST_OS=“Unraid” -e ‘CUSTOM_BUILD’=’/config/custom/caddy_linux_amd64_custom’ -e ‘PUID’=‘99’ -e ‘PGID’=‘100’ -e ‘UMASK’=‘002’ -p ‘18080:8080/tcp’ -p ‘18443:8443/tcp’ -v ‘/mnt/cache/appdata/caddy’:’/config’:‘rw’ --cap-add=NET_ADMIN --restart unless-stopped ‘hotio/caddy’

caddy_linux_amd64_custom is builded from your website with ntlm plugin for amd64

a. System environment:

Docker on Unraid 6.9.2

b. Command:

Paste command here.

c. Service/unit/compose file:

Paste full file contents here.
Make sure backticks stay on their own lines,
and the post looks nice in the preview pane.

d. My complete Caddyfile or JSON config:

{
  http_port  8080
  https_port 8443
}

:8080 {
  log {
    output file /config/logs/access.log
  }
  root * /app/www
  file_server
}

devops.mydomain.one 
{
  log {
    output file /config/logs/access_devops.log
    level WARN
  }
  tls xxx@protonmail.com  
  reverse_proxy 192.168.1.5:80 {
    header_up Host {http.reverse_proxy.upstream.hostport}
    header_up X-Forwarded-Host {host}
    transport http_ntlm {
      tls_insecure_skip_verify
    }
  }
}

issues.mydomain.one {
  log {
    output file /config/logs/access_exceptionless.log
    level WARN
  }  
  tls xxx@protonmail.com
  reverse_proxy 192.168.1.18:18354 {
     header_up X-Real-IP {remote_host}
  }
}

shiori.mydomain.one {
  log {
    output file /config/logs/access_shiori.log
    level WARN
  }   
  tls xxx@protonmail.com
  reverse_proxy 192.168.1.18:8085 {
     header_up X-Real-IP {remote_host}
  }
}

sonarqube.mydomain.one {
  log {
    output file /config/logs/access_sonarqube.log
    level WARN
  }    
  tls xxx@protonmail.com
  reverse_proxy 192.168.1.18:9000 {
     header_up X-Real-IP {remote_host}
  }
}

share.mydomain.one {
  log {
    output file /config/logs/access_youtransfer.log
    level WARN
  }    
  tls xxx@protonmail.com
  reverse_proxy 192.168.1.18:5000 {
     header_up X-Real-IP {remote_host}
  }
}

bitwarden.mydomain.one {
  log {
    output file /config/logs/access_bitwarden.log
    level WARN
  }    
  tls xxx@protonmail.com
  reverse_proxy 192.168.1.18:8185 {
     header_up X-Real-IP {remote_host}
  }
}

3. The problem I’m having:

I am trying to reverse proxy a self hosted Azure Server DevOps (Community).
But i can’t access Azure Devop in browser, no prompt for user account.

4. Error messages and/or full log output:

ErrorWarningSystemArrayLogin

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 00-start-container: executing...

----------------------------------------------------------------------
ENVIRONMENT
----------------------------------------------------------------------
PUID=99
PGID=100

2
TZ=Europe/Paris
CUSTOM_BUILD=/config/custom/caddy_linux_amd64_custom
----------------------------------------------------------------------

Executing usermod...
Applying permissions to /config
[cont-init.d] 00-start-container: exited 0.
[cont-init.d] 01-config-app: executing...
Installing default "templates"...
[cont-init.d] 01-config-app: exited 0.
[cont-init.d] 02-custom-build: executing...
Trying to use the custom build "/config/custom/caddy_linux_amd64_custom"...
Built-in: v2.4.1 h1:kAJ0JB5Xk5gPdTH/27S5cyoMGqD5lBAe9yZ8zTjVJa0=
Custom: v2.4.1 h1:kAJ0JB5Xk5gPdTH/27S5cyoMGqD5lBAe9yZ8zTjVJa0=
[cont-init.d] 02-custom-build: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
{"level":"info","ts":1622283275.5793426,"msg":"using provided configuration","config_file":"/config/Caddyfile","config_adapter":""}
{"level":"warn","ts":1622283275.5825603,"msg":"input is not formatted with 'caddy fmt'","adapter":"caddyfile","file":"/config/Caddyfile","line":2}
{"level":"info","ts":1622283275.5838346,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019","127.0.0.1:2019"]}
{"level":"info","ts":1622283275.5840342,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv1","https_port":8443}
{"level":"info","ts":1622283275.5840526,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv1"}
{"level":"info","ts":1622283275.5840616,"logger":"http","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":8080}
{"level":"info","ts":1622283275.5841253,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000355b90"}
{"level":"info","ts":1622283275.5848236,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["sonarqube.mydomain.one","bitwarden.mydomain.one","devops.mydomain.one","issues.mydomain.one","shiori.mydomain.one","share.mydomain.one"]}
{"level":"info","ts":1622283275.5848854,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/config/caddy"}
{"level":"info","ts":1622283275.5880704,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1622283275.5943847,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1622283275.5943947,"msg":"serving initial configuration"}
2021-05-29 12:14:35,808 fail2ban.server [287]: INFO --------------------------------------------------
2021-05-29 12:14:35,808 fail2ban.server [287]: INFO Starting Fail2ban v0.11.1
2021-05-29 12:14:35,809 fail2ban.observer [287]: INFO Observer start...
2021-05-29 12:14:35,852 fail2ban.database [287]: INFO Connected to fail2ban persistent database '/config/fail2ban/fail2ban.sqlite3'
2021-05-29 12:14:35,853 fail2ban.jail [287]: INFO Creating new jail 'caddy-4xx'
2021-05-29 12:14:35,858 fail2ban.jail [287]: INFO Jail 'caddy-4xx' uses poller {}
2021-05-29 12:14:35,859 fail2ban.jail [287]: INFO Initiated 'polling' backend
2021-05-29 12:14:35,861 fail2ban.filter [287]: INFO maxRetry: 20
2021-05-29 12:14:35,861 fail2ban.filter [287]: INFO findtime: 60
2021-05-29 12:14:35,861 fail2ban.actions [287]: INFO banTime: 3600
2021-05-29 12:14:35,861 fail2ban.filter [287]: INFO encoding: UTF-8
2021-05-29 12:14:35,861 fail2ban.filter [287]: INFO Added logfile: '/config/logs/access.log' (pos = 5059, hash = 329f06d839adacd083cecfef0a4e07b7ca202a62)
2021-05-29 12:14:35,863 fail2ban.jail [287]: INFO Jail 'caddy-4xx' started
Server ready
{"level":"error","ts":1622284983.8421829,"logger":"http.log.error.log1","msg":"tls: first record does not look like a TLS handshake","request":{"remote_addr":"123.123.123.123:1044","proto":"HTTP/1.1","method":"GET","host":"devops.mydomain.one","uri":"/","headers":{"Sec-Fetch-Dest":["document"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Sec-Gpc":["1"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-User":["?1"],"Connection":["keep-alive"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"http/1.1","proto_mutual":true,"server_name":"devops.mydomain.one"}},"duration":0.002190392,"status":502,"err_id":"cyu21ji1j","err_trace":"reverseproxy.statusError (reverseproxy.go:861)"}

5. What I already tried:

I have added ntlm module and tried with post found on forum but no succes …

6. Links to relevant resources:

I think the problem is that you’re trying to proxy on port 80 which is an HTTP server, but you specified tls_insecure_skip_verify which told Caddy to try to make an HTTPS request.

You can’t make HTTPS requests to an HTTP server.

Try removing tls_insecure_skip_verify.

1 Like

Hello francislavois,

Thanks it’s now partially working wiouth tls_insecure_skip_verify. I am redirected to authentication prompt, but i need to enter credentials 2 times to access devops ui …, once with remote host (devops.mydomain.one) and then for local IP ?

I have found this ressource who explain how to reverse proxy devops with HaProxy … Using HAProxy as a reverse proxy for Azure DevOps Server - Tom Austin but i don’t kown how to translate this for caddy …

This topic was automatically closed after 30 days. New replies are no longer allowed.