1. The problem I’m having:
I have 2 caddy instances. On the public instance, I have 7-8 hosts that all proxy traffic to the internal caddy instance and they do so with TLS enabled.
Previously, I had N blocks 1 for each host. I am trying to figure out if I can condense them all into 1 block since all the config parameter are the same except for the TLS SNI value which varies across hosts. I tried to configure it but
I am getting TLS related between a client on the public internet and the public caddy instance. Is there any way to do this without repeating the blocks ?
2. Error messages and/or full log output:
{"level":"debug","ts":1737673663.7874644,"logger":"http.stdlib","msg":"http: TLS handshake error from 98.80.130.239:3599: no server TLS configuration available for ClientHello: &{CipherSuites:[49196 49195 49200 49199 159 163 158 162 49188 49192 49187 49191 107 106 103 64 49198 49202 49197 49201 49190 49194 49189 49193 49162 49172 49161 49171 57 56 51 50 49157 49167 49156 49166 157 156 61 60 53 47 255] ServerName:git.ishanjain.me SupportedCurves:[CurveP256 CurveP384 CurveP521 CurveID(256) CurveID(257) CurveID(258) CurveID(259) CurveID(260)] SupportedPoints:[0] SignatureSchemes:[ECDSAWithP256AndSHA256 ECDSAWithP384AndSHA384 ECDSAWithP521AndSHA512 PSSWithSHA256 PSSWithSHA384 PSSWithSHA512 SignatureScheme(2057) SignatureScheme(2058) SignatureScheme(2059) PKCS1WithSHA256 PKCS1WithSHA384 PKCS1WithSHA512 SignatureScheme(1026) SignatureScheme(771) SignatureScheme(769) SignatureScheme(770) ECDSAWithSHA1 PKCS1WithSHA1 SignatureScheme(514)] SupportedProtos:[] SupportedVersions:[771 770 769] Conn:0xc00148cdd8 config:0xc0015db180 ctx:0xc00041caa0}"}
3. Caddy version:
v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=
4. How I installed and ran Caddy:
Built using xcaddy with a few custom modules
a. System environment:
OS: Arch linux
Arch: amd64
systemd 256 (256.1-1-arch-g34ba18b^)
b. Command:
caddy run --config /etc/caddy/caddy.json
c. Service/unit/compose file:
d. My complete Caddy config:
{
"apps": {
"geoip2": {
"accountId": 362099,
"databaseDirectory": "/var/lib/caddy",
"editionID": "GeoLite2-City",
"lockFile": "/var/lib/caddy/db.lck",
"updateFrequency": 86400,
"updateUrl": "https://updates.maxmind.com"
},
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"logs": {
"logger_names": {
"auth.ishanjain.me": "log0",
"cups.home.ishanjain.me": "log0",
"dash.ishanjain.me": "log0",
"dl.ishanjain.me": "log0",
"dns.ishan.pw": "local_only",
"git.ishanjain.me": "log0",
"ha.home.ishanjain.me": "log0",
"home.dns.ishan.pw": "log0",
"influx.home.ishanjain.me": "log0",
"irc.ishanjain.me": "log0",
"jellyfin.ishanjain.me": "log0",
"ldap.ishanjain.me": "log0",
"money.ishanjain.me": "log0",
"omada.home.ishanjain.me": "log0",
"pdf.ishanjain.me": "log0",
"public.dns.ishan.pw": "log0",
"pve.home.ishanjain.me": "log0",
"pvenas.home.ishanjain.me": "log0",
"pvepc.home.ishanjain.me": "log0",
"qbit.ishanjain.me": "log0",
"rss.ishanjain.me": "log0",
"status.ishanjain.me": "log0",
"vault.ishanjain.me": "log0"
}
},
"routes": [
{
"handle": [
{
"enable": "trusted_proxies",
"handler": "geoip2"
},
{
"handler": "headers",
"request": {
"set": {
"X-Forwarded-For": [
"{http.request.remote.host}"
],
"X-Real-IP": [
"{http.request.remote.host}"
]
}
},
"response": {
"deferred": true,
"delete": [
"Server"
],
"set": {
"X-City": [
"{geoip2.city_name}"
],
"X-Continent": [
"{geoip2.continent_code}"
],
"X-Country": [
"{geoip2.country_code}"
],
"X-Latitude": [
"{geoip2.location_latitude}"
],
"X-Longitude": [
"{geoip2.location_longitude}"
],
"X-State": [
"{geoip2.subdivisions_1_iso_code}"
]
}
}
}
],
"terminal": false
},
{
"group": "adguardhome",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"protocol": "http",
"tls": {
"server_name": "dns.ishan.pw"
}
},
"upstreams": [
{
"dial": "127.0.0.1:8443"
}
]
}
],
"match": [
{
"host": [
"dns.ishan.pw"
],
"path": [
"/dns-query/*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "127.0.0.1:1030"
}
]
}
],
"match": [
{
"host": [
"public.dns.ishan.pw"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"compression": true,
"protocol": "http",
"tls": {
"server_name": "dns.ishan.pw"
}
},
"upstreams": [
{
},
{
"dial": "10.0.99.14:443"
}
]
}
],
"match": [
{
"host": [
"home.dns.ishan.pw"
]
}
]
}
]
}
],
"match": [
{
"host": [
"*.ishan.pw",
"*.dns.ishan.pw"
]
}
],
"terminal": true
},
{
"handle": [
{
"encodings": {
"gzip": {}
},
"handler": "encode",
"prefer": [
"gzip"
]
},
{
"handler": "file_server",
"root": "/home/ishan/dl"
}
],
"match": [
{
"host": [
"dl.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "127.0.0.1:1337"
}
]
}
],
"match": [
{
"host": [
"status.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "127.0.0.1:4242"
}
]
}
],
"match": [
{
"host": [
"rss.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "127.0.0.1:3030"
}
]
}
],
"match": [
{
"host": [
"vault.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "10.0.50.17:9091"
}
]
}
],
"match": [
{
"host": [
"auth.ishanjain.me"
]
}
],
"terminal": true
},
{
"group": "homecaddy",
"handle": [
{
"handler": "reverse_proxy",
"health_checks": {
"active": {
"expect_status": 200,
"interval": "10s",
"port": 9001,
"timeout": "10s",
"uri": "/"
}
},
"load_balancing": {
"retries": 2,
"selection_policy": {
"policy": "first"
},
"try_duration": "3s",
"try_interval": "10ms"
},
"transport": {
"protocol": "http",
"tls": {
"server_name": "pvenas.home.ishanjain.me"
}
},
"upstreams": [
{
},
{
"dial": "10.0.50.3:443"
}
]
}
],
"match": [
{
"host": [
"cups.home.ishanjain.me",
"dash.ishanjain.me",
"git.ishanjain.me",
"ha.home.ishanjain.me",
"influx.home.ishanjain.me",
"irc.ishanjain.me",
"jellyfin.ishanjain.me",
"ldap.ishanjain.me",
"money.ishanjain.me",
"omada.home.ishanjain.me",
"pdf.ishanjain.me",
"qbit.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handle_response": [
{
"match": {
"status_code": [
2
]
},
"routes": [
{
"handle": [
{
"handler": "vars"
}
]
}
]
}
],
"handler": "reverse_proxy",
"headers": {
"request": {
"set": {
"X-Forwarded-Method": [
"{http.request.method}"
],
"X-Forwarded-Uri": [
"{http.request.uri}"
]
}
}
},
"rewrite": {
"method": "GET",
"uri": "/api/authz/forward-auth"
},
"upstreams": [
{
"dial": "10.0.50.17:9091"
}
]
},
{
"handler": "reverse_proxy",
"health_checks": {
"active": {
"expect_status": 200,
"interval": "10s",
"port": 8006,
"timeout": "10s",
"uri": "/"
}
},
"load_balancing": {
"retries": 2,
"selection_policy": {
"policy": "first"
},
"try_duration": "3s",
"try_interval": "10ms"
},
"transport": {
"compression": true,
"protocol": "http",
"tls": {
"server_name": "pvepc.home.ishanjain.me"
}
},
"upstreams": [
{
},
{
"dial": "10.0.99.4:8006"
}
]
}
],
"match": [
{
"host": [
"pvepc.home.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handle_response": [
{
"match": {
"status_code": [
2
]
},
"routes": [
{
"handle": [
{
"handler": "vars"
}
]
}
]
}
],
"handler": "reverse_proxy",
"headers": {
"request": {
"set": {
"X-Forwarded-Method": [
"{http.request.method}"
],
"X-Forwarded-Uri": [
"{http.request.uri}"
]
}
}
},
"rewrite": {
"method": "GET",
"uri": "/api/authz/forward-auth"
},
"upstreams": [
{
"dial": "10.0.50.17:9091"
}
]
},
{
"handler": "reverse_proxy",
"health_checks": {
"active": {
"expect_status": 200,
"interval": "10s",
"port": 8006,
"timeout": "10s",
"uri": "/"
}
},
"load_balancing": {
"retries": 2,
"selection_policy": {
"policy": "first"
},
"try_duration": "3s",
"try_interval": "10ms"
},
"transport": {
"compression": true,
"protocol": "http",
"tls": {
"server_name": "pvenas.home.ishanjain.me"
}
},
"upstreams": [
{
},
{
"dial": "10.0.99.9:8006"
}
]
}
],
"match": [
{
"host": [
"pvenas.home.ishanjain.me"
]
}
],
"terminal": true
},
{
"handle": [
{
"handle_response": [
{
"match": {
"status_code": [
2
]
},
"routes": [
{
"handle": [
{
"handler": "vars"
}
]
}
]
}
],
"handler": "reverse_proxy",
"headers": {
"request": {
"set": {
"X-Forwarded-Method": [
"{http.request.method}"
],
"X-Forwarded-Uri": [
"{http.request.uri}"
]
}
}
},
"rewrite": {
"method": "GET",
"uri": "/api/authz/forward-auth"
},
"upstreams": [
{
"dial": "10.0.50.17:9091"
}
]
},
{
"handler": "reverse_proxy",
"health_checks": {
"active": {
"expect_status": 200,
"interval": "10s",
"port": 8006,
"timeout": "10s",
"uri": "/"
}
},
"load_balancing": {
"retries": 2,
"selection_policy": {
"policy": "first"
},
"try_duration": "3s",
"try_interval": "10ms"
},
"transport": {
"compression": true,
"protocol": "http",
"tls": {
"server_name": "pve.home.ishanjain.me"
}
},
"upstreams": [
{
},
{
"dial": "10.0.99.8:8006"
}
]
}
],
"match": [
{
"host": [
"pve.home.ishanjain.me"
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"client_authentication": {
"mode": "require_and_verify",
"trusted_ca_certs": [
]
},
"match": {
"sni": []
},
"protocol_min": "tls1.3"
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"name": "cloudflare"
}
},
"http": {
"disabled": false
},
"tls-alpn": {
"disabled": false
}
},
"email": "contact@ishanjain.me",
"module": "acme"
}
],
"subjects": [
"*.home.ishanjain.me",
"*.ishanjain.me",
"*.ishan.pw",
"*.dns.ishan.pw",
"dns.ishan.pw"
]
}
]
}
}
},
"logging": {
"logs": {
"discard": {
"writer": {
"output": "discard"
}
},
"garbage": {
"encoder": {
"format": "json"
},
"exclude": [
"http.log.access.log0",
"http.log.access.local_only"
],
"include": [
"http.log.access"
],
"writer": {
"filename": "/var/log/caddy/garbage.txt",
"output": "file",
"roll_keep_days": 180,
"roll_local_time": true,
"roll_size_mb": 400
}
},
"influx_log": {
"encoder": {
"format": "json"
},
"include": [
"http.log.access.log0"
],
"writer": {
"bucket": "caddy-del",
"host": "http://10.0.50.8:8086",
"ignore_fields": [
"level",
"logger",
"msg",
"request_headers_Accept-Encoding",
"resp_headers_Cache-Control",
"resp_headers_Date",
"resp_headers_X-Xss-Protection_0",
"tls",
"ts"
],
"measurement": "access",
"org": "homelab",
"output": "influx_log",
"tags": {
"request_city": "{resp_headers_X-City_0}",
"request_continent": "{resp_headers_X-Continent_0}",
"request_country": "{resp_headers_X-Country_0}",
"request_host": "{request_host}",
"request_method": "{request_method}",
"request_proto": "{request_proto}",
"request_state": "{resp_headers_X-State_0}",
"request_status": "{status}",
"request_user_agent": "{request_headers_User-Agent_0}"
}
}
},
"local_only": {
"encoder": {
"format": "json"
},
"include": [
"http.log.access.local_only"
],
"writer": {
"filename": "/var/log/caddy/local_only.txt",
"output": "file",
"roll_keep_days": 180,
"roll_local_time": true,
"roll_size_mb": 400
}
},
"local_warn": {
"encoder": {
"format": "json"
},
"include": [
"http.handlers.reverse_proxy"
],
"level": "warn",
"writer": {
"filename": "/var/log/caddy/reverse_proxy_warn.txt",
"output": "file",
"roll_keep_days": 180,
"roll_local_time": true,
"roll_size_mb": 400
}
},
"log0": {
"encoder": {
"format": "json"
},
"include": [
"http.log.access.log0"
],
"writer": {
"filename": "/var/log/caddy/log.txt",
"output": "file",
"roll_keep_days": 180,
"roll_local_time": true,
"roll_size_mb": 400
}
},
"debug": {
"encoder": {
"format": "json"
},
"level": "debug",
"include": [
],
"writer": {
"filename": "/var/log/caddy/debug.txt",
"output": "file",
"roll_keep_days": 180,
"roll_local_time": true,
"roll_size_mb": 400
}
}
}
}
}