[Let's Encrypt|https://letsencrypt.org] ist eine Organisation, die kostenlose SSL-Zertifikate herausgibt. Diese Zertifikate werdeen von allen normalen Browsern und Betriebssystemen inzwischen anerkannt. Dadurch ist es möglich, einfach und preiswert grosse Teile des Internets sicher zu verschlüsseln.

Grundsätzlich arbeitet Let's Enrypt vollautomatisch, ohne dabei die Sicherheit zu gefährden. Um das zu erreichen, sind Zertifikate immer nur 90 Tage gültig. Eine automatische Software (z.B. certbot) muss diese regelmässig erneuern.

Um zu beweisen, das man Besitzer der Domain ist, um die es geht (also um sich zu authentifizieren), muss der Anwender (also am besten, aber nicht zwingend, dessen Software) eine sogenannte Challenge bestehen. Das kann z.B. sein, das man eine Datei mit einem bestimmten Namen und Inhalt auf einen Webserver schiebt um zu beweisen, das man diesen Webserver "besitzt".

Man kann auch wildcard-Zertifikate (also sowas wie *.lug-kr.de) erhalten. Dazu muss man allerdings eine Nameserver-Challenge bestehen (also einen Eintrag in die Nameserver-Konfiguration schieben können).

= certbot =

Unter Linux benutzt man, um ein SSL-Zertifikat zu bekommen, das Programm [certbot|https://certbot.eff.org/docs/intro.html]. Es arbeitet mit Plugins für verschiedene Arten der Authentifizierung und Installation.

Ein Aufruf wie der folgende macht in den meisten Fällen schon alles, was man braucht:

  certbot --apache

In der Folge läuft certbot per crontab regelmäßig automatisch und prüft, ob auf dem Rechner Zertifikate erneuert werden müssen. Ggf. macht es dieses dann direkt automatisch.


== kompliziertes Beispiel ==

Als ein etwas komplizierteres Beispiel möchte ich ein Zertifikat für eine Subdomain haben, die ich bei Domainfactory gehostet habe. Diese unterstützen leider keinerlei Automatisierung.

Ich möchte das Zertifikat benutzen, um intern damit zu experimentieren. Das bedeutet, ich möchte einen caldav-Server unter caldav.thomasbayen.de in meinem lokalen Netz einrichten. Dazu verbiege ich die Domain in meinem lokalen Nameserver. Diese Vorgehensweise erlaubt es mir, mit dem Server zu experimentieren und hn zu testen, ohne ihn direkt offen ins Internet stellen zu müssen. Damit das allerdings hübsch funktioniert, sollte der interne Server ein ordentlich signiertes, also "offizielles" Zertifikat erhalten.

Als Vorbereitung habe ich bei Domainfactory einen Webspace eingerichtet und einen ftp-Zugang, mit dem ich diese erreichen kann. Für den Anfang zeigt der Webspace auf meine Hauptdomain. Die ftp-Zugangsdaten habe ich in ~/.nettrdc gespeichert (siehe man netrc) und dann erstmal ausprobiert, ob ich Kontakt bekomme.

  echo ls | ftp -p ftp.thomasbayen.de

Danach habe ich im Webspace die von LetsEncrypt gewünschten Verzeichnisse angelegt:

  echo mkdir webseiten/.well-known | ftp -p ftp.thomasbayen.de
  echo mkdir webseiten/.well-known/acme-challenge | ftp -p ftp.thomasbayen.de

Nun habe ich als nächstes den certbot aufgerufen. Mit diesem simplen Befehl ist das im Grunde auch schon getan. Das "--manual" sorgt dafür, das das Programm auf der Konsole schön einfach und höflich nach allem fragt, was es so wissen will. Es legt einerseits einen Account für mich an (der dann in /etc/letsencrypt gespeichert wird). Andererseits startet es eine Challenge, die ich dann in einem zweiten Konsolenfenster per copy & paste ausgeführt habe.

  sudo certbot certonly --manual --preferred-challenges http

  nano challenge.txt
  echo put challenge.txt webseiten/.well-known/acme-challenge/555SWVCrc-Rq-ZlGpYfC417c8z-w0Lw4dZyHG_fza_w | ftp -p ftp.thomasbayen.de

Am Ende habe ich mein Zertifikat und meinen privaten Schlüssel in /etc/letsencrypt/live/caldav.thomasbayen.de/. Von dort aus kann ich sie dann weiterkopieren.

=== weitere Automatisierung ===

Diesen Vorgang muss ich nun all 2-3 Monate manuell durchführen, was natürlich nicht so schön ist. Eine weitere Automatisierung kann man mit Hooks machen ( https://certbot.eff.org/docs/using.html#hooks ).

Ich habe dieses Skript authenticator.sh geschrieben, das mit meinem Domainfactory-Account zusammenarbeitet.

  #!/bin/bash
  echo "authenticator.sh von Thomas Bayen wird ausgeführt für 
  Domain $CERTBOT_DOMAIN"
  echo $CERTBOT_VALIDATION >/tmp/certbot_validation
  echo put /tmp/certbot_validation webseiten/.well-known/acme-challenge/$CERTBOT_TOKEN | ftp -p $CERTBOT_DOMAIN
  rm /tmp/certbot_validation

Dazu nehme ich dann folgendes Skript (zertifikate_erneuern.sh), um das neue Zertifikat zu erzeugen und mit diesem Hook-Skript die Authentifizierung durchzuführen und sodann das Zertifikat direkt zu installieren:

  #!/bin/bash
  DOMAIN=calendar.thomasbayen.de
  sudo certbot certonly --manual --preferred-challenges http \
  --manual-auth-hook /home/tbayen/Projekte/SSL/authenticator.sh \
  --keep-until-expiring \
  -d $DOMAIN
  scp /etc/letsencrypt/live/$DOMAIN/fullchain.pem root@$DOMAIN:/var/davical/config/ssl/$DOMAIN-fullchain.pem
  scp /etc/letsencrypt/live/$DOMAIN/privkey.pem root@$DOMAIN:/var/davical/config/ssl/$DOMAIN-privkey.pem
  ssh root@$DOMAIN "podman restart davicalcontainer"

''Bemerkung: Die bisher benötigte Option --manual-public-ip-logging-ok ist [seit certbot 1.10.0|https://community.letsencrypt.org/t/certbot-1-10-0-release/139518] ersatzlos weggefallen.''


= Links hier im Wiki =

* PJACJavaACMEClient
* CaCert
* OpenSSL

[{Tag Community SSL}]