Let’s Encrypt mit SAN (unauthorized)

Sickboy

Müßiggänger
Hallo allerseits,

ich habe folgendes seltsames Problem: ich versuche für eine Maschine SAN-Zertifikate von Let’s Encrypt zu erhalten, bekomme vom acme-client aber immer ein "bad response" zurück:
Code:
{
  "type": "http-01",
  "status": "invalid",
  "error": {
    "type": "urn:acme:error:unauthorized",
    "detail": "Invalid response from http://example.com/.well-known/acme-challenge/JERs-WnDdO7Lzp3PJL9aH7WrIhrUmRQS2lEmlg16Uaw: \"\u003chtml\u003e\r\n\u003chead\u003e\u003ctitle\u003e404 Not Found\u003c/title\u003e\u003c/head\u003e\r\n\u003cbody bgcolor=\"white\"\u003e\r\n\u003ccenter\u003e\u003ch1\u003e404 Not Found\u003c/h1\u003e\u003c/center\u003e\r\n\u003chr\u003e\u003ccenter\u003e\"",
    "status": 403
  },
  "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/4_wnRilmFJ9zB2KvzSSn91Fdonv4f8bs-7S9RGB4DAg/1055328709",
  "token": "JERs-WnDdO7Lzp3PJL9aH7WrIhrUmRQS2lEmlg16Uaw",
  "keyAuthorization": "JERs-WnDdO7Lzp3PJL9aH7WrIhrUmRQS2lEmlg16Uaw.qFo0j3x81_6YnlcHVGOeaT2213OA7bhujutkrV38AlY",
  "validationRecord": [
    {
      "url": "http://example.com/.well-known/acme-challenge/JERs-WnDdO7Lzp3PJL9aH7WrIhrUmRQS2lEmlg16Uaw",
      "hostname": "example.com",
      "port": "80",
      "addressesResolved": [
        "X.X.X.X"
      ],
      "addressUsed": "X.X.X.X"
    }
  ]
}

Für eine Reihe von Subdomains sollen Zertifikate erstellt werden (example.com, www.example.com, pkg.example.com, etc.). Die Adressen werden mittels Reverse Proxy an einzelne Jails weitergeleitet. Die URL /.well-known/acme-challenge/ ist auch für jede Subdomain erreichbar (also http://example.com/.well-known/acme-challenge/ geht).

Reverse Proxy
Der Reverse Proxy leitet die Sub-Domains auf die entsprechenden Jails weiter, zum Beispiel example.com und www.example.com:
Code:
    upstream www {
        server 10.0.0.3:80;
    }

    server {
        listen      80;
        server_name example.com;
        server_name www.example.com;

        client_max_body_size    1024M;
        proxy_read_timeout      300;

        location / {
            proxy_pass      http://www;
            proxy_redirect  off;
            proxy_buffering off;
        }
    }


Nginx
In den Jails laufen dann nginx-Server, die Zugriff auf /.well-known/acme-challenge/ erlauben:
Code:
    server {
        listen      80;
        server_name localhost;
        root        /var/www;
        index       index.html index.htm index.php;

        location ^~ /.well-known/acme-challenge/ {
            default_type   "text/plain";
            root           /mnt/acme;
            allow          all;
        }
    }

Das Verzeichnis /mnt/acme wird für jede Jail per nullfs durchgeschleift und zeigt auf /usr/local/www/acme der Reverse-Proxy-Jail. Klappt also alles.

Der Aufruf von
Code:
# acme-client -v example.com www.example.com pkg.example.com files.example.com bla.example.com
führt dann zu:
Code:
acme-client: adding SAN: www.example.com
acme-client: adding SAN: pkg.example.com
acme-client: adding SAN: files.example.com
acme-client: adding SAN: blah.example.com
acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
acme-client: acme-v01.api.letsencrypt.org: DNS: 104.86.32.165
acme-client: acme-v01.api.letsencrypt.org: DNS: 2a02:26f0:c6:182::3d5
acme-client: acme-v01.api.letsencrypt.org: DNS: 2a02:26f0:c6:1a4::3d5
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: example.com
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: www.example.com
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: pkg.example.com
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: files.example.com
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: blah.example.com
acme-client: /usr/local/www/acme/QHZ_OGAyY0x-dnwFWOCnKLnaoMD8AbfW_QANdFLdKgU: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/iIOSC3B_So3csAGKd0RkvDidAYio0OKfhBsLGe3cAD4/1055650489: challenge
acme-client: /usr/local/www/acme/Uk35S781YblfDkart8Hp5kIYYsjAtFpwO3RSwJzpp94: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/g-jtYrsIaf_S9Uaerbmo3N6eURhGp9q7XcnJ5okCnI4/1055650513: challenge
acme-client: /usr/local/www/acme/MM21l9S-xs4v7Hq3e5FEtQPL6MtEUe_HBebI20CqxmU: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/NsKc1rfuXt7B_Q-g6n8vH0jMLMcZ9GGgWVNdUJtgT2M/1055650551: challenge
acme-client: /usr/local/www/acme/D0ZY07_XFI89bs1oCfY31SGBcr3Pa2fH2h_VqBjnH-E: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/GzTY2G4zZP_fDWPytbG8c2gr3Yj0mO49eQgXuPIbbIk/1055650583: challenge
acme-client: /usr/local/www/acme/uEU5ZND3oJDTevpdOc-mtputChB0EyHj40av-qVwCz4: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/51aTfDiT8rJ0QKKskK8kweZ9dy4-74PiVqGDYBBmNUA/1055650601: challenge
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/iIOSC3B_So3csAGKd0RkvDidAYio0OKfhBsLGe3cAD4/1055650489: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/iIOSC3B_So3csAGKd0RkvDidAYio0OKfhBsLGe3cAD4/1055650489: bad response
acme-client: transfer buffer: [{ "type": "http-01", "status": "invalid",
"error": { "type": "urn:acme:error:unauthorized", "detail": "Invalid response
from
http://example.com/.well-known/acme-challenge/QHZ_OGAyY0x-dnwFWOCnKLnaoMD8AbfW_QANdFLdKgU:
\"\u003chtml\u003e\r\n\u003chead\u003e\u003ctitle\u003e404 Not
Found\u003c/title\u003e\u003c/head\u003e\r\n\u003cbody
bgcolor=\"white\"\u003e\r\n\u003ccenter\u003e\u003ch1\u003e404 Not
Found\u003c/h1\u003e\u003c/center\u003e\r\n\u003chr\u003e\u003ccenter\u003e\"",
"status": 403 }, "uri":
"https://acme-v01.api.letsencrypt.org/acme/challenge/iIOSC3B_So3csAGKd0RkvDidAYio0OKfhBsLGe3cAD4/1055650489",
"token": "QHZ_OGAyY0x-dnwFWOCnKLnaoMD8AbfW_QANdFLdKgU", "keyAuthorization":
"QHZ_OGAyY0x-dnwFWOCnKLnaoMD8AbfW_QANdFLdKgU.qFo0j3x81_6YnlcHVGOeaT2213OA7bhujutkrV38AlY",
"validationRecord": [ { "url":
"http://example.com/.well-known/acme-challenge/QHZ_OGAyY0x-dnwFWOCnKLnaoMD8AbfW_QANdFLdKgU", "hostname": "example.com", "port": "80", "addressesResolved": [ "X.X.X.X" ], "addressUsed": "X.X.X.X" } ] }] (1104 bytes)
acme-client: bad exit: netproc(36743): 1

Woher kommt dieser Fehler?
 
Das Problem ist, dass die Token zur Authorisierung nicht von LE geprüft werden können, da beim Aufruf der URL ein 403 kommt.
Hast du mal überprüft, ob du an die Token-Dateien direkt von Außen rankommst?

Rob
 
Die Token-Datei wird gleich wieder gelöscht. Aber ich kann auf beliebige Dateien im Pfad
/.well-known/acme-challenge
zugreifen. Also sollte auch der Let’s-Encrypt-Server Zugriff haben.
 
Fehler gefunden. In der Nginx-Konfiguration habe ich ein Slash vergessen. Korrekt heißt es:
Code:
server {
    listen 80;
    server_name localhost;
    root /var/www;
    index index.html index.htm index.php;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
       root /mnt/acme/; # <-- Slash ans Ende!
       allow all;
    }
}
 
Hmm, wenn ich das wüsste. Die "test.html" wurde jedenfalls angezeigt. Vielleicht kam die aber auch aus dem Browser-Cache. o.O
 
Zurück
Oben