Reverse proxy to Caddy application server

1. Caddy version (caddy version):

2.2.1

2. How I run Caddy:

Windows service

a. System environment:

Windows Server 2012

b. Command:

caddy run - config Caddyfile

d. My complete Caddyfile or JSON config:

  1. App server
(server) {
	root * D:/sites-enabled
	encode gzip
    
	# Proxy PHP files to the FastCGI responder
	@phpFiles {
		path *.php
	}
	
	@env {
		path_regexp env ^/(env_[\w]*)/jis/(.*)$
	}

	@api {
		path_regexp api ^/(env_[\w]*)/api/(.*)$
	}

	handle @api {
		root * D:/sites-enabled/{re.api.1}/api/public

    	php_fastcgi 127.0.0.1:9007 {
			env REQUEST_URI /{re.api.2}
		}

    	file_server
	}

	handle {
		route @env {
			try_files {path} /{http.regexp.env.1}/jis/{file} /{http.regexp.env.1}/jis/static/js/{file} /{http.regexp.env.1}/jis/static/css/{file} /{http.regexp.env.1}/jis/static/media/{file} /{http.regexp.env.1}/jis/index.html
		}
		reverse_proxy @phpFiles 127.0.0.1:9000 {
			transport fastcgi {
				split .php
			}
		}	
    	file_server
	}
}

http://localhost:8885,
http://185.5.38.114:8885 {
	import server
}
  1. Proxy Server
http://localhost:9993,
http://185.5.38.112:9993 {

    @envs4 {
        path */154/*
    }

    handle @envs4 {
       reverse_proxy 185.5.38.114:8885
    }
	
}

3. The problem I’m having:

What we are trying to achieve:

We have our App hosted on multiple servers and we are trying to make them accessible via a single URL.
Each App server has Caddy running with the first Caddyfile above.
No problem on that part we can access the application via the local network (185.5.38.114) and localhost.

Our Proxy server receives configuration of each App server in order to know to which server to proxy.
Both Caddy instances run on same physical server, that being said, the Proxy actually uses a JSON config (created by the adapt command line) in order to be able to disable the admin API on the proxy.

The problem:

When accessing from the proxy machine “localhost:9993/154/” the reverse proxy works perfectly well and redirects to “185.5.38.114:8885/154/”.
However when accessing “185.5.38.112:9993/154/” the reverse proxy doesn’t work as well. Caddy does respond but a blank page is returned instead of actually being served the contents of “185.5.38.114:8885/154/”.

4. Error messages and/or full log output:

Here are the logs of the application server (185.5.38.114:8885)
Via “localhost:9993/154/” (This one works):

{
  "level": "info",
  "ts": 1608202231.6015518,
  "logger": "http.log.access",
  "msg": "handled request",
  "request": {
    "remote_addr": "185.5.38.112:62892",
    "proto": "HTTP/1.1",
    "method": "GET",
    "host": "localhost:9993",
    "uri": "/154/",
    "headers": {
      "X-Forwarded-Proto": ["http"],
      "Accept-Language": ["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],
      "Cache-Control": ["max-age=0"],
      "X-Forwarded-For": ["::1"],
      "Accept-Encoding": ["gzip, deflate, br"],
      "Sec-Fetch-Dest": ["document"],
      "Sec-Fetch-Mode": ["navigate"],
      "Sec-Fetch-User": ["?1"],
      "Sec-Fetch-Site": ["none"],
      "User-Agent": [
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 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"
      ],
      "Upgrade-Insecure-Requests": ["1"]
    }
  },
  "common_log": "185.5.38.112 - - [17/Dec/2020:11:50:31 +0100] \"GET /154/ HTTP/1.1\" 200 1342",
  "duration": 0.0200196,
  "size": 1342,
  "status": 200,
  "resp_headers": {
    "Server": ["Caddy"],
    "Etag": ["\"qlg0ctb92\""],
    "Content-Type": ["text/xml; charset=utf-8"],
    "Last-Modified": ["Wed, 16 Dec 2020 17:24:29 GMT"],
    "Content-Encoding": ["gzip"],
    "Vary": ["Accept-Encoding"]
  }
}

Via “185.5.38.112:9993/154/” (Doesn’t work):

{
  "level": "info",
  "ts": 1608202134.4373214,
  "logger": "http.log.access",
  "msg": "handled request",
  "request": {
    "remote_addr": "185.5.38.112:62892",
    "proto": "HTTP/1.1",
    "method": "GET",
    "host": "172.31.99.53:9993",
    "uri": "/154/",
    "headers": {
      "X-Forwarded-Proto": ["http"],
      "Accept-Language": ["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],
      "Cache-Control": ["no-cache"],
      "X-Forwarded-For": ["172.31.99.53"],
      "Accept-Encoding": ["gzip, deflate"],
      "Pragma": ["no-cache"],
      "User-Agent": [
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 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"
      ],
      "Upgrade-Insecure-Requests": ["1"]
    }
  },
  "common_log": "185.5.38.112 - - [17/Dec/2020:11:48:54 +0100] \"GET /154/ HTTP/1.1\" 0 0",
  "duration": 0,
  "size": 0,
  "status": 0,
  "resp_headers": { "Server": ["Caddy"] }
}

5. What I already tried:

Changing the Proxy config to reverse proxy to an existing Apache on the App server (185.5.38.114:8881) works.
Configuring an Apache to proxy to the Caddy App server didn’t work.

Thanks in advance !

You can just use the admin off global option in the Caddyfile for this. No need to modify JSON.

{
	admin off
}

Be aware that turning off the admin API also makes it impossible to use caddy reload to gracefully reload Caddy on config changes. If you’re turning it off because of a port conflict, you can just change it to a different port instead, like admin localhost:2020 or whatever.

I would just change your site address to just :9993, to cover both.

The reason it doesn’t work is because Caddy is trying to match the Host header to 185.5.38.112, but the host is actually 172.31.99.53 as you can see in the log (i.e. request.host in the JSON)

If you just make your site address :9993, Caddy will respond to any request on port 9993 without checking the Host.

2 Likes

Thanks a lot !

For the admin directive I definitely missed that one out from the docs my bad.
Using :9993 as site address did solve the problem.

Cheers

1 Like

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