Migrate to using a wildcard certificate

1. Caddy version (caddy version):

v2.3.0 built including the Cloudflare module

2. How I run Caddy:

I use Caddyfile rather than JSON.

a. System environment:

FreeNAS 11.3 (a FreeBSD derivative)

b. Command:

service caddy start

c. Service/unit/compose file:

n/a

d. My complete Caddyfile or JSON config:

This is an extract from the relevant section of my Caddyfile that I’m looking at converting to use a wildcard certificate.

www.udance.com.au, udance.com.au {
  encode gzip
  import tlsdns
  import authproxy /phpmyadmin*
  import logging udance

  reverse_proxy http://10.1.1.55

  reverse_proxy /tautulli* http://10.1.1.26:8181
  reverse_proxy /transmission* http://10.1.1.28:9091
}

import online rslsync      10.1.1.22:8888 # Resilio Sync
import online cloud        10.1.1.29      # Nextcloud 
import online heimdall     10.1.1.23      # Heimdall 
import online blog         10.1.1.54      # blog.udance.com.au
import online test         10.1.1.50      # test.udance.com.au
import online basil        10.1.1.56      # basil.udance.com.au
import online sachika      10.1.1.57      # sachika.udance.com.au

To avoid cluttering the above extract, I’ve not included the snippets. For completeness, I’ve included them below.

(tlsdns) {
  tls {
    dns cloudflare [REDACTED]
  }
}

(authproxy) {
  basicauth {args.0} {
    admin [REDACTED]
  }
}

(logging) {
  log {
    format json
    output file /var/log/caddy/{args.0}.log {
      roll_keep 7
    }
  }
}

(online) {
  {args.0}.udance.com.au {

    encode gzip
    import tlsdns
    import authproxy /phpmyadmin*
    import logging {args.0}

    reverse_proxy http://{args.1}
  }
}

3. The problem I’m having:

So, this is my first attempt at redesigning that section of the Caddyfile to use a wildcard certificate.

*.udance.com.au {
  map {hostname} {ipaddress} {
    rslsync      10.1.1.22:8888 # Resilio Sync
    cloud        10.1.1.29      # Nextcloud 
    heimdall     10.1.1.23      # Heimdall 
    blog         10.1.1.54      # blog.udance.com.au
    test         10.1.1.50      # test.udance.com.au
    basil        10.1.1.56      # basil.udance.com.au
    sachika      10.1.1.57      # sachika.udance.com.au    
  }    

  encode gzip
  import tlsdns
  import authproxy /phpmyadmin*
  import logging {hostname}

  reverse_proxy http://{ipaddress}
}

Queries:

  1. Can you please let me know if I’m I on the right track with the wildcard caddy block map directive? Once I get it right, I believe I can remove the online snippet.
  2. I’ve left the Caddy block containing the domain udance.com.au intact as I assume the wildcard certificate only applies to its subdomains. What’s not clear to me is whether it makes sense to treat the www subdomain differently or leave it as is?
  3. I’m on Caddy 2.3.0 and not the 2.4.0 beta as I’m using Caddy in a production environment. This means I’m restricted to using the tls directive rather than the acme_dns directive, which I understand was introduced with 2.4.0. If and when I do migrate to 2.4.0, do I just add the acme_dns directive to the global section of the Caddyfile and then remove references to the tlsdns snippet in the Caddy blocks?
  4. Is it possible to logically group the domain and its subdomains under a single Caddy block or do these need to be kept separate as I’ve done?

4. Error messages and/or full log output:

n/a

5. What I already tried:

I’ve studied the various links in the next section, but have not made any changes to my Caddyfile as I run several production services that could be unnecessarily disrupted. This is really just at the redesign phase at this stage.

6. Links to relevant resources:

  1. In post #6 of Relationship between rewrite, redir, respond and try_files?, @francislavoie made me aware of the map directive. This led me to wonder whether I could use it with wildcard certificate and subdomains.
  2. The documented map directive.
  3. In post #2 of Utilizing Wildcard Certificate for Subdomains, @francislavoie suggests an interesting solution.
  4. @matt’s wiki article Serving tens of thousands of domains over HTTPS with Caddy confirmed for me that I could use the map directive in the way I had assumed would be possible.
2 Likes

I don’t think map is optimal here because it involves placeholders for the proxy upstreams. There’s some things that aren’t possible when the reverse_proxy handler needs to resolve its upstream addresses from placeholders.

I’d suggest doing it with a snippet with args and handle blocks. This would be more optimal because the JSON config output by the adapter will directly reference the domains due to {args.*} being replaced at adapt time instead of at runtime. Something like this:

(subdomain) {
	@sub-{args.0} host {args.0}.udance.com.au
	handle @sub-{args.0} {
		reverse_proxy http://{args.1}
	}
}

*.udance.com.au {
	encode gzip 
	import tlsdns
	import authproxy /phpmyadmin*
	import logging udance

	import subdomain rslsync      10.1.1.22:8888 # Resilio Sync
	import subdomain cloud        10.1.1.29      # Nextcloud 
	import subdomain heimdall     10.1.1.23      # Heimdall 
	import subdomain blog         10.1.1.54      # blog.udance.com.au
	import subdomain test         10.1.1.50      # test.udance.com.au
	import subdomain basil        10.1.1.56      # basil.udance.com.au
	import subdomain sachika      10.1.1.57      # sachika.udance.com.au

	handle {
		# Fallback for any subdomain not otherwise handled
	}
}

A couple things to note, it’s not possible to have more than one log per site block in the Caddyfile unfortunately, so you can’t split your logs into multiple files when using this pattern. This is a limitation of the Caddyfile adapter at the moment.

In your map approach, you used {hostname} but this wouldn’t work as-is because that would give you the full hostname, not just the subdomain. You would need to use {labels.3} to get the actual subdomain (i.e the 0 indexed 4th host label, starting from the right).

You’ll probably want to move www.dance.com.au into the same site block if you want it to use the wildcard cert. You can do this with another handle block similarly to the snippet above. You can do the same with the main domain as well, like *.example.com, example.com, with another handle for the main one as well.

Yeah. You might not need to do that though since you’ll only have tls defined once if you use a single site block with handle blocks.

Answered :wink:

What might those be? From what I can see, his config is pretty elegant.

What’s interesting is that @matt uses the map directive for wildcard subdomains in the wiki article Serving tens of thousands of domains over HTTPS with Caddy and doesn’t use the handle block. Is there a subtle difference that I’m not understanding between the two approaches?

Noted.

OK. I see what I’ve done wrong.

Noted.

Noted.

I’m talking about our “due to parsing difficulties” error:

$ cat Caddyfile
:80

map {hostname} {ip} {
	foo.example.com 1.2.3.4
	bar.example.com 2.3.4.5:8080
	default 4.5.6.7
}

reverse_proxy http://{ip}


$ ./caddy adapt --pretty
2021/03/02 15:17:11.650	INFO	using adjacent Caddyfile
adapt: parsing caddyfile tokens for 'reverse_proxy': Caddyfile:9 - Error during parsing: due to parsing difficulties, placeholders are not allowed when an upstream address contains a scheme

You would need to explicitly define the port for each entry in the map to :80 and then omit http://.

So, if I combine some of the advice I’ve now received, here’s my next design iteration:.

*.udance.com.au {
  map {labels.3} {ip} {
    rslsync      10.1.1.22:8888    # Resilio Sync
    cloud        10.1.1.29:80      # Nextcloud 
    heimdall     10.1.1.23:80      # Heimdall 
    blog         10.1.1.54:80      # blog.udance.com.au
    test         10.1.1.50:80      # test.udance.com.au
    basil        10.1.1.56:80      # basil.udance.com.au
    sachika      10.1.1.57:80      # sachika.udance.com.au
    www          10.1.1.55:80      # www.udance.com.au   
  }    

  encode gzip
  import tlsdns
  import authproxy /phpmyadmin*
  import logging udance

  reverse_proxy {ip}
}

Queries:

  1. I’m not clear on how I might use the map default switch? Is it a case of sending it to a site that says ‘No such domain’, or just leave it out altogether and just let the browser work it out?
  2. A variation on the previous query…if there is no labels.3, would it then use the default switch? e.g.
*.udance.com.au, udance.com.au {
  map {labels.3} {ip} {
    ...
   default 10.1.1.55:80 # udance.com.au
  }
  1. In this version, I move the www subdomain out of the individual certificate domain block and into the wildcard certificate subdomain block. However, it’s not clear to me how to treat the subdirectories that are in the domain block that are also associated with the www subdomain. Would something like the following work? If so, I’d include it just before the last closing parenthesis in the previous Caddy block.
  @subdir {
    host www.udance.com.au
  }
 
  handle @subdir {
    reverse_proxy /tautulli* http://10.1.1.26:8181
    reverse_proxy /transmission* http://10.1.1.28:9091
  }

I wonder if we could be smarter about that… not really sure how to do it yet.

This is sorta why I suggest the handle approach, because that way you have a very obvious place to implement fallback logic. With map, that’s less simple, but you can do it with an expression matcher I guess:

map {labels.3} {ip} {
	...
	default default
}

@default expression `{ip} == "default"`
handle @default {
	# Some fallback behaviour
}

reverse_proxy {ip}

I’d probably use {upstream} instead of {ip} btw, bit more explanatory of a name, cause “ip” could be the client IP or something.

Yeah I think so, cause {labels.3} will be an empty string I believe, so it’ll fall through to your default.

Yeah that would probably work. Can shorten your matcher to:

@www host www.udance.com.au
handle @www {
	...
}

Okay, that gives me the confidence to progress to the next step of the redesign and, hopefully, the final piece of the puzzle. Let’s now say I want to have the treatment of a domain and its subdomains dealt with under a single Caddy block. The reason I might want to do that is to better associate blocks for different domains I might manage. So using the udance domain example again:

*.udance.com.au, udance.com.au {
  map {labels.3} {ip} {
    rslsync      10.1.1.22:8888    # Resilio Sync
    cloud        10.1.1.29:80      # Nextcloud 
    heimdall     10.1.1.23:80      # Heimdall 
    blog         10.1.1.54:80      # blog.udance.com.au
    test         10.1.1.50:80      # test.udance.com.au
    basil        10.1.1.56:80      # basil.udance.com.au
    sachika      10.1.1.57:80      # sachika.udance.com.au
    www          10.1.1.55:80      # www.udance.com.au
    default      10.1.1.55:80      # udance.com.au   
  }    

  encode gzip
  import authproxy /phpmyadmin*
  import logging udance

  @subdomains host *.udance.com.au
  @udance host udance.com.au
  @www host www.udance.com.au

  handle @subdomains {
    import tlsdns # wildcard certificate
    handle @www {
      ... # subdomain treatment
  }
  handle @udance {
    import tlsdns # individual certificate
    ...  # subdomain treatment
  }
  reverse_proxy {ip}
}

Queries:

  1. I’m assuming because I’m dealing with an individual certificate for the domain, and a wildcard certificate for its subdomains, the tlsdns snippet cannot be outside the primary handle blocks?
  2. Does this seem reasonable?

The questions I now have to deal with is ‘Is it better to keep the domain block (including the www subdomain) and subdomain block separate? Have I made the Caddyfile clearer, or more ambiguous by merging the two?’ I’m going to have to reflect on that one.

Or do I accept that the domain and www subdomain share the same individual certificate, which would make things clearer as in…

  @subdomains host *.udance.com.au
  @udance host udance.com.au, www.udance.com.au

  handle @udance {
    import tlsdns # individual certificate
    ...  # subdomain treatment
  }

  handle @subdomains {
    import tlsdns # wildcard certificate
  }

Queries:

  1. I’m assuming the www subdomain would only be treated by the first handle block, but I’m not sure?

Yes, wildcards are sorted less specific so they go at the end.

Similarly to log, you can only have one tls per site. And you can’t have tls in a handle, it needs to be at the top-level of your site.

So does that mean that Caddy will automatically work out whether it needs to use a wildcard or individual certificate, or, that I can’t really treat a domain and its subdomains under a single Caddy block? No real issue if it’s the latter. I’ll just keep the single certificate domain+www and wildcard certificate subdomain blocks separate. I’m really just trying to see how far I can push the redesign of the Caddyfile.

I strongly recommend you run caddy adapt --pretty on your config after every change you make to see how it transforms the JSON.

Essentially, yes. It’ll use the most specific certificate that applies first, if there’s more than one that apply.

1 Like

I’m beginning to appreciate why this is an important step.

So, here’s the redesign on paper. I’ll report back tomorrow on how well the implementation went. Thanks, @francislavoie and @matt for your guidance tonight.

*.udance.com.au, udance.com.au {
  map {labels.3} {upstream} {
    rslsync      10.1.1.22:8888    # Resilio Sync
    cloud        10.1.1.29:80      # Nextcloud 
    heimdall     10.1.1.23:80      # Heimdall 
    blog         10.1.1.54:80      # blog.udance.com.au
    test         10.1.1.50:80      # test.udance.com.au
    basil        10.1.1.56:80      # basil.udance.com.au
    sachika      10.1.1.57:80      # sachika.udance.com.au
    www          10.1.1.55:80      # www.udance.com.au
    default      10.1.1.55:80      # udance.com.au   
  }    

  encode gzip
  import tlsdns
  import authproxy /phpmyadmin*
  import logging udance

  @udance host udance.com.au, www.udance.com.au

  handle @udance {
    ...  # subdir treatment
  }
  reverse_proxy {upstream}
}
2 Likes

So, I thought I’d approach the implementation in a piecemeal fashion as well. I ignored the domain+www block and concentrated on the wildcard subdomain block. This is what I added to the bottom of my Caddyfile. I also commented out the corresponding lines in the original extract.

*.udance.com.au {
  map {labels.3} {upstream} {
    rslsync      10.1.1.22:8888    # Resilio Sync
    cloud        10.1.1.29:80      # Nextcloud
    heimdall     10.1.1.23:80      # Heimdall
    blog         10.1.1.54:80      # blog.udance.com.au
    test         10.1.1.50:80      # test.udance.com.au
    basil        10.1.1.56:80      # basil.udance.com.au
    sachika      10.1.1.57:80      # sachika.udance.com.au
#    www          10.1.1.55:80      # www.udance.com.au
#    default      10.1.1.55:80      # udance.com.au
  }

  encode gzip
  import tlsdns
  import authproxy /phpmyadmin*
  import logging udance

  reverse_proxy {upstream}
}

Validating the Caddyfile revealed no errors.

root@caddy:/usr/local/www # service caddy validate
2021/03/03 04:59:58.034 INFO    using provided configuration    {"config_file": "/usr/local/www/Caddyfile", "config_adapter": "caddyfile"}
2021/03/03 04:59:58.041 INFO    tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc0002ce000"}
2021/03/03 04:59:58.041 INFO    http    server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS       {"server_name": "srv0", "https_port": 443}
2021/03/03 04:59:58.041 INFO    http    enabling automatic HTTP->HTTPS redirects        {"server_name": "srv0"}
2021/03/03 05:00:09.707 INFO    tls.cache.maintenance   stopped background certificate maintenance      {"cache": "0xc0002ce000"}
Valid configuration
root@caddy:/usr/local/www #

However, after a service caddy reload, when attempting to access one of the subdomains, say cloud.udance.com.au, I get a 502 error.

I check that the wildcard certificate was generated and that seems okay.

root@caddy:/ # ls -l /.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wild*
total 20
-rw-------  1 root  wheel  3157 Mar  3 12:20 wildcard_.udance.com.au.crt
-rw-------  1 root  wheel   154 Mar  3 12:20 wildcard_.udance.com.au.json
-rw-------  1 root  wheel   227 Mar  3 12:20 wildcard_.udance.com.au.key

However, when I check the Caddy log, I see something interesting…

root@caddy:/var/log # cat /var/log/caddy.log
{"level":"info","ts":1614748952.7792225,"msg":"using provided configuration","config_file":"/usr/local/www/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1614748952.7864382,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["127.0.0.1:2019","localhost:2019","[::1]:2019"]}
{"level":"info","ts":1614748952.7875009,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000376000"}
{"level":"info","ts":1614748952.7877486,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1614748952.787799,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1614748964.174874,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["tc123.udance.com.au","truecommand.udance.com.au","nc-apache.udance.com.au","caffigoalkeeping.com","www.caffigoalkeeping.com.au","portainer.udance.com.au","wordpress.udance.com.au","www.xenografix.com.au","nc-fpm.udance.com.au","www.udance.com.au","caffigoalkeeping.com.au","collabora.udance.com.au","udance.com.au","www.readymcgetty.com.au","readymcgetty.com.au","office.udance.com.au","*.udance.com.au","xenografix.com.au","www.caffigoalkeeping.com"]}
{"level":"info","ts":1614748964.1869757,"logger":"tls","msg":"cleaned up storage units"}
{"level":"info","ts":1614748964.192141,"msg":"autosaved config","file":"/.config/caddy/autosave.json"}
{"level":"info","ts":1614748964.1921597,"msg":"serving initial configuration"}
Successfully started Caddy (pid=60618) - Caddy is running in the background
{"level":"error","ts":1614748992.9612057,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"10.1.1.113:39484","proto":"HTTP/2.0","method":"PROPFIND","host":"cloud.udance.com.au","uri":"/remote.php/dav/calendars/basil/personal/","headers":{"Content-Length":["265"],"User-Agent":["DAVx5/3.3.9-ose (2021/02/28; dav4jvm; okhttp/4.9.1) Android/11"],"Accept-Language":["en-AU, en;q=0.7, *;q=0.5"],"Authorization":["Basic YmFzaWxpY2EgaXgKOmN2aWc="],"Depth":["0"],"Accept-Encoding":["br,gzip"],"Content-Type":["application/xml; charset=utf-8"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000133454,"status":502,"err_id":"kxkbpin1f","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749065.5240397,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.50:54858","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/dashboard/","headers":{"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Connection":["Keep-Alive"],"Cf-Ipcountry":["AU"],"Cf-Ray":["62a0703ab886df95-MEL"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"],"Accept-Encoding":["gzip"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Cookie":["tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cf-Request-Id":["08982478b70000df9555ab3000000001"],"Accept-Language":["en-au"],"Cdn-Loop":["cloudflare"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000065856,"status":502,"err_id":"09h4jmn7d","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.525788,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.50:55610","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/core/preview?fileId=331091&x=32&y=32","headers":{"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cdn-Loop":["cloudflare"],"Connection":["Keep-Alive"],"Accept-Encoding":["gzip"],"Cf-Ray":["62a070410fd0df95-MEL"],"Cf-Ipcountry":["AU"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cf-Request-Id":["0898247ca50000df95798cd000000001"],"X-Forwarded-Proto":["https"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Language":["en-au"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000060729,"status":502,"err_id":"3p1tmsbsk","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5266666,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.50:55608","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/avatar/barry/32?v=2","headers":{"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cf-Ray":["62a070410fcadf95-MEL"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Connection":["Keep-Alive"],"Accept-Encoding":["gzip"],"Cf-Request-Id":["0898247ca40000df9573849000000001"],"Accept-Language":["en-au"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cdn-Loop":["cloudflare"],"Cf-Ipcountry":["AU"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.0000586,"status":502,"err_id":"vu12ie2vd","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5291593,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.226:28138","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/user_status/img/user-status-online.svg","headers":{"Cf-Ray":["62a070410fcedf95-MEL"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Cdn-Loop":["cloudflare"],"Connection":["Keep-Alive"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Cf-Ipcountry":["AU"],"Accept-Language":["en-au"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cf-Request-Id":["0898247ca50000df95528ce000000001"],"Accept-Encoding":["gzip"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-Proto":["https"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000039093,"status":502,"err_id":"ks5wrgxjn","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5303893,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.14:30270","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/theming/img/core/filetypes/file.svg?v=0","headers":{"Accept-Encoding":["gzip"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cdn-Loop":["cloudflare"],"Cf-Ipcountry":["AU"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-Proto":["https"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Accept-Language":["en-au"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Connection":["Keep-Alive"],"Cf-Ray":["62a070410fccdf95-MEL"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Cf-Request-Id":["0898247ca70000df958c853000000001"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000032378,"status":502,"err_id":"ta1xhby4f","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5310187,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.194:44098","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/theming/img/core/filetypes/image.svg?v=0","headers":{"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Cf-Request-Id":["0898247ca40000df95a10ad000000001"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"X-Forwarded-Proto":["https"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Encoding":["gzip"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Accept-Language":["en-au"],"Cf-Ray":["62a070410fc8df95-MEL"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cdn-Loop":["cloudflare"],"Connection":["Keep-Alive"],"Cf-Ipcountry":["AU"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000036073,"status":502,"err_id":"qc0fewg3a","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5321314,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.198:51996","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/dashboard/img/kamil-porembinski-clouds.jpg","headers":{"Cdn-Loop":["cloudflare"],"Connection":["Keep-Alive"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Accept-Language":["en-au"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Accept-Encoding":["gzip"],"X-Forwarded-Proto":["https"],"Cf-Request-Id":["0898247ca60000df955c399000000001"],"Cf-Ray":["62a070410fd3df95-MEL"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Accept":["image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Cf-Ipcountry":["AU"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.00003569,"status":502,"err_id":"ewuw7762e","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.5328748,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.224:43012","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/files_rightclick/css/app.css?v=46c85d58-0","headers":{"Accept":["text/css,*/*;q=0.1"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Accept-Encoding":["gzip"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cf-Request-Id":["0898247ca70000df95b314f000000001"],"X-Forwarded-Proto":["https"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0703ab886df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cdn-Loop":["cloudflare"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cf-Ray":["62a070410fc6df95-MEL"],"Accept-Language":["en-au"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Connection":["Keep-Alive"],"Cf-Ipcountry":["AU"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000031287,"status":502,"err_id":"8vjsma683","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749066.7449393,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.224:43186","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apple-touch-icon-precomposed.png","headers":{"Connection":["Keep-Alive"],"Cookie":["__cfduid=daa7c891a8e0ed5fd846e78f270fd6ae41614596871"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cf-Ray":["62a070426bdb3778-MEL"],"Accept":["*/*"],"Accept-Language":["en-au"],"Accept-Encoding":["gzip"],"Cf-Ipcountry":["AU"],"User-Agent":["Safari/15610.4.3.1.6 CFNetwork/1128.0.2 Darwin/19.6.0 (x86_64)"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cdn-Loop":["cloudflare"],"Cf-Request-Id":["0898247d8100003778d4a36000000001"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000037372,"status":502,"err_id":"naczega7u","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749099.467625,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.50:24742","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/dashboard/","headers":{"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"X-Forwarded-Proto":["https"],"Accept-Language":["en-au"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Accept-Encoding":["gzip"],"Cf-Ipcountry":["AU"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Cf-Request-Id":["089824fd4e0000df9552861000000001"],"Connection":["Keep-Alive"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cookie":["cf_use_ob=0; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cdn-Loop":["cloudflare"],"Cf-Ray":["62a0710eec03df95-MEL"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000077323,"status":502,"err_id":"bv65gg1x2","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749119.89252,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"162.158.2.50:39814","proto":"HTTP/1.1","method":"GET","host":"cloud.udance.com.au","uri":"/apps/dashboard/","headers":{"Cf-Ray":["62a0718e9c08df95-MEL"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"],"Accept-Language":["en-au"],"Cf-Connecting-Ip":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"],"Cdn-Loop":["cloudflare"],"Accept-Encoding":["gzip"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"],"Connection":["Keep-Alive"],"X-Forwarded-Proto":["https"],"Cookie":["cf_use_ob=0; cf_ob_info=502:62a0710eec03df95:MEL; tk_lr=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_or=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; tk_r3d=%22https%3A%2F%2Fwww.caffigoalkeeping.com.au%22; nc_session_id=56jtq4atqqdj1bdavoasr38h35; nc_token=d%2BM%2BAjhBxoSh3p%2BDZk7kTpMkhaCkqx1J; nc_username=barry; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; __cfduid=d7e82a25af9097f3ed614a4db802bf4691614399683"],"Cf-Request-Id":["0898254d1d0000df9570035000000001"],"Cf-Ipcountry":["AU"],"X-Forwarded-For":["2001:44b8:6135:5200:a477:b3d7:5432:63b6"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000077582,"status":502,"err_id":"qx0jj0tu2","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749163.5411074,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.29:80:: address 10.1.1.29:80:: too many colons in address","request":{"remote_addr":"10.1.1.113:39514","proto":"HTTP/2.0","method":"PROPFIND","host":"cloud.udance.com.au","uri":"/remote.php/dav/calendars/basil/personal/","headers":{"Accept-Language":["en-AU, en;q=0.7, *;q=0.5"],"Authorization":["Basic YmFzaWxpY2EgaXgKOmN2aWc="],"Depth":["0"],"Accept-Encoding":["br,gzip"],"Content-Type":["application/xml; charset=utf-8"],"Content-Length":["265"],"User-Agent":["DAVx5/3.3.9-ose (2021/02/28; dav4jvm; okhttp/4.9.1) Android/11"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"cloud.udance.com.au"}},"duration":0.000102101,"status":502,"err_id":"nmfugrdts","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749215.7444136,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.54:80:: address 10.1.1.54:80:: too many colons in address","request":{"remote_addr":"108.162.219.44:27732","proto":"HTTP/1.1","method":"HEAD","host":"blog.udance.com.au","uri":"/","headers":{"User-Agent":["jetmon/1.0 (Jetpack Site Uptime Monitor by WordPress.com)"],"Cf-Connecting-Ip":["192.0.101.226"],"Cdn-Loop":["cloudflare"],"Cf-Request-Id":["089826c140000091aa6a372000000001"],"Connection":["Keep-Alive"],"Cf-Ipcountry":["US"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Accept-Encoding":["gzip"],"X-Forwarded-For":["192.0.101.226"],"Cf-Ray":["62a073e1fedc91aa-EWR"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"blog.udance.com.au"}},"duration":0.000065883,"status":502,"err_id":"d8czi0aac","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
{"level":"error","ts":1614749330.6632104,"logger":"http.log.error.log10","msg":"making dial info: upstream {upstream}:: invalid dial address 10.1.1.50:80:: address 10.1.1.50:80:: too many colons in address","request":{"remote_addr":"108.162.212.145:21372","proto":"HTTP/1.1","method":"HEAD","host":"test.udance.com.au","uri":"/","headers":{"Cf-Ray":["62a076b05b1c12ab-MIA"],"X-Forwarded-Proto":["https"],"User-Agent":["jetmon/1.0 (Jetpack Site Uptime Monitor by WordPress.com)"],"Cdn-Loop":["cloudflare"],"Cf-Request-Id":["0898288233000012abf6a84000000001"],"Accept-Encoding":["gzip"],"Cf-Ipcountry":["US"],"X-Forwarded-For":["192.0.91.177"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Cf-Connecting-Ip":["192.0.91.177"],"Connection":["Keep-Alive"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"test.udance.com.au"}},"duration":0.000084075,"status":502,"err_id":"kq4mavq3a","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}
root@caddy:/var/log #

There are messages about ‘too many colons in address’. Help!

For the moment, I’ve rolled back to the original Caddyfile.

Here’s another thread with a somewhat similar issue Dial error when using placeholder as proxy target

Which version of Caddy are you using? I believe that’s been fixed on the master branch. Also, what does your caddy adapt output look like? Are the extra :: in the JSON config?

2.3.0. Does rebuilding Caddy with the master update me to the 2.4.0 beta?

Not that I can see.

                                                                                                                {
                                                                                                                        "input": "cloud",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.29:80"
                                                                                                                        ]
                                                                                                                },

The v2.4.0-beta.1 tag is older than master but you can try either one. Run xcaddy build master --with ... or run xcaddy build v2.4.0-beta.1 --with ...

That’s for the map handler. What about the reverse_proxy handler? Do you see {upstream}:: there?

Not sure. There’s a single colon after {upstream}.

                                                {
                                                        "match": [
                                                                {
                                                                        "host": [
                                                                                "*.udance.com.au"
                                                                        ]
                                                                }
                                                        ],
                                                        "handle": [
                                                                {
                                                                        "handler": "subroute",
                                                                        "routes": [
                                                                                {
                                                                                        "handle": [
                                                                                                {
                                                                                                        "Defaults": null,
                                                                                                        "destinations": [
                                                                                                                "{upstream}"
                                                                                                        ],
                                                                                                        "handler": "map",
                                                                                                        "mappings": [
                                                                                                                {
                                                                                                                        "input": "rslsync",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.22:8888"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "cloud",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.29:80"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "heimdall",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.23:80"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "blog",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.54:80"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "test",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.50:80"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "basil",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.56:80"
                                                                                                                        ]
                                                                                                                },
                                                                                                                {
                                                                                                                        "input": "sachika",
                                                                                                                        "outputs": [
                                                                                                                                "10.1.1.57:80"
                                                                                                                        ]
                                                                                                                }
                                                                                                        ],
                                                                                                        "source": "{http.request.host.labels.3}"
                                                                                                }
                                                                                        ]
                                                                                },
                                                                                {
                                                                                        "handle": [
                                                                                                {
                                                                                                        "handler": "authentication",
                                                                                                        "providers": {
                                                                                                                "http_basic": {
                                                                                                                        "accounts": [
                                                                                                                                {
                                                                                                                                     "password": "REDACTED",
                                                                                                                                     "username": "admin"
                                                                                                                                }
                                                                                                                        ],
                                                                                                                        "hash": {
                                                                                                                                "algorithm": "bcrypt"
                                                                                                                        },
                                                                                                                        "hash_cache": {}
                                                                                                                }
                                                                                                        }
                                                                                                }
                                                                                        ],
                                                                                        "match": [
                                                                                                {
                                                                                                        "path": [
                                                                                                                "/phpmyadmin*"
                                                                                                        ]
                                                                                                }
                                                                                        ]
                                                                                },
                                                                                {
                                                                                        "handle": [
                                                                                                {
                                                                                                        "encodings": {
                                                                                                                "gzip": {}
                                                                                                        },
                                                                                                        "handler": "encode"
                                                                                                },
                                                                                                {
                                                                                                        "handler": "reverse_proxy",
                                                                                                        "upstreams": [
                                                                                                                {
                                                                                                                        "dial": "{upstream}:"
                                                                                                                }
                                                                                                        ]
                                                                                                }
                                                                                        ]
                                                                                }
                                                                        ]
                                                                }
                                                        ],
                                                        "terminal": true
                                                }
                                        ],

I’m going to roll back and try again later when I have a block of free time.