Connection error when renewing IDN domain

I am unable to renew a certificate containing a german “umlaut”.

Unfortunately it seems like an error on the LE side, because it seems to be trying to resolve the de-punycoded address, which will, of course, not work. (See “hostname” in JSON-Output)
Correct me if I am wrong.

(You wont find anything under the domain, because it is only for internal use.)

Note, that obtaining new certificates with “ü” in them seems to work and obtaining the cert in the first place also worked, with the same configuration.

My domain is: müllhalde.h3ndr1k.de (müllhalde.h3ndr1k.de)

I ran this command: dehydrated -c -g

It produced this output:

# dehydrated -c -g
# INFO: Using main config file /etc/dehydrated/config
Processing xn--mllhalde-65a.h3ndr1k.de with alternative names: muellhalde.h3ndr1k.de
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Dec 31 23:49:45 2017 GMT Certificate will expire
(Less than 30 days). Renewing!
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for xn--mllhalde-65a.h3ndr1k.de...
 + Requesting challenge for muellhalde.h3ndr1k.de...
 + Responding to challenge for xn--mllhalde-65a.h3ndr1k.de...
ERROR: Challenge is invalid! (returned: invalid) (result: {
  "type": "http-01",
  "status": "invalid",
  "error": {
    "type": "urn:acme:error:connection",
    "detail": "Fetching https://müllhalde.h3ndr1k.de/.well-known/acme-challenge/<foo>: Error getting validation data",
    "status": 400
  },
  "uri": "https://acme-staging.api.letsencrypt.org/acme/challenge/<foo>",
  "token": "<foo>",
  "keyAuthorization": "<foo>",
  "validationRecord": [
    {
      "url": "https://m%C3%BCllhalde.h3ndr1k.de/.well-known/acme-challenge/<foo>",
      "hostname": "müllhalde.h3ndr1k.de",
      "port": "443",
      "addressesResolved": [],
      "addressUsed": "",
      "addressesTried": []
    },
    {
      "url": "http://xn--mllhalde-65a.h3ndr1k.de/.well-known/acme-challenge/<foo>",
      "hostname": "xn--mllhalde-65a.h3ndr1k.de",
      "port": "80",
      "addressesResolved": [
        "139.20.170.204"
      ],
      "addressUsed": "139.20.170.204",
      "addressesTried": []
    }
  ]
})

My web server is (include version): Apache 2.4.25-3+deb9u3
The operating system my web server runs on is (include version): Debian Stretch
I can login to a root shell on my machine (yes or no, or I don’t know): yes

You’re serving a redirect for that domain, but the target URL (from the Location header) is not using punycode:

curl -v http://xn--mllhalde-65a.h3ndr1k.de/.well-known/acme-challenge/foo
*   Trying 139.20.170.204...
* TCP_NODELAY set
* Connected to xn--mllhalde-65a.h3ndr1k.de (139.20.170.204) port 80 (#0)
> GET /.well-known/acme-challenge/foo HTTP/1.1
> Host: xn--mllhalde-65a.h3ndr1k.de
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
>
< HTTP/1.1 301 Moved Permanently
< Date: Wed, 06 Dec 2017 12:42:45 GMT
< Server: Apache
< Location: https://müllhalde.h3ndr1k.de/.well-known/acme-challenge/foo
< Content-Length: 268
< Content-Type: text/html; charset=iso-8859-1

The browsers I tested with seem to accept this encoding, but I think that’s them being overly lax. curl, on the other hand, fails with this redirect in place.

I’m having a hard time finding an RFC that explicitly states that URLs in HTTP headers must use punycode, but I feel like the HTTP Location header should fall into the “IDN-unaware domain name slot” category described in RFC 3490, which would imply punycode is applicable. Changing your redirect to use punycode should fix the issue.

I’d be curious about the web server configuration you’re using for that redirect, would you mind sharing that? Mostly just wondering if the configuration snippets most guides use would cause this error with IDNs.

2 Likes

Ah, thanks for the hint. It now works properly. Seems I might have changed the server config some day.

Sure, here is the new config:

<VirtualHost *:80>
ServerName mü.h3ndr1k.de
ServerAlias xn--m-eha.h3ndr1k.de
ServerAlias mue.h3ndr1k.de

RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]

-bla-

</VirtualHost>

The old config contained:

RewriteRule ^ https://mü.h3ndr1k.de%{REQUEST_URI} [END,QSA,R=permanent]

SSL config:

<VirtualHost *:443>
ServerName mü.h3ndr1k.de
ServerAlias xn--m-eha.h3ndr1k.de
ServerAlias mue.h3ndr1k.de
-bla-

That in connection with your redirect is the culprit:

You use %{SERVER_NAME}, so it uses the value of the ServerName statement (with umlauts). If you'd use %{HTTP_HOST} instead, the redirect would use the value from the Host header of the client making the request (without umlauts).

I doubt one can use non-ace names in the ServerName directive.

Hmm, but it just worked. I was able to renew the certificate with SERVER_NAME.

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