Reverse Proxy to internal service with port range

1. Caddy version (caddy version):

v2.3.0 (inside docker)

2. How I run Caddy:

I run caddy in a docker container with the relevant caddyfile configuration file. Then use docker-compose for minor changes.

a. System environment:

Ubuntu 20.04.2 LTS

b. Command:

Docker-compose up -d

c. Service/unit/compose file:

version: '3.8'

services:
  caddy:
    container_name: PROXY-CADDY
    restart: always
    ports:
      - 80:80
      - 443:443
    image: caddy:2.3.0
    volumes:
      - ./caddy/data:/data
      - ./caddy/config/Caddyfile:/etc/caddy/Caddyfile

d. My complete Caddyfile or JSON config:

domain.com.au  { 
        reverse_proxy 10.12.0.36:8001 10.12.0.36:8002 

        }

3. The problem I’m having:

I am unable to route multiple internal ports via 443 to a single service on ports 8001 and 8002 (both a required to function)

I am able to connect to the remote server using IP and tradition connection of 8001 and 8002, however this is unsecure. I would like to route communication over 443 HTTPS. via a seperate server handling all the proxy to a a single internal host.

4. Error messages and/or full log output:

No specific error messages, I can see via TCP viewer that a connection is being established when i route a single port only (10.12.0.36:8001) however i cannot seem to work out from Caddy documentation how to route a port range/multiple.

5. What I already tried:

As above, TCP viewer on both client and server side shows a single est connection. Is it possible to route all traffic matching a domain name over 433 to internally route any source port address to the internal server (could be anything) 8001-8005 as an example.

6. Links to relevant resources:

Reading over the documentation it does not seem to support this function or option is not available (forgive my limited networking experience on this)

Actually, this is supported. The reverse proxy docs link to this page, which shows the syntax:

This should work:

reverse_proxy 10.12.0.36:8001-8005
2 Likes

Thank you francisavoie! my mistake for missing that page.

I put in your suggestion, however it is now spitting out errors, saying the “dial address must represent precisely one socket”

PROXY-CADDY | {“level”:“error”,“ts”:1617055681.310346,“logger”:“http.log.error”,“msg”:“making dial info: upstream 10.12.0.36:8001-8005: dial address must represent precisely one socket: 10.12.0.36:8001-8005 represents 7”,“request”:{“remote_addr”:“117.x.x.x:19312”,“proto”:“HTTP/1.1”,“method”:“GET”,“host”:“domain.com.au”,“uri”:"/api/server/root-certificate-public-key",“headers”:{“X-Connectionguid”:[“2ed456e6-8156-4c58-be6f-e0580273a708”],“X-Auth”:[""],“Accept”:[“application/json”]},“tls”:{“resumed”:false,“version”:771,“cipher_suite”:49196,“proto”:"",“proto_mutual”:true,“server_name”:“domain.com.au”}},“duration”:0.000050938,“status”:502,“err_id”:“4ehsyrsy7”,“err_trace”:“reverseproxy.statusError (reverseproxy.go:783)”}

Any thoughts?

Appreciated.

Hmm, my bad then. In that case, you’ll have to do this:

reverse_proxy 10.12.0.36:8001 10.12.0.36:8002 10.12.0.36:8003 10.12.0.36:8004 10.12.0.36:8005
1 Like

Slight improvement!

However, now I am getting a “Connection Refused” message on a specific port.

PROXY-CADDY | {“level”:“error”,“ts”:1617058016.2914352,“logger”:“http.log.error”,“msg”:“dial tcp 10.12.0.36:8001: connect: connection refused”,“request”:{“remote_addr”:“117.x.x.x:50760”,“proto”:“HTTP/1.1”,“method”:“GET”,“host”:“domain.com.au”,“uri”:"/api/server/root-certificate-public-key",“headers”:{“X-Connectionguid”:[“b7e4086c-8b38-4b32-a4b6-b5d9560e13ef”],“X-Auth”:[""],“Accept”:[“application/json”]},“tls”:{“resumed”:false,“version”:771,“cipher_suite”:49196,“proto”:"",“proto_mutual”:true,“server_name”:“domain.com.au”}},“duration”:0.000960981,“status”:502,“err_id”:“h6iji5hn5”,“err_trace”:“reverseproxy.statusError (reverseproxy.go:783)”}

The firewall on the internal device is completely off (for testing) and the proxy server too. Not sure where exactly the connection is being refused. (Both machines are on private lan)

Appreciate any assistance (been fantastic so far)

Do you actually have a service listening on that port?

The specific ports are 8200 and 8206 (different from our 8001 discussion, but to keep it simple)

It seems, I can only get one TCP port connection at a time either 8200 is successful and 8206 is refused or vice versa…

Hi @francislavoie, tried doing some more troubleshooting and it seems my firewall (192.168.200.1) is intercepting the packets and dropping them (presumably)

Anything i can put in the configuration file to help get around this issue?
192.168.200.135 (Local machine)
192.168.200.203 (Server machine running service)
192.168.200.1 (Firewall) (Opnsense)

{“level”:“error”,“ts”:1617370780.5333998,“logger”:“http.log.error”,“msg”:“read tcp 192.168.200.135:57502->192.168.200.203:8206: read: connection reset by peer”,“request”:{“method”:“GET”,“uri”:"/api/server/root-certificate-public-key",“proto”:“HTTP/1.1”,“remote_addr”:“192.168.200.1:3246”,“host”:“domain.com”,“headers”:{“X-Auth”:[""],“Accept”:[“application/json”],“X-Connectionguid”:[“ec5f96-6a53-4430-ad5f-5816a72c6448”]},“tls”:{“resumed”:false,“version”:771,“ciphersuite”:49196,“proto”:"",“proto_mutual”:true,“server_name”:“domain.com”}},“duration”:0.000550915,“status”:502,“err_id”:“es2itsanc”,“err_trace”:“reverseproxy.(*Handler).ServeHTTP (reverseproxy.go:411)”}

I don’t know anything about that firewall, so there’s not much I can do to help.