1. Caddy version (caddy version
):
v.2.3.0 (Custom build + Gandi DNS ACME)
2. How I run Caddy:
JSON config file, plus two env-vars to stipulate the config and data directories.
a. System environment:
VPS, Debian
b. Command:
# XDG_DATA_HOME=/opt/caddy/data XDG_CONFIG_HOME=/opt/caddy/config caddy run --config /opt/caddy/caddy_config.json
c. Service/unit/compose file:
Running manually at present while I debug.
d. My complete Caddyfile or JSON config:
{
"apps": {
"tls": {
"automation": {
"policies": [
{
"issuers": [
{
"email": "<redacted>",
"module": "acme",
"challenges": {
"dns": {
"provider": {
"name": "gandi",
"api_token": "<not today, satan>"
}
}
}
}
]
}
]
}
},
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.domaĆn.ie"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "headers",
"response": {
"set": {
"Strict-Transport-Security": [
"max-age=31556925"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Content-Type-Options": [
"nosniff"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Download-Options": [
"noopen"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Frame-Options": [
"DENY"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Permitted-Cross-Domain-Policies": [
"none"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Robots-Tag": [
"noindex,nofollow,nosnippet,noarchive"
]
}
}
},
{
"handler": "headers",
"response": {
"set": {
"X-Xss-Protection": [
"1; mode=block"
]
}
}
}
],
"match": [
{
"path": [
"/"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "localhost:7156"
}
]
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}
NB: Note the domain name contains an accented character āĆā. The actual domain has an accented āĆ³ā, in case that matters
3. The problem Iām having:
Lets-Encrypt is rejecting the domain accusing it of having an āinvalid characterā. Of course Iām eyerolling about the anglocentricity of the whole thing, but really I just want a cert that will work so Iām open to suggestions: Should I be putting the punycode domain in the caddyfile? If so, this should probably be documented at the Caddy end of things. Or is it just that Lets-Encrypt donāt understand non-English domains? e.g. is this fixable at my end?
4. Error messages and/or full log output:
The ACME challenge with Lets-Encrypt fails with this error:
2021/01/21 15:08:45.186 INFO using provided configuration {"config_file": "/opt/caddy/caddy_config.json", "config_adapter": ""}
2021/01/21 15:08:45.187 INFO admin admin endpoint started {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/01/21 15:08:45.188 INFO http 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}
2021/01/21 15:08:45.188 INFO http enabling automatic HTTP->HTTPS redirects {"server_name": "srv0"}
2021/01/21 15:08:45.189 INFO http enabling automatic TLS certificate management {"domains": ["example.domaĆn.ie"]}
2021/01/21 15:08:45.190 INFO autosaved config {"file": "/opt/caddy/config/caddy/autosave.json"}
2021/01/21 15:08:45.190 INFO serving initial configuration
2021/01/21 15:08:45.190 INFO tls.obtain acquiring lock {"identifier": "example.domaĆn.ie"}
2021/01/21 15:08:45.190 INFO tls.obtain lock acquired {"identifier": "example.domaĆn.ie"}
2021/01/21 15:08:45.200 INFO tls.issuance.acme waiting on internal rate limiter {"identifiers": ["example.domaĆn.ie"]}
2021/01/21 15:08:45.201 INFO tls.issuance.acme done waiting on internal rate limiter {"identifiers": ["example.domaĆn.ie"]}
2021/01/21 15:08:45.201 INFO tls.cache.maintenance started background certificate maintenance {"cache": "<redacted>"}
2021/01/21 15:08:45.202 INFO tls cleaned up storage units
2021/01/21 15:08:46.471 INFO tls.issuance.acme.acme_client validations succeeded; finalizing order {"order": "https://acme-v02.api.letsencrypt.org/acme/order/<redacted>/<redacted>"}
2021/01/21 15:08:46.660 ERROR tls.obtain will retry {"error": "[example.domaĆn.ie] Obtain: [example.domaĆn.ie] finalizing order https://acme-v02.api.letsencrypt.org/acme/order/<redacted>/<redacted>: request to https://acme-v02.api.letsencrypt.org/acme/finalize/<redacted>/<redacted> failed after 1 attempts: HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Error finalizing order :: Cannot issue for \"example.domaĆn.ie\": Domain name contains an invalid character (ca=https://acme-v02.api.letsencrypt.org/directory)", "attempt": 1, "retrying_in": 60, "elapsed": 1.469109322, "max_duration": 2592000}
5. What I already tried:
TBH, I donāt want to experiment too much in case I get blacklisted by the ACME providers or end up rate limited for a week.
I had been having HTTP-code-400 errors with zeroSSL when I was using the HTTP ACME challenge mode, and it was telling me the CSRs didnāt matchā¦ I didnāt get far in resolving this issue, so I just switched to Gandi DNS and hoped that would fix things, or at least give a more informative error.
I disabled ZeroSSL because I felt the fallback was just risking me getting banned from both services while I debugged, and because oddly I was not getting an error with Lets-Encrypt at firstā¦ it would seem to succeed, and then there would be no log-line indicating failure, and it would proceed to ZeroSSL. So I was hoping to shake this bug out, too.
Perhaps the unspecified CSR mismatch with ZeroSSL was due to this issue also? It isnāt clear to me why I only started getting this clearly-worded error when I enabled Gandi-based DNS ACME, and not when I was attempting the HTTP ACME challenge.
6. Links to relevant resources:
None found.