1. Caddy version (caddy version
):
2.5.1
2. How I run Caddy:
Currently using Caddy to expose Plex publicly with my own DNS. Also for exposing other services internally only using self signed cert.
a. System environment:
Docker v20.10.17
b. Command:
docker-compose up -d
c. Service/unit/compose file:
services:
caddy:
image: pleasestopasking/caddy:2.5.1_02
hostname: caddy
container_name: caddy
restart: always
ports:
- 80:80
- 443:443
volumes:
- $PWD/docker-configs/caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
name: caddy_data
caddy_config:
name: caddy_config
d. My complete Caddyfile or JSON config:
(baseline-headers) {
header {
Permissions-Policy: "interest-cohort=(), camera=(), geolocation=(), microphone=(), payment=(), usb=(), vr=()"
Access-Control-Allow-Methods: GET, OPTIONS, PUT
Access-Control-Max-Age: 100
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-site
Server: null
Vary: Origin
X-Forwarded-Proto: https
Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: "1; mode=block"
Referrer-Policy: strict-origin-when-cross-origin
X-Robots-Tag: none,noarchive,nosnippet,notranslate,noimageindex
}
}
(plex-headers) {
header {
Content-Security-Policy: "default-src 'self'; base-uri 'self'; script-src 'self' 'unsafe-eval' 'sha256-nJQTRKTrsNC7POCKq7aJgohAiPwBISLvR7aJylcnMeE=' 'sha256-pKO/nNgeauDINvYfxdygP3mGssdVQRpRNxaF7uPRoGM=' 'sha256-WbMRMEGI/3b4tpLvamts9byuWeI9lP2bKREKq08ujJU=' 'sha256-Jak/x3IyEWydZxb+2CUd6rJQgpjhTbdymhm4fpt8EVQ=' 'sha256-4yWHSc589xcanc7GAAy3++M4EvUxNtUsJySeoYEE6z8=' 'sha256-9YWnVu29Ew4LEW4tEiPWEdcHvzlbbwpiazu4PZR3oTY='; style-src 'self' 'unsafe-hashes' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='; img-src 'self' https://provider-static.plex.tv data: blob:; font-src 'self' data:; connect-src 'self' https://analytics.plex.tv https://metadata.provider.plex.tv https://together.plex.tv https://plex.tv https://*.plex.direct:* wss://*.plex.direct:* wss://pubsub.plex.tv; media-src 'self' https://*.plex.direct:*; object-src 'self'; child-src 'none'; frame-src 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content"
}
}
*.geordi.lan:443 {
tls internal
@omv host omv.geordi.lan
handle @omv {
reverse_proxy 192.168.4.46:6080
encode gzip
import baseline-headers
header {
Access-Control-Allow-Origin: https://omv.geordi.lan
}
}
@homer host homer.geordi.lan
handle @homer {
reverse_proxy homer:8080
encode gzip
import baseline-headers
header {
Access-Control-Allow-Origin: https://homer.geordi.lan
}
}
@adguard host adguard.geordi.lan
handle @adguard {
reverse_proxy 192.168.4.71
encode gzip
import baseline-headers
header {
Access-Control-Allow-Origin: https://adguard.geordi.lan
}
}
@grafana host grafana.geordi.lan
handle @grafana {
reverse_proxy grafana:3000
encode gzip
import baseline-headers
header {
Access-Control-Allow-Origin: https://grafana.geordi.lan
}
}
@prometheus host prometheus.geordi.lan
handle @prometheus {
reverse_proxy prometheus:9090
encode gzip
import baseline-headers
header {
Access-Control-Allow-Origin: https://prometheus.geordi.lan
}
}
# Fallback for otherwise unhandled domains
handle {
abort
}
}
plex.htchr.dev:443 {
reverse_proxy plex:32400
encode gzip
import baseline-headers
import plex-headers
header {
Access-Control-Allow-Origin: https://plex.htchr.dev
}
}
3. The problem I’m having:
My current implementation is working just fine but I would like to move my internal services from *geordi.lan to *.internal.htchr.dev while ensuring they are never exposed publicly and ALSO using LE certs. I could switch from port 443 on the internal services to something else that I am not forwarding from my router but I would like to stick with the standard 443.
After reading through the documentation and others implementations, I believe I have come to the conclusion that the only way to properly do this is to purchase another domain name such as htchr2.dev and use that for internal services by using DNS validation but not setting any A/CNAME records that point to my public IP.
I am hoping someone can provide feedback on my idea and whether or not I am on the right path here.
4. Error messages and/or full log output:
None at this time
5. What I already tried:
I have tried the following config and while it does successfully grab a wildcard certificate, my DNS is publicly available and the only real security provided is the @denied
if the requester is not coming from a private CIDR range.
Currently using Hover as my registrar which does have a DNS module available so I have also use DuckDNS delegation to obtain the wildcard certificate which does work.
*.internal.htchr.dev:443 {
tls {
dns duckdns {
api_token <redacted>
override_domain htchr-internal.duckdns.org
}
}
@denied not remote_ip private_ranges
abort @denied
respond "You have been granted access!"
}