Reverse Proxying for Services running on Proxmox Hypervisor

1. Caddy version:

v2.6.2

2. How I installed, and run Caddy:

a. System environment:

Proxmox, Debain LXC, Docker

b. Command:

Run it via docker-compose up -d

c. Service/unit/compose file:

version: '3'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      - WEBSOCKET_ENABLED=true # Enable WebSocket notifications.
      - ADMIN_TOKEN=...
      # - SIGNUPS_ALLOWED=false
      - DOMAIN=https://mine.duckdns.org
      # - SIGNUPS_ALLOWED=true
      # - SIGNUPS_VERIFY=true
      # - SIGNUPS_DOMAINS_WHITELIST=example.com,example.net,example.org
    volumes:
      - ./vw-data:/data

  caddy:
    image: caddy:2
    container_name: caddy
    restart: always
    ports:
      - 80:80  # Needed for the ACME HTTP-01 challenge.
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data
    environment:
      - DOMAIN=mine.duckdns.org  # Your domain.
      - EMAIL=mail@mine.de    # The email address to use for ACME registration.
      - LOG_FILE=/data/access.log

d. My complete Caddy config:

mine.duckdns.org:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  # Use the ACME HTTP-01 challenge to get a cert for the configured domain.
  tls mail@mine.de

  # alternative with custom certificate (place ca.crt and ca.key to ./caddy-config/ volume which is mounted on /config/
  # tls /config/ca.crt /config/ca.key

  # This setting may have compatibility issues with some browsers
  # (e.g., attachment downloading on Firefox). Try disabling this
  # if you encounter issues.
  encode gzip

  # Notifications redirected to the WebSocket server
  reverse_proxy /notifications/hub vaultwarden:3012

  # Proxy everything else to Rocket
  reverse_proxy vaultwarden:80 {
       # Send the true remote IP to Rocket, so that vaultwarden can put this in the
       # log, so that fail2ban can ban the correct IP.
       header_up X-Real-IP {remote_host}
  }
}

3. The problem I’m having:

I have an LXC Container on a proxmox hypervisor. On this LXC runs my Vaultwarden with I access from the Internet via this working Caddy config. Despite reading several hours here in the Forum and in the docs I don’t understand the caddyfile config fully :slight_smile:

What I want to achieve:
I have some other services running on differen LXCs or VMs on my Proxmox and I want them to be accessible over the Internet too. And I want to do this via this Caddy.

First question: I read that it could be easier if I run Caddy as a separate machine instead of running it in a docker conatiner in an LXC like I do it now. Is that the case?

I have a wireguard server on another LXC:
Internal IP is 192.168.0.27:5000
External address was mine.duckdns.org:51820 before i set up caddy

So how does the caddyfile has to be configured to get both services accessible. Vaultwarden runs as a dockercontainer on the same LXC as Caddy does. Read something about handles, but as far as I understand this is not possible with duckdns. But sub-subdomains should work? e.g. wireguard.mine.duckdns.org and vaultwarden.mine.duckdns.org?

Hope it’s clear what I want to know :smiley:

4. Error messages and/or full log output:

Paste logs/commands/output here.
USE THE PREVIEW PANE TO MAKE SURE IT LOOKS NICELY FORMATTED.

5. What I already tried:

6. Links to relevant resources:

It’s not necessarily easier or harder at all, from Caddy’s perspective.

I run Caddy in Docker almost exclusively; the most often use case I have for Caddy outside of a container is actually when testing and running configs from the forums here to help people troubleshoot.

You definitely want to take a look at the Caddyfile Concepts documentation to get started: https://caddyserver.com/docs/caddyfile/concepts#structure

Particularly, this infographic will be very helpful to demonstrate the structure you want:

If you observe your existing Caddyfile, you will find that your Vaultwarden reverse-proxy takes the form of a site block (like the bottom two sections, highlighted in blue).

Caddy makes it very easy to add additional sites by just writing additional site blocks.

In this case, all your other site needs is a site address and a reverse_proxy. Something like:

subdomain.example.com {
  reverse_proxy 192.168.0.27:5000
}

Would probably work just fine.

Apologies, but I’m not entirely sure what you mean by handles. If you’re referring to subfolders (e.g. mine.duckdns.org/vaultwarden/) then I would attempt to dissuade you from this as in the event of uncooperative upstream applications, things can get quite hairy. (I wrote a post about that class of issues, which I call The "subfolder problem", OR, "why can't I reverse proxy my app into a subfolder?")

Subdomains will work. Sub-subdomains I’m not entirely sure about; you’d have to ensure DuckDNS is cooperative. Some quick dig-ing indicates that they seem to have the behaviour that sub-subdomains point to the same IP as the subdomain, so you might just be gold to use wireguard.mine.duckdns.org and others in the same vein to distinguish your sites.

2 Likes

THANK YOU! I’ so glad 'bout your answer! Studied a lot and learned a lot more. As enthusiastic as i was I completely rewrote my caddyfile but caddy says it’s not properly formatted. Ran the fmt command, copied and pasted the output but no luck… And it doesn’t work anyway :frowning:

# Vaultwarden
vaultwarden.mine.duckdns.org {
        tls mail@mine.de
        encode gzip
        reverse_proxy localhost:80
}
# Wireguard
wireguard.mine.duckdns.org {
        tls mail@mine.de
        encode gzip
        reverse_proxy 192.168.0.27:5000
}

Just to be sure that I understand all correctly: All incoming requests using the 443 https port and caddy routes the requests in this case based on the subdomain to the correct port of the service in my network?

Thank you

1 Like

caddy fmt is picky about using tabs instead of spaces. If you copied it from your terminal, then you might have copied spaces, if your terminal program doesn’t let you copy tabs as tabs.

You’ll need to be more specific. In what way is it not working? What’s in your logs? What error do you see?

1 Like

Thank you. Thought about it again. Initially I wanted to group all exposed services at one point and thought that caddy is the best way. BUT realized that vpn isn’t a http service and in terms of security there is no advantage for me if I try to put the vpn service behind another “door”. So i let the wireguard-Port open in my router…

vaultwarden.mine.duckdns.org works now. But I cant access it when I’m in my local network via 192.168.0.29. Is there something missing in the config so I can access it locally too?

And the last question: In my first caddyfile template there is “Rocket” mentioned. Is this some kind of logger or sth.?

Thank you

“cant access” is, unfortunately, a vague description of a problem that could be a million other different kinds of problems. We could make guesses for days as to why you can’t access it.

Could you elaborate in more detail? What happens when you try? What specific result or error are you getting?

The only Rocket I can think of off the top of my head would be Rocket Chat. But this isn’t a question we’ll have a definitive answer for you - you’re better off asking whoever wrote that comment in your Caddyfile.

1 Like

Okay sorry, what further Information should I provide.
If I enter the IP: https://192.168.0.29, than I get a Safari cannot open Site… could not establish a safe connection.

That’s exactly the info we needed.

Okay, so you’re typing literally https://192.168.0.29 in a browser window.

Looking at your most recent Caddyfile, it looks like you haven’t actually configured it to serve the site address 192.168.0.29. Because Caddy isn’t configured for this address, it does not have a HTTPS certificate and can’t establish a HTTPS connection.

What website do you want Caddy to serve when you browse to https://192.168.0.29?

Okay, yes. Rationale is if Internet connection breaks down, I want to stillhave access to my vaultwarden instance. Caddy should serve https://192.168.0.29. The same service as it has to serve if i connect via the Internet URL.

# Vaultwarden
vaultwarden.mine.org:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  tls mail@mine.de
  encode gzip
  reverse_proxy /notifications/hub vaultwarden:3012
  reverse_proxy vaultwarden:80 {
       header_up X-Real-IP {remote_host}
  }
}
# Vaultwarden intern
192.168.0.29:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }
  tls mail@mine.de
  encode gzip
  reverse_proxy localhost:80
  }

Even with this configuration I get the same Error as before.

Another question:

reverse_proxy vaultwarden:80

Am I right, that the reverse proxy directive in this means that every request for this domain gets fowarded to the container “vaultwarden” and its port 80?

That’s unfortunate. Are you sure you reloaded Caddy with the new config? Just to clarify, I expected an error, but I was hoping for a different error.

When you try to connect to Caddy over HTTPS and request a site Caddy isn’t configured for, Caddy will refuse to provide any HTTPS certificate, which will cause an error that breaks HTTPS; no connection possible.

When you try to connect to Caddy over HTTPS for an IP address, and it’s been configured to serve that IP address over HTTPS, it should generate an internal certificate. This should produce a different kind of error indicating that the certificate is untrusted, and it should be possible to accept the risk and continue.

Could you try run this command and post the output: curl -v https://192.168.0.29

When you launch containers in the same Docker bridge network (which Compose does by default, putting all services in a project in the same network unless configured otherwise) then Docker provides domain name services, resolving service or container names to their internal container IP addresses.

So, yes - that means Caddy will do a DNS lookup for your vaultwarden service and then connect to that container on port 80 as its upstream for the reverse proxy.

Remember that containers are distinct hosts on their internal network, so reverse proxying to localhost is like telling Caddy to connect to itself, not to the Docker host machine (unless you have network_mode: host).

1 Like

Thank you for that precious input :slight_smile:

Changed my Caddyfile to:

# Vaultwarden
vaultwarden.mine.duckdns.org:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  tls mail@mine.de
  encode gzip
  reverse_proxy /notifications/hub vaultwarden:3012
  reverse_proxy vaultwarden:80 {
       header_up X-Real-IP {remote_host}
  }
}
# Vaultwarden intern
192.168.0.29:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }
  tls mail@mine.de
  encode gzip
  reverse_proxy vaultwarden:80
  }


Could you try run this command and post the output: curl -v https://192.168.0.29

of course:

*   Trying 192.168.0.29:443...
* Connected to 192.168.0.29 (192.168.0.29) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error
* Closing connection 0
curl: (35) error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error

Yeah, see, that particular error tells me Caddy’s not sending a certificate. That’s obviously not good.

Add the debug global option to your Caddyfile, start Caddy up, try to browse to the IP address again (or repeat the curl command), then bring Caddy back down. This time, I’d like to see the full Caddy log output, from startup to shutdown. I’d like to see what Caddy is reporting about its certificate selection logic.

https://caddyserver.com/docs/caddyfile/options#debug

Okay buckle up, hope this is what you asked for:

{"log":"{\"level\":\"debug\",\"ts\":1677058979.0520873,\"logger\":\"http\",\"msg\":\"servers shutting down with eternal grace period\"}\n","stream":"stderr","time":"2023-02-22T09:42:59.054984274Z"}
{"log":"{\"level\":\"info\",\"ts\":1677058979.155359,\"logger\":\"tls.cache.maintenance\",\"msg\":\"stopped background certificate maintenance\",\"cache\":\"0xc000253260\"}\n","stream":"stderr","time":"2023-02-22T09:42:59.155444419Z"}
{"log":"{\"level\":\"info\",\"ts\":1677058979.162771,\"logger\":\"admin\",\"msg\":\"stopped previous server\",\"address\":\"localhost:2019\"}\n","stream":"stderr","time":"2023-02-22T09:42:59.167766682Z"}
{"log":"{\"level\":\"info\",\"ts\":1677058979.1627858,\"msg\":\"shutdown complete\",\"signal\":\"SIGTERM\",\"exit_code\":0}\n","stream":"stderr","time":"2023-02-22T09:42:59.167783063Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.1840496,\"msg\":\"using provided configuration\",\"config_file\":\"/etc/caddy/Caddyfile\",\"config_adapter\":\"caddyfile\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.189575522Z"}
{"log":"{\"level\":\"warn\",\"ts\":1677059132.29415,\"msg\":\"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies\",\"adapter\":\"caddyfile\",\"file\":\"/etc/caddy/Caddyfile\",\"line\":7}\n","stream":"stderr","time":"2023-02-22T09:45:32.294446741Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3005822,\"logger\":\"admin\",\"msg\":\"admin endpoint started\",\"address\":\"localhost:2019\",\"enforce_origin\":false,\"origins\":[\"//localhost:2019\",\"//[::1]:2019\",\"//127.0.0.1:2019\"]}\n","stream":"stderr","time":"2023-02-22T09:45:32.30074699Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.301415,\"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}\n","stream":"stderr","time":"2023-02-22T09:45:32.301469904Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3014975,\"logger\":\"http\",\"msg\":\"enabling automatic HTTP-\u003eHTTPS redirects\",\"server_name\":\"srv0\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.301562635Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3062236,\"logger\":\"http\",\"msg\":\"enabling HTTP/3 listener\",\"addr\":\":443\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.306282456Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3066757,\"msg\":\"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details.\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.306716401Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.3072681,\"logger\":\"http\",\"msg\":\"starting server loop\",\"address\":\"[::]:443\",\"tls\":true,\"http3\":true}\n","stream":"stderr","time":"2023-02-22T09:45:32.307321481Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3073382,\"logger\":\"http.log\",\"msg\":\"server running\",\"name\":\"srv0\",\"protocols\":[\"h1\",\"h2\",\"h3\"]}\n","stream":"stderr","time":"2023-02-22T09:45:32.307446334Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.3075013,\"logger\":\"http\",\"msg\":\"starting server loop\",\"address\":\"[::]:80\",\"tls\":false,\"http3\":false}\n","stream":"stderr","time":"2023-02-22T09:45:32.307543903Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3075564,\"logger\":\"http.log\",\"msg\":\"server running\",\"name\":\"remaining_auto_https_redirects\",\"protocols\":[\"h1\",\"h2\",\"h3\"]}\n","stream":"stderr","time":"2023-02-22T09:45:32.307577033Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3075886,\"logger\":\"http\",\"msg\":\"enabling automatic TLS certificate management\",\"domains\":[\"192.168.0.29\",\"vaultwarden.mine.duckdns.org\"]}\n","stream":"stderr","time":"2023-02-22T09:45:32.307637032Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.3132415,\"logger\":\"tls\",\"msg\":\"loading managed certificate\",\"domain\":\"vaultwarden.mine.duckdns.org\",\"expiration\":1683831527,\"issuer_key\":\"acme-v02.api.letsencrypt.org-directory\",\"storage\":\"FileStorage:/data/caddy\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.313280847Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.3143437,\"logger\":\"tls.cache\",\"msg\":\"added certificate to cache\",\"subjects\":[\"vaultwarden.mine.duckdns.org\"],\"expiration\":1683831527,\"managed\":true,\"issuer_key\":\"acme-v02.api.letsencrypt.org-directory\",\"hash\":\"00fcbd725aa3114c1c71a396c9e72bf0c8c9a806911f934df97cdbfc27a136b5\",\"cache_size\":1,\"cache_capacity\":10000}\n","stream":"stderr","time":"2023-02-22T09:45:32.314382279Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.314418,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"cached_managed_cert\",\"id\":\"aa6894b0-a339-4f67-a108-abf27a5947f8\",\"origin\":\"tls\",\"data\":{\"sans\":[\"vaultwarden.mine.duckdns.org\"]}}\n","stream":"stderr","time":"2023-02-22T09:45:32.314491263Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.314596,\"msg\":\"autosaved config (load with --resume flag)\",\"file\":\"/config/caddy/autosave.json\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.314625934Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3146365,\"msg\":\"serving initial configuration\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.314654394Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3158987,\"logger\":\"tls.cache.maintenance\",\"msg\":\"started background certificate maintenance\",\"cache\":\"0xc000189260\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.315934968Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3160758,\"logger\":\"tls\",\"msg\":\"cleaning storage unit\",\"description\":\"FileStorage:/data/caddy\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.316125184Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.322642,\"logger\":\"tls\",\"msg\":\"finished cleaning storage units\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.322678377Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.3232944,\"logger\":\"tls.obtain\",\"msg\":\"acquiring lock\",\"identifier\":\"192.168.0.29\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.323331104Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.330896,\"logger\":\"tls.obtain\",\"msg\":\"lock acquired\",\"identifier\":\"192.168.0.29\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.330990968Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059132.331086,\"logger\":\"tls.obtain\",\"msg\":\"obtaining certificate\",\"identifier\":\"192.168.0.29\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.331117298Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.331241,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"cert_obtaining\",\"id\":\"9dfef911-5c53-47c1-a270-36772eb21f05\",\"origin\":\"tls\",\"data\":{\"identifier\":\"192.168.0.29\"}}\n","stream":"stderr","time":"2023-02-22T09:45:32.331277205Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.3317316,\"logger\":\"tls.obtain\",\"msg\":\"trying issuer 1/2\",\"issuer\":\"acme-v02.api.letsencrypt.org-directory\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.331766447Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.331857,\"logger\":\"tls.obtain\",\"msg\":\"trying issuer 2/2\",\"issuer\":\"acme.zerossl.com-v2-DV90\"}\n","stream":"stderr","time":"2023-02-22T09:45:32.331887573Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059132.331906,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"cert_failed\",\"id\":\"58eb1daf-1023-4c52-90f3-7615fce78cb4\",\"origin\":\"tls\",\"data\":{\"error\":{},\"identifier\":\"192.168.0.29\",\"issuers\":[\"acme-v02.api.letsencrypt.org-directory\",\"acme.zerossl.com-v2-DV90\"],\"renewal\":false}}\n","stream":"stderr","time":"2023-02-22T09:45:32.331940415Z"}
{"log":"{\"level\":\"error\",\"ts\":1677059132.331966,\"logger\":\"tls.obtain\",\"msg\":\"will retry\",\"error\":\"[192.168.0.29] Obtain: subject does not qualify for a public certificate: 192.168.0.29\",\"attempt\":1,\"retrying_in\":60,\"elapsed\":0.000960624,\"max_duration\":2592000}\n","stream":"stderr","time":"2023-02-22T09:45:32.331991512Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.1446986,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"b489289a-0a10-45b7-b596-9eb4b3e56d6c\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[19018,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"ServerName\":\"\",\"SupportedCurves\":[6682,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[43690,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:37.144842853Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.1448948,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.144917753Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.1449301,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50066\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.144955156Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.1449718,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50066\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50066\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[19018,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:37.144996454Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.1450963,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50066: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.145126409Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.20787,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"2ea92ea7-ea0a-454a-aff9-045c22df94ac\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[2570,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"ServerName\":\"\",\"SupportedCurves\":[2570,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[23130,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:37.207966645Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.2080138,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.208045366Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.2080572,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50067\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.208092614Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.208107,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50067\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50067\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[2570,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:37.208129177Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.2082105,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50067: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.208248379Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.2683475,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50068: tls: client offered only unsupported versions: [301]\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.268439891Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3376715,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"4ead83a5-8290-43e5-9a5b-77ab3377ba97\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[19018,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"ServerName\":\"\",\"SupportedCurves\":[35466,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[35466,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:37.337768057Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3382668,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.338292388Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.338305,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50069\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.338330244Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3383467,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50069\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50069\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[19018,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:37.338373375Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3384376,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50069: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.33846226Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3989325,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"36ba6ced-2d04-4327-83aa-d7161faa6f84\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[35466,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"ServerName\":\"\",\"SupportedCurves\":[6682,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[23130,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:37.399023146Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3990743,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.399099539Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3991122,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50070\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.399136616Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3991537,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50070\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50070\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[35466,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:37.399180046Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.3992646,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50070: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.399291734Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059137.448711,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50071: tls: client offered only unsupported versions: [301]\"}\n","stream":"stderr","time":"2023-02-22T09:45:37.448776654Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.039904,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"bd2ce583-2e4f-4752-bbf6-34b58cb16fc1\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[39578,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"ServerName\":\"\",\"SupportedCurves\":[19018,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[47802,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:42.040160924Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0399787,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.040179336Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0400074,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50072\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.04018212Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0400217,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50072\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50072\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[39578,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:42.040184573Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0400803,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50072: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.040213608Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0966456,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"9f762051-da15-49f9-948d-3fdd91fd8a70\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[64250,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"ServerName\":\"\",\"SupportedCurves\":[27242,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[56026,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:42.0969186Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0967317,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.096949674Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0967484,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50073\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.096954011Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0967624,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50073\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50073\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[64250,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:42.096956595Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.0968385,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50073: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.096959573Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.152329,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50074: tls: client offered only unsupported versions: [301]\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.152500761Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.2334807,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"e69c0beb-9b6f-45ce-b64f-35b1f8c46f75\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[31354,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"ServerName\":\"\",\"SupportedCurves\":[10794,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[56026,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:42.23374523Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.2335653,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.233775547Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.2335823,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50075\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.233778406Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.2335992,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50075\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50075\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[31354,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:42.233780791Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.2336621,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50075: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.233783771Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.3090808,\"logger\":\"events\",\"msg\":\"event\",\"name\":\"tls_get_certificate\",\"id\":\"d192e3a1-aae1-4cef-9873-ff93187f11ff\",\"origin\":\"tls\",\"data\":{\"client_hello\":{\"CipherSuites\":[10794,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"ServerName\":\"\",\"SupportedCurves\":[56026,29,23,24,25],\"SupportedPoints\":\"AA==\",\"SignatureSchemes\":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],\"SupportedProtos\":[\"h2\",\"http/1.1\"],\"SupportedVersions\":[35466,772,771,770,769],\"Conn\":{}}}}\n","stream":"stderr","time":"2023-02-22T09:45:42.309385896Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.309175,\"logger\":\"tls.handshake\",\"msg\":\"no matching certificates and no custom selection logic\",\"identifier\":\"172.22.0.3\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.309410441Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.3091924,\"logger\":\"tls.handshake\",\"msg\":\"all external certificate managers yielded no certificates and no errors\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50076\",\"sni\":\"\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.309413684Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.309207,\"logger\":\"tls.handshake\",\"msg\":\"no certificate matching TLS ClientHello\",\"remote_ip\":\"192.168.0.27\",\"remote_port\":\"50076\",\"server_name\":\"\",\"remote\":\"192.168.0.27:50076\",\"identifier\":\"172.22.0.3\",\"cipher_suites\":[10794,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],\"cert_cache_fill\":0.0001,\"load_if_necessary\":true,\"obtain_if_necessary\":true,\"on_demand\":false}\n","stream":"stderr","time":"2023-02-22T09:45:42.309416516Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.309273,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50076: no certificate available for '172.22.0.3'\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.309431166Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059142.3714428,\"logger\":\"http.stdlib\",\"msg\":\"http: TLS handshake error from 192.168.0.27:50077: tls: client offered only unsupported versions: [301]\"}\n","stream":"stderr","time":"2023-02-22T09:45:42.371576118Z"}
{"log":"{\"level\":\"info\",\"ts\":1677059146.902235,\"msg\":\"shutting down apps, then terminating\",\"signal\":\"SIGTERM\"}\n","stream":"stderr","time":"2023-02-22T09:45:46.902552596Z"}
{"log":"{\"level\":\"warn\",\"ts\":1677059146.9022613,\"msg\":\"exiting; byeee!! 👋\",\"signal\":\"SIGTERM\"}\n","stream":"stderr","time":"2023-02-22T09:45:46.902576572Z"}
{"log":"{\"level\":\"debug\",\"ts\":1677059146.9022913,\"logger\":\"http\",\"msg\":\"servers shutting down with eternal grace period\"}\n","stream":"stderr","time":"2023-02-22T09:45:46.902579882Z"}

1 Like

@francislavoie, reckon Docker is NATing the IP address here and it’s confusing SNI in the process?

1 Like

Docker often runs a userland TCP proxy which transforms the packets so they look like they’re coming from Docker’s IP instead of from the original client.

You’re better off using an actual domain and running a DNS server locally or w/e. Or use a dummy subdomain that you can set to your LAN IP.

1 Like

Agreed.

I think you could theoretically add Caddy to a macvlan bridge as well as the default Docker bridge network and connect to the IP it gets from your LAN, but at that point - yeah. Just configure an internal DNS to point to the Caddy host, it will save you a lot of effort.

Wow you are blazing fast :star_struck:.

DNS Job at my place is carried out by a fritz box. Don’ know if you ever heard. It’s the all in one router, given by the Provider… Don’t know if this is possible with it

The FRITZ!Box cannot be used for DNS resolution of domain names that point to private IP addresses in the FRITZ!Box home network. As a result, the domain name cannot be used to access server services in the FRITZ!Box home network.

Cause

  • For security reasons, the FRITZ!Box suppresses DNS responses that refer to IP addresses in its own home network. This is a security function of the FRITZ!Box to protect against so-called DNS rebinding attacks.

—No DNS resolution of private IP addresses | FRITZ!Box 7360 | AVM International

The linked article then appears to give step-by-step instructions on how to bypass this protection in order to allow a domain name to return a private IP address.

A quick search didn’t turn up anything useful specific to split DNS, though (i.e. overriding requests inside the LAN to return the private IP for the Caddy host while external requests go to public DNS providers and return the public IP instead).

So, instead, I imagine you’ll need to configure a dummy subdomain (like vaultwarden-internal.mine.duckdns.org or something) that returns the private IP address in question, and then add the hostname in question to the allowlist in your FRITZ!Box.

I seem to remember that there was some kind of public DNS server out there you could formulate a request for and it would just return the IP address you wanted, like 127.0.0.1.ns.example that would just return 127.0.0.1. But for the life of me, I can’t remember where I found that - and it seems very, very hard to google.

1 Like

Okay. First: I’m so thankful for the efforts you make for me :heart_eyes:.

Try to keep up with the information you provide. What would be the easiest way? Set up a local DNS? As I enter the IP Adresses all the time in my local Network I’m not using the local DNS implemented in the Fritzbox anyway :-).

Or what means setup a dummy subdomain. If i use internal.vaultwarden.com or sth. like that I still need a DNS which resolves it if there is no internet connection available or do I get sth. wrong?
And the only thing on my Router is to exclude a Domain Name from rebind protection

I don’t know about the easiest, I’m afraid. I’m not familiar with FRITZ!Box.

For me personally, I use pfSense. Since it’s got its own DNS resolver chain, in addition to being able to automatically do name resolution for LAN hosts without me needing to configure anything, I could also just add arbitrary domain name → IP address associations and have it override public DNS. That means I could have this working on my network just by adding a single record and hitting ‘save’.

Since I can’t see from a quick google that FRITZ!Box has this kind of functionality - it seems to rely on external resolvers - you’d need to use some other DNS resolver.

That might mean using DuckDNS itself - exactly as you’ve noted - although it would fall over if your internet went out and you didn’t have that DNS record cached on your computer or the FRITZ!Box, as you’ve noted. Technically it’s a minor no-no to abuse public DNS to resolve private IP addresses, but it’s only a technical no-no, it’s not illegal or anything.

It also might mean running another DNS server in your network. You could run something like CoreDNS (originally based on Caddy v1!) as a standalone internal DNS resolver, and then point your FRITZ!Box at that for resolution. Then you could leave vaultwarden.mine.duckdns.org configured with your external IP address over at DuckDNS, but just add it to your internal server as well, pointing at your private IP address. This “overloads” the record; requests for Vaultwarden internally go directly over LAN, while requests for Vaultwarden externally go to your external IP address. This is Split DNS. It would mean that your Caddy server needs only one Site Address configured to serve both, and it’s probably the ideal configuration, but whether it’s easiest for you, I’m not sure.

1 Like