Let’s Encrypt! Zertifikate & Uberspace

Geschrieben von Igor Scheller am 2. November 2015

Irgendwie hatte ich es mal geschafft, ein paar Domains für die closed Beta von Let’s Encrypt! zu registrieren, heute kam dann endlich die Mail mit der Bestätigung *freu*.

Lets Encrypt! ist eine Initiative unter anderem von Mozilla, Cisco, Akamai und der EFF, welche es sich auf die Fahne geschrieben hat, einfach, kostenlos und sichere SSL-Zertifikate anzubieten. Nachdem am 19.10.15 endlich das cross-signing der Root-CAs durch war, werden jetzt die ersten Zertifikate an Betateilnehmer ausgegeben (ick freu mir wie nen karnickel :D). Durch dieses Cross-Signing werden die Let’s Encrypt-Zertifikate von allen Browsern ohne Probleme angenommen. Ein kleines Manko könnte aktuell noch sein, dass man das Zertifikat alle 90 Tage (besser 60) erneuern muss, Let’s Encrypt arbeitet aber schon an einem verbesserten Auto-Updater, sodass man sich nicht mal mehr darum kümmern muss.

Wie bereits erwähnt, soll das Erstellen des Zertifikates sehr einfach sein, also optimal, um meine bei Uberspace gehostete Domain mit dem cert zu versehen.

Erste Schritte

Auch wenn in der Let’s Encrypt-Mail steht, dass die Installation sehr einfach ist, benötigt sie doch auf dem Webserver, auf welchem die Domain liegt, Rootberechtigungen. Das ist allerdings auf Shared-Hostern nicht gegeben -> man kann nicht die Offizielle Software verwenden. Doch auch hier findet sich schnell eine Lösung in form eines kleinen Scriptes: github.com/diafygi/letsencrypt-nosudo.

Dieses ermöglicht es, die Zertifikats-Validierung ohne Root-Rechte durchzuführen (nach einer kleinen Modifikation):

Auf dem Uberspace muss im Webroot ein neues Verzeichnis erstellt werden:

mkdir .well-known

In diesem Verzeichnis muss nun eine .htaccess-Datei mit folgendem Inhalt angelegt werden:

RewriteEngine on
RewriteRule . letsEncrypt.php

Diese leitet alle Anfragen, welche unterhalb des .well-known-Ordners ankommen auf die letsEncrypt.php, welche den folgenden Inhalt hat:

<php
header('Content-Type: application/jose+json');

echo "";

Jetzt ist alles vorbereitet und man kann nach einem

git clone https://github.com/diafygi/letsencrypt-nosudo.git

den Schritten auf der Seite folgen um das Zertifikat zu generieren.

Generieren des Zertifikates

Wenn das Script einen dazu auffordert einen Python-Code als sudo auszuführen:

[...] You need to run this command on igorshp.de (don't stop the python command until the next step).

sudo python -c "import BaseHTTPServer; \
h = BaseHTTPServer.BaseHTTPRequestHandler; \
h.do_GET = lambda r: r.send_response(200) or r.end_headers() or r.wfile.write('{\"header\": {\"alg\": \"RS256\"}, \"protected\": \"[...]\", \"payload\": \"[...]\"}'); \
s = BaseHTTPServer.HTTPServer(('0.0.0.0', 80), h); \
s.serve_forever()"

Hier muss man sich den Inhalt, beginnend mit der geschweiften öffnenden Klammer ({) und endend mit der geschweiften schließenden Klammer (}) kopieren und zwischen die doppelten Anführungszeichen des Echos im Script eingeben & im Terminal mit Enter bestätigen, sodass dieses etwa so aussieht:

<?php
header('Content-Type: application/jose+json');

echo "{\"header\": {\"alg\": \"RS256\"}, \"protected\": \"[...]\", \"payload\": \"[...]\"}";

Dadurch werden alle Anfragen nach dem schema http://[domain.tld]/.well-known/acme-challenge/[langerhashwert] mit dem angegebenen String beantwortet und damit die Domain verifiziert.

Diesen schritt muss man noch ein zweites mal wiederholen und schon hat man sein eigenes Zertifikat!

Einrichten bei Uberspace

Als letzten Schritt muss noch der .well-known-Ordner vom Server gelöscht werden und das Zertifikat auf den Uberspace gespeichert werden.
Also schnell die signed.crt und die domain.key per SSH/SFTP auf den Uberspace-Host hochladen (diese muss direkt im Home oder in einem angelegten Unterordner liegen, !NICHT! im webroot!) und mit ein paar Befehlen das einbinden vorbereiten (es wird eine user.domain.combined.pem-Datei erstellt):

wget https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem
uberspace-prepare-certificate -i lets-encrypt-x1-cross-signed.pem -k domain.key -c signed.crt

Wenn alles geklappt hat, muss nur noch eine Mail an hallo@uberspace geschrieben werden & das Zertifikat kann verwendet werden 🙂

Shorturl Kategorie: IgorsHP, Tutorials, Web Tags:

Über Igor Scheller

Kontakt: Twitter Facebook Google+

Über mich gibt es nicht viel zu sagen ;) Ich bin Technikbegeistert, mich interessiert eigentlich alles was irgendwie etwas mit Computern, Elektronik, Programmieren und Technik zu tun hat, und manchmal schreibe ich auch darüber. Wenn du mehr wissen wilst, kannst du es mir ja Mailen :D (Oder in die Kommentare schreiben (oder per Snailmail senden))

10 Kommentare

  • Dominique Müller am Freitag, 20. November 2015 um 0:23 Uhr

    Ich wollte nur schnell sagen: Danke für diesen Artikel! Der hat mich am Ende gerettet.

    Antworten
  • Jonas John am Montag, 16. November 2015 um 0:51 Uhr

    Hallo Igor, vielen Dank für die ausführliche Anleitung!

    Eine kleine Anmerkung dazu, die anderen Ubernauten helfen könnte:

    Und zwar habe ich alle Schritte wie beschrieben durchgeführt. Allerdings erhielt ich vom letsencrypt-nosudo Skript kein JSON / Python Webserver Snippet, wie im Beitrag beschrieben, sondern nur einen hash-artigen Text (r.wfile.write(‚FcABC-123xyz(…).r-UU123(…)_X11b‘). Dadurch funktionierte dann der letzte Teil deiner Anleitung mit der letsEncrypt.php Datei leider nicht mehr und ich erhielt die folgende Fehlermeldung:

    Error parsing key authorization file / Invalid key authorization: malformed key thumbprint

    Nach mehreren Versuchen und etwas googeln habe ich dann die Lösung gefunden und zwar will letsencrypt den korrekten Content-Type haben was in meinem Fall dann „text/plain“ war.

    TL;DR
    Falls ihr kein JSON bekommt einfach „application/jose+json“ durch „text/plain“ ersetzen und den hash-artigen Text anstatt des JSONs einfügen dann sollte alles klappen 🙂

    Gruß,
    Jonas

    Antworten
    • Igor Scheller am Montag, 28. Dezember 2015 um 1:28 Uhr

      Das stimmt, das wurde vereinfacht 🙂

      Jetzt reicht es, in der .htaccess-Datei folgende Zeilen stehen zu haben:


      RewriteEngine on
      RewriteRule . letsEncrypt.txt

      Die 2 Zeichenketten können dann einfach in der letsEncrypt.txt eingetragen werden, wenn das Script einen danach fragt!

      (Die Zeile aus der der Code kopier werden muss sieht übrigens so aus:)

      [...] r.end_headers() or r.wfile.write('[Diese Zeichenkette muss in die letsEncrypt.txt]'); [...]

      Antworten
  • Ben am Freitag, 13. November 2015 um 9:30 Uhr

    Muss das Zertifikat nicht alle 3 Monate erneuert werden?`Wie geht man dann vor?

    Antworten
    • Igor Scheller am Freitag, 13. November 2015 um 19:12 Uhr

      Genau, aktuell muss man die Zertifikate leider alle 3 Monate erneuern, dies kann aber auch automatisch erfolgen (cronjob etc.), allerdings ist das in dem Script leider noch nicht implementiert.

      Aber: es wird bereits ein Issue auf Github erstellt, es ist also nur noch eine Frage der Zeit 😀

      https://github.com/diafygi/letsencrypt-nosudo/issues/10

      Antworten
  • GALORE am Mittwoch, 11. November 2015 um 0:26 Uhr

    Hallo Igor!
    Vielen Dank für die Anleitung!
    Nur leider habe ich Probleme bei „Generieren des Zertifikates“. Wenn das Script einen dazu auffordert einen Python-Code als sudo auszuführen. Wenn ich den String von von { bis } in die „“ vom echo in die letsEncrypt.php eingefügt habe und dann im Terminal mit Enter bestätige bekomme ich folgende Fehlermeldung:

    Traceback (most recent call last):
    File „sign_csr.py“, line 431, in
    signed_crt = sign_csr(args.public_key, args.csr_path, email=args.email)
    File „sign_csr.py“, line 365, in sign_csr
    raise KeyError(„‚{}‘ challenge did not pass: {}“.format(i[‚domain‘], challenge_status))
    KeyError: „‚meinedomain.com‘ challenge did not pass: {u’status‘: u’invalid‘, u’tls‘: False, u’validationRecord‘:
    /* …. */
    u’error‘: {u’type‘: u’urn:acme:error:unauthorized‘, u’detail‘: u’Validation response failed to parse as JWS: square/go-jose: compact JWS format must have three parts‘}, u’type‘: u’simpleHttp‘}“

    Um den Fehler einzugrenzen, mit Webroot meinst du /var/www/virtual/$USER/ ?
    Hier wird das .well-known Verzeichnis mit der .htaccess erstellt /var/www/virtual/$USER/.well-known/.htaccess.
    Wo muss dann die letsEncrypt.php hin ?

    Irgend eine Idee was ich falsch mache ?

    Antworten
    • Igor Scheller am Freitag, 13. November 2015 um 8:19 Uhr

      Mit Webroot ist der /var/www/virtual/$USER/html/-Ordner gemeint (der LetsEncrypt-Server verbindet sich nach meinedomain.com/.well-known/***, in diesen Ordner gehört die .htaccess und die .php-Datei 🙂

      Antworten
  • JoJota am Mittwoch, 4. November 2015 um 22:41 Uhr

    Hallo Igor,
    danke für den interessanten Artikel!
    Ich bekomme bei der Installation auf meinem Uberspace leider mit dem Befehl „python sign_csr.py –public-key user.pub domain.csr > signed.crt“ nur die folgende Fehlermeldung:

    Traceback (most recent call last):
    File "sign_csr.py", line 426, in
    signed_crt = sign_csr(args.public_key, args.csr_path, email=args.email)
    File "sign_csr.py", line 18, in sign_csr
    nonce_req = urllib2.Request("{}/directory".format(CA))
    ValueError: zero length field name in format

    Irgendeine Idee woran das liegen kann?

    Gruß JoJota

    Antworten
    • Igor Scheller am Mittwoch, 4. November 2015 um 22:56 Uhr

      Hallo JoJota!

      Das liegt an der verwendeten Python Version. Dieses ist bei Uberspace standard die 2.6, benötigt wird aber mind. 2.7:
      Auf deinem Uberspace-host muss du also anstatt
      python sign_csr.py [...]
      folgenden Command benutzen:
      python2.7 sign_csr.py [...]

      Antworten
      • JoJota am Donnerstag, 5. November 2015 um 12:30 Uhr

        Hat funktioniert. Vielen Dank!

        Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.