Trouble With Internal Proxies

1. The problem I’m having:

I have been trying to stop managing (needing to remember) IPs for applications / services I am running locally. What has happened up until the last week or so is that I spin up an application in a Proxmox LXC and set a static IP for it in my router. Then, in my browser I just use the IP:PORT to get to the service. All of that works but whenever I reopen a browser and I am not restoring previous sessions, then I have to think about what IP and PORT the service is on so I can get back to it.

There was 2 options at that point, I could deploy a dashboard or I could look at using DNS. Given that I have some externally exposed services, I had Caddy and thus it seemed reasonable that I could use it to do something similar for the internal services.

First thing I did was ensure that Pi-Hole had the Conditional Forwarding turned on and pointed to my router and using the same domain “internal” as I used on my router.

Next, I entered a block in my Caddyfile following the same format as with external assets with the exception of the tls directive. For external facing, I use my Cloudflare account and the DNS Challenge. For the internal, I was using tls internal.

I started with sonarr and added the following block to my Caddyfile:

sonarr.internal {
  tls internal
  reverse_proxy sonarr.internal:8989
  log {
    output file /var/log/caddy/sonarr.log
    format json
    level DEBUG
  }
}

Didn’t work. At this point, I wasn’t sure if the IP was being found (DNS issues) so I started with PiHole and my router. After discussing with the PiHole community, it was indicated that DNS could be ruled out as the IP was being returned.

No logs are created either.

From my Caddy server, I ran a number of test using curl and dig.

curl -vL http://sonarr.internal
*   Trying 192.168.1.242:80...
* connect to 192.168.1.242 port 80 failed: Connection refused
* Failed to connect to sonarr.internal port 80 after 1 ms: Couldn't connect to server
* Closing connection 0
curl: (7) Failed to connect to sonarr.internal port 80 after 1 ms: Couldn't connect to server

I found it interesting (but maybe expected) that it was port 80 and the IP address is correct. So I ran the command again but this time added the expected 8989 for the port.

curl -vL http://sonarr.internal:8989
*   Trying 192.168.1.242:8989...
* Connected to sonarr.internal (192.168.1.242) port 8989 (#0)
> GET / HTTP/1.1
> Host: sonarr.internal:8989
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Length: 1952
< Content-Type: text/html
< Date: Tue, 20 Aug 2024 10:55:59 GMT
< Server: Kestrel
< Cache-Control: no-cache, no-store
< Expires: -1
< Pragma: no-cache
< 
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#3a3f51"/><meta name="msapplication-navbutton-color" content="#3a3f51"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><meta name="format-detection" content="telephone=no"><meta name="description" content="Sonarr"/><link rel="apple-touch-icon" sizes="180x180" href="/Content/Images/Icons/apple-touch-icon.png?h=d+iS4xWxn2A2bjUwrERmSg"/><link rel="icon" type="image/png" sizes="32x32" href="/Content/Images/Icons/favicon-32x32.png?h=s64FHSxrh1sgZCiBBIVikQ"/><link rel="icon" type="image/png" sizes="16x16" href="/Content/Images/Icons/favicon-16x16.png?h=wksVbPqhKGB2B5P0O0h8IQ"/><link rel="manifest" href="/Content/Images/Icons/manifest.json?h=cUPA5242uyihHp+0wPd35A" crossorigin="use-credentials"/><link rel="mask-icon" href="/Content/Images/Icons/safari-pinned-tab.svg?h=00yLx0v47nGMoh9FRbDFkg" color="#00ccff"/><link rel="shortcut icon" type="image/ico" href="/favicon.ico"/><meta name="msapplication-config" content="/Content/Images/Icons/browserconfig.xml"/><link rel="stylesheet" href="/Content/Fonts/fonts.css?h=zGLiHXGOeD2wslXPvUJgKA"><script>window.Sonarr = {
        urlBase: ''
      };</script><script src="/index-f922a4ce2468b041d6e4.js"></script><link href="/Content/styles.css?h=zd/NtvlL8ktbpoBZYtb1Yw" rel="stylesheet"><title>Sonarr</title><style>.root {
        overflow: hidden;
        height: 100%; /* needed for proper layout */
      }

      @media only screen and (max-width: 768px) {
        .root {
          display: flex;
          flex-direction: column;
          min-height: 100%;
          height: auto;
        }
* Connection #0 to host sonarr.internal left intact
      }</style></head><body><div id="portal-root"></div><div id="root" class="root"></div></body></html>
dig sonarr.internal     

; <<>> DiG 9.18.24-1-Debian <<>> sonarr.internal
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21731
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;sonarr.internal.               IN      A

;; ANSWER SECTION:
sonarr.internal.        0       IN      A       192.168.1.242

;; Query time: 1 msec
;; SERVER: 192.168.1.233#53(192.168.1.233) (UDP)
;; WHEN: Tue Aug 20 11:06:59 UTC 2024
;; MSG SIZE  rcvd: 60

2. Error messages and/or full log output:

Generally speaking, there are no error messages / logs.

journalctl

Aug 19 13:03:07 caddy systemd[1]: Starting caddy.service - Caddy...
Aug 19 13:03:07 caddy caddy[30053]: caddy.HomeDir=/var/lib/caddy
Aug 19 13:03:07 caddy caddy[30053]: caddy.AppDataDir=/var/lib/caddy/.local/share/caddy
Aug 19 13:03:07 caddy caddy[30053]: caddy.AppConfigDir=/var/lib/caddy/.config/caddy
Aug 19 13:03:07 caddy caddy[30053]: caddy.ConfigAutosavePath=/var/lib/caddy/.config/caddy/autosave.json
Aug 19 13:03:07 caddy caddy[30053]: caddy.Version=v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=
Aug 19 13:03:07 caddy caddy[30053]: runtime.GOOS=linux
Aug 19 13:03:07 caddy caddy[30053]: runtime.GOARCH=amd64
Aug 19 13:03:07 caddy caddy[30053]: runtime.Compiler=gc
Aug 19 13:03:07 caddy caddy[30053]: runtime.NumCPU=1
Aug 19 13:03:07 caddy caddy[30053]: runtime.GOMAXPROCS=1
Aug 19 13:03:07 caddy caddy[30053]: runtime.Version=go1.22.1
Aug 19 13:03:07 caddy caddy[30053]: os.Getwd=/
Aug 19 13:03:07 caddy caddy[30053]: LANG=C
Aug 19 13:03:07 caddy caddy[30053]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Aug 19 13:03:07 caddy caddy[30053]: NOTIFY_SOCKET=/run/systemd/notify
Aug 19 13:03:07 caddy caddy[30053]: HOME=/var/lib/caddy
Aug 19 13:03:07 caddy caddy[30053]: LOGNAME=caddy
Aug 19 13:03:07 caddy caddy[30053]: USER=caddy
Aug 19 13:03:07 caddy caddy[30053]: INVOCATION_ID=f7645ad4e1f34ea493d10d6e16c2cc27
Aug 19 13:03:07 caddy caddy[30053]: JOURNAL_STREAM=8:197702557
Aug 19 13:03:07 caddy caddy[30053]: SYSTEMD_EXEC_PID=30053
Aug 19 13:03:07 caddy caddy[30053]: {"level":"info","ts":1724072587.0775619,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Aug 19 13:03:07 caddy caddy[30053]: {"level":"info","ts":1724072587.0795665,"msg":"adapted config to JSON","adapter":"caddyfile"}
Aug 19 13:03:07 caddy caddy[30053]: {"level":"warn","ts":1724072587.0795727,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' t
o fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":50}
Aug 19 13:03:07 caddy caddy[30053]: {"level":"info","ts":1724072587.0806556,"msg":"redirected default logger","from":"stderr","to":"/var/log/caddy
/debug.log"}
Aug 19 13:03:07 caddy caddy[30053]: {"level":"info","ts":1724072587.0818315,"msg":"failed to sufficiently increase receive buffer size (was: 208 k
iB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
Aug 19 13:03:07 caddy systemd[1]: Started caddy.service - Caddy.
Aug 20 10:51:21 caddy systemd[1]: Stopping caddy.service - Caddy...
Aug 20 10:51:21 caddy systemd[1]: caddy.service: Deactivated successfully.
Aug 20 10:51:21 caddy systemd[1]: Stopped caddy.service - Caddy.
Aug 20 10:51:21 caddy systemd[1]: caddy.service: Consumed 15.173s CPU time.
Aug 20 10:51:21 caddy systemd[1]: Starting caddy.service - Caddy...
Aug 20 10:51:22 caddy caddy[38710]: caddy.HomeDir=/var/lib/caddy
Aug 20 10:51:22 caddy caddy[38710]: caddy.AppDataDir=/var/lib/caddy/.local/share/caddy
Aug 20 10:51:22 caddy caddy[38710]: caddy.AppConfigDir=/var/lib/caddy/.config/caddy
Aug 20 10:51:22 caddy caddy[38710]: caddy.ConfigAutosavePath=/var/lib/caddy/.config/caddy/autosave.json
Aug 20 10:51:22 caddy caddy[38710]: caddy.Version=v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=
Aug 20 10:51:22 caddy caddy[38710]: runtime.GOOS=linux
Aug 20 10:51:22 caddy caddy[38710]: runtime.GOARCH=amd64
Aug 20 10:51:22 caddy caddy[38710]: runtime.Compiler=gc
Aug 20 10:51:22 caddy caddy[38710]: runtime.NumCPU=1
Aug 20 10:51:22 caddy caddy[38710]: runtime.GOMAXPROCS=1
Aug 20 10:51:22 caddy caddy[38710]: runtime.Version=go1.22.1
Aug 20 10:51:22 caddy caddy[38710]: os.Getwd=/
Aug 20 10:51:22 caddy caddy[38710]: LANG=C
Aug 20 10:51:22 caddy caddy[38710]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Aug 20 10:51:22 caddy caddy[38710]: NOTIFY_SOCKET=/run/systemd/notify
Aug 20 10:51:22 caddy caddy[38710]: HOME=/var/lib/caddy
Aug 20 10:51:22 caddy caddy[38710]: LOGNAME=caddy
Aug 20 10:51:22 caddy caddy[38710]: USER=caddy
Aug 20 10:51:22 caddy caddy[38710]: INVOCATION_ID=34db0359ed7a4e67b00a676acd864e7f
Aug 20 10:51:22 caddy caddy[38710]: JOURNAL_STREAM=8:203362687
Aug 20 10:51:22 caddy caddy[38710]: SYSTEMD_EXEC_PID=38710
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.032852,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.0342128,"msg":"adapted config to JSON","adapter":"caddyfile"}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"warn","ts":1724151082.0342188,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' t
o fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":48}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.0353272,"msg":"redirected default logger","from":"stderr","to":"/var/log/caddy
/debug.log"}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.037223,"msg":"warning: \"certutil\" is not available, install \"certutil\" wit
h \"apt install libnss3-tools\" or \"yum install nss-tools\" and try again"}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.0372734,"msg":"define JAVA_HOME environment variable to use the Java trust"}
Aug 20 10:51:22 caddy caddy[38710]: {"level":"info","ts":1724151082.0513105,"msg":"failed to sufficiently increase receive buffer size (was: 208 k
iB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
Aug 20 10:51:22 caddy systemd[1]: Started caddy.service - Caddy.

Note: I saw the comment about the format and ran the command as recommended.

Specific sonarr.log

cat /var/log/caddy/sonarr.log
cat: /var/log/caddy/sonarr.log: No such file or directory

Debug log

{"level":"warn","ts":1724151082.0654244,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [sonarr.internal]: no OCSP server specified in certificate","identifiers":["sonarr.internal"]}
{"level":"debug","ts":1724151082.065438,"logger":"tls.cache","msg":"added certificate to cache","subjects":["sonarr.internal"],"expiration":1724046172,"managed":true,"issuer_key":"local","hash":"3aebe1f542d632077320a4e2f6e7745841ae98b65da1ebfc56794e213e583c17","cache_size":12,"cache_capacity":10000}
{"level":"debug","ts":1724151082.0654519,"logger":"events","msg":"event","name":"cached_managed_cert","id":"835026c5-3ce6-4179-bd6d-4b10d82a15e5","origin":"tls","data":{"sans":["sonarr.internal"]}}
{"level":"info","ts":1724151082.0675695,"logger":"tls","msg":"certificate is in configured renewal window based on expiration date","subjects":["sonarr.internal"],"expiration":1724046172,"ari_cert_id":"","next_ari_update":null,"renew_check_interval":600,"window_start":-6795364578.8713455,"window_end":-6795364578.8713455,"remaining":-104910.067569193}
{"level":"info","ts":1724151082.0677338,"logger":"tls.renew","msg":"acquiring lock","identifier":"sonarr.internal"}
{"level":"info","ts":1724151082.068569,"logger":"tls.renew","msg":"lock acquired","identifier":"sonarr.internal"}
{"level":"info","ts":1724151082.0687044,"logger":"tls.renew","msg":"renewing certificate","identifier":"sonarr.internal","remaining":-104910.068702798}
{"level":"debug","ts":1724151082.0687244,"logger":"events","msg":"event","name":"cert_obtaining","id":"792ba694-aede-4844-9992-a85131e2341b","origin":"tls","data":{"forced":false,"identifier":"sonarr.internal","issuer":"local","remaining":-104910068702798,"renewal":true}}
{"level":"info","ts":1724151082.0693057,"logger":"tls.renew","msg":"certificate renewed successfully","identifier":"sonarr.internal","issuer":"local"}
{"level":"debug","ts":1724151082.0693412,"logger":"events","msg":"event","name":"cert_obtained","id":"04ba4596-d6e5-434c-894a-73875041b05a","origin":"tls","data":{"certificate_path":"certificates/local/sonarr.internal/sonarr.internal.crt","csr_pem":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlIcE1JR1BBZ0VBTUFBd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFRS3llcllRQkdyUEM5TQpTTVdRSzdUQ0dXUjh4TUIydUtTbzdIcWJLTVcwTW1TVmVxb0U4RElYNmNrMUt3WjZMbTlsdFBiMllCazRnN3hzCnpJc2JySklTb0Mwd0t3WUpLb1pJaHZjTkFRa09NUjR3SERBYUJnTlZIUkVFRXpBUmdnOXpiMjVoY25JdWFXNTAKWlhKdVlXd3dDZ1lJS29aSXpqMEVBd0lEU1FBd1JnSWhBTjV1VVROZkRvVUl1WVdwNUd0ZU5TM2RNOEdBc1RpVAoySDFsYzRjUlljTkJBaUVBelptYi9RQzk5aGFFMlhjd0g3ejEyNmt0cEtBT2lJV2drWUVoRXdzVHVwUT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==","identifier":"sonarr.internal","issuer":"local","metadata_path":"certificates/local/sonarr.internal/sonarr.internal.json","private_key_path":"certificates/local/sonarr.internal/sonarr.internal.key","remaining":-104910068702798,"renewal":true,"storage_path":"certificates/local/sonarr.internal"}}
{"level":"info","ts":1724151082.0693502,"logger":"tls.renew","msg":"releasing lock","identifier":"sonarr.internal"}
{"level":"info","ts":1724151082.0693958,"logger":"tls","msg":"reloading managed certificate","identifiers":["sonarr.internal"]}
{"level":"warn","ts":1724151082.0695336,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [sonarr.internal]: no OCSP server specified in certificate","identifiers":["sonarr.internal"]}
{"level":"debug","ts":1724151082.0695467,"logger":"tls.cache","msg":"removed certificate from cache","subjects":["sonarr.internal"],"expiration":1724046172,"managed":true,"issuer_key":"local","hash":"3aebe1f542d632077320a4e2f6e7745841ae98b65da1ebfc56794e213e583c17","cache_size":11,"cache_capacity":10000}
{"level":"debug","ts":1724151082.0695555,"logger":"tls.cache","msg":"added certificate to cache","subjects":["sonarr.internal"],"expiration":1724194283,"managed":true,"issuer_key":"local","hash":"74619680d61fe6506820b62c5fc05696a89ba6167e746e84f348692958351f1d","cache_size":12,"cache_capacity":10000}
{"level":"info","ts":1724151082.0695624,"logger":"tls.cache","msg":"replaced certificate in cache","subjects":["sonarr.internal"],"new_expiration":1724194283}

I attempted to install the certificate on my Mac, but I get an error -26276 indicating that the certificate is not valid.

When I go to http://sonarr.internal in the browser, I just get a can’t connect.

I then used Postman and did a GET

GET http://sonarr.internal/
Error: connect ECONNREFUSED 192.168.1.242:80
Request Headers
User-Agent: PostmanRuntime/7.30.0
Accept: */*
Postman-Token: 9e27d16c-b4fc-4fe0-8765-0198f4f4a46c
Host: sonarr.internal
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Again, I added the PORT

GET http://sonarr.internal:8989/
200
11 ms
Network
addresses: {…}
local: {…}
address: "192.168.1.2"
family: "IPv4"
port: 49497
remote: {…}
address: "192.168.1.242"
family: "IPv4"
port: 8989
Request Headers
User-Agent: PostmanRuntime/7.30.0
Accept: */*
Postman-Token: 2d3dd1b5-09b9-4aa6-92da-4cebfcac6789
Host: sonarr.internal:8989
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Response Headers
Content-Type: text/html
Date: Tue, 20 Aug 2024 11:02:08 GMT
Server: Kestrel
Cache-Control: no-cache, no-store
Content-Encoding: br
Expires: -1
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Accept-Encoding
Response Body
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#3a3f51"/><meta name="msapplication-navbutton-color" content="#3a3f51"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><meta name="format-detection" content="telephone=no"><meta name="description" content="Sonarr"/><link rel="apple-touch-icon" sizes="180x180" href="/Content/Images/Icons/apple-touch-icon.png?h=d+iS4xWxn2A2bjUwrERmSg"/><link rel="icon" type="image/png" sizes="32x32" href="/Content/Images/Icons/favicon-32x32.png?h=s64FHSxrh1sgZCiBBIVikQ"/><link rel="icon" type="image/png" sizes="16x16" href="/Content/Images/Icons/favicon-16x16.png?h=wksVbPqhKGB2B5P0O0h8IQ"/><link rel="manifest" href="/Content/Images/Icons/manifest.json?h=cUPA5242uyihHp+0wPd35A" crossorigin="use-credentials"/><link rel="mask-icon" href="/Content/Images/Icons/safari-pinned-tab.svg?h=00yLx0v47nGMoh9FRbDFkg" color="#00ccff"/><link rel="shortcut icon" type="image/ico" href="/favicon.ico"/><meta name="msapplication-config" content="/Content/Images/Icons/browserconfig.xml"/><link rel="stylesheet" href="/Content/Fonts/fonts.css?h=zGLiHXGOeD2wslXPvUJgKA"><script>window.Sonarr = {
        urlBase: ''
      };</script><script src="/index-f922a4ce2468b041d6e4.js"></script><link href="/Content/styles.css?h=zd/NtvlL8ktbpoBZYtb1Yw" rel="stylesheet"><title>Sonarr</title><style>.root {
        overflow: hidden;
        height: 100%; /* needed for proper layout */
      }

      @media only screen and (max-width: 768px) {
        .root {
          display: flex;
          flex-direction: column;
          min-height: 100%;
          height: auto;
        }
      }</style></head><body><div id="portal-root"></div><div id="root" class="root"></div></body></html>

3. Caddy version:

caddy version
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

Because I am using Cloudflare, I did the xcaddy following the following --with Cloudflare

https://caddyserver.com/docs/build#xcaddy

and when I am restarting

systemctl restart caddy

a. System environment:

Caddy is in a Debian 12 Proxmox LXC. PiHole and Unbound are on the same Proxmox node and are also in LXCs. Sonarr is also on the same Proxmox node.

b. Command:

systemctl restart caddy

While referring to the url in the help text, I saw section about Local HTTS (Keep Caddy Running — Caddy Documentation). I ran that command in the process of writing this post. I went back and checked to see if things changed, nothing did.

c. Service/unit/compose file:

.

d. My complete Caddy config:

I am really not comfortable pasting the entire Caddyfile when it contains entries for things that work. If that means I can't get help based on everything else, then that is fine.

5. Links to relevant resources:

The only other thing that I can think of that might be relevant is that I did attempt to use the IP address, but it didn’t work either.

sonarr.internal {
  tls internal
  reverse_proxy 192.168.1.242:8989
}

Howdy @wdpronovost,

I see that you’re listening for the site address sonarr.internal and reverse proxying to sonarr.internal.

We can see that sonarr.internal resolves to 192.168.1.242 inside your LAN, but the setup raises the question:

What IP addresses do the Caddy host and Sonar host have? Are they the same IP?

1 Like

No, everything has their own IPs. Caddy is on 192.168.1.234.

The thing they have in common however is that they are on the same Proxmox node.

Edit:
The reason for the setup was to avoid needing to enter the PORT as part of the address.

If Caddy is on 192.168.1.234, how could a client browse to sonarr.internal (which resolves to a different IP address 192.168.1.242) but still connect to Caddy?

It sounds to me like what you want is for sonarr.internal to resolve to the Caddy host 192.168.1.234. Then, Caddy reverse proxies to 192.168.1.242 on your behalf.

2 Likes

My total lack of understanding and difficulty comprehending all this “stuff”.

That said, your comment is making me think differently. Using Plex, which is exposed externally, I have my FQDN and when a request comes in, the router forwards to Caddy and Caddy forwards to the IP of Plex.

To me, what I was seeing was the Caddyfile and a config that was saying “when you see Plex, send it here” and that is what I was mimicking. “When you see sonarr, send it here” you’ve helped me realize I’m missing the caddy part.

This makes me think I need to use PiHole to get the request to caddy first. Or maybe I can do something in the router.

I appreciate this, let me see what I can take away and implement.

1 Like

You have definitely got me closer now! I am getting a white page and now my sonarr.log is populating.

{"level":"error","ts":1724203208.1829472,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"192.168.1.2","remote_port":"59789","client_ip":"192.168.1.2","proto":"HTTP/2.0","method":"GET","host":"sonarr.internal","uri":"/","headers":{"Sec-Fetch-Site":["none"],"Accept-Encoding":["gzip, deflate"],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Mode":["navigate"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15"],"Accept-Language":["en-US,en;q=0.9"],"Sec-Fetch-Dest":["document"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"sonarr.internal"}},"bytes_read":0,"user_id":"","duration":0.001242025,"size":0,"status":502,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"]}}

As you can see, I am getting the lovely 502 which I believe can be associated with the SSL.

Recap, here is my config for sonarr:

sonarr.internal {
        encode gzip
        tls internal
        log {
                output file /var/log/caddy/sonarr.log
                format json
                level DEBUG
        }
        reverse_proxy sonarr.internal:8989
# {
#               header_up X-Real-IP {http.request.remote}
#               header_up X-Forwarded-Port {http.request.port}
#               header_up X-Forwarded-Proto {http.request.scheme}
#               header_up X-Forwarded-Ssl {on}
#       }
}

Note: I was trying different things that I have seen on other threads / internal. I don’t really know what they do / mean but the log details are from the config above (those commented out).

I do have the “Caddy Local Authority - 2024 ECC Root”, the “Caddy Local Authority - ECC Intermediate”, and “sonarr.internal” certificates installed and they are indicated as valid.

Any other questions that might prompt me to consider something I have missed or overlooked?

1 Like

I’m guessing you’ve pointed the internal DNS for sonarr.internal at Caddy now?

If so, that means reverse_proxy sonarr.internal:8989 is probably trying to proxy to itself, which isn’t going to work, since there’s nothing on the Caddy host listening on port 8989.

To fix this now that sonarr.internal doesn’t point at the actual Sonarr host itself, you’ll need to replace it in your reverse_proxy directive with the actual IP address of Sonarr. Which, based on previous information, should look like:

reverse_proxy 192.168.1.242:8989

1 Like

Using the IP address prompts the certificate warning but will get me to the site, however, that is the setup I was trying to avoid.

My goal in this was to remove IP addresses from the equation so I didn’t need to manage them and could allow them to be dynamic if I wanted.

I did point sonarr.internal in PiHole Local DNS to the Caddy IP as that seems reasonable and similar to the router. Meaning, having to remember 1 IP for something that needs to remain static makes complete sense.

There is really no way to accomplish this without using IPs in Caddy? If not, then it probably just easier to static everything and use bookmarks. Just not as pretty!

If you don’t want to hard-code your IP address in the Caddy configuration, then the solution is DNS.

You’re using it already, to point sonarr.internal at Caddy. You just need to add another record, for internal purposes, that Caddy can use to find out where Sonarr actually is.

Something like sonarr-host.internal or sonarr-app.internal or whatever you like, really; point it at the Sonarr IP. Then you reverse_proxy to whatever hostname you picked.

Do the same for each service you want Caddy to reverse proxy; point servicename.internal at Caddy, and servicename-app.internal at the actual IP address of the service.

2 Likes

Once again, you got me thinking in a different way. I ended up making a change to the resolv.conf and pointed the nameserver at my router instead of pihole and that appears to have worked.

I really appreciate the discussion and assistance in getting me to think about this differently via your help.

I’ll update this once I am more confident it’s all working.

1 Like

@Whitestrake thank you again. I am confident this has solved my routing issues. I am having Certificate issues but I need to spend more time trying to better understand before asking for help and that would be a separate issue so I’ll create a new thread if I need help.

For those that might stumble across this, a summary of what worked for me: (Router providing DHCP, PiHole, Caddy)
Internal URLs pointed to Caddy’s IP via the Local DNS.
Caddy’s resolv.conf was updated to point to the routers IP so it can resolve the URL.

1 Like

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