Kategorien
Allgemein Systemadministration Technologien

Let’s Encrypt: Public Beta – Seit 3. Dezember kann nun jeder kostenlose Zertifikate erstellen – Update

Bislang war Let’s Encrypt nur mit Warteliste bzw. mit Einladung für einen beschränkten Benutzerkreis verfügbar. Seit heute kann nun jeder den Dienst nutzen und sich selbst kostenlose Zertifikate erstellen lassen. Was Let’s Encrypt ist wurde bereits dem Artikel „Beta Phase für gratis SSL Zertifikate von Let’s Encrypt “ beschrieben. Nun soll es darum gehen erste Zertifikate zu erstellen.

Allgemein

Die automatische Zertifikats-Erstellung wird über ein neues Protokoll abgewickelt. Dieses wurden von Let’s Encrypt, nicht ganz ohne Augenzwinkern, „ACME“ genannt und übernimmt die Kommunikation mit dem Let’s Encrypt CA Server. Den dazu gehörigen Client  können wir ganz leicht auf unserem Linux Server installieren. Dieser übernimmt bei Bedarf neben der Zertifikats-Anforderung auch die Installation bei unserem Webserver. Clients für andere Betriebssysteme sollen bald folgen.

Let’s Encrypt Zertifikate sind immer nur 90 Tage gültig. Daher sollten diese unbedingt automatisch erneuert werden um abgelaufene Zertifikate zu vermeiden.

Allgemeine Informationen zu Let’s Encrypt finden sich unter anderem bei Caschys Blog, Golem und Heise.

Let’s Encrypt Client installieren

Den Client kann man sich bequem über Github herunterladen. Ggf. ist dafür vorher die Installation von git auf dem Server erforderlich. Stand dieses Eintrags ist dies die Version 0.5.0.

cd /opt
sudo git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Der letsencrypt Client verwendet selbst Python. Beim ersten Aufruf versucht dieser aber die notwändigen Programme selbst nachinstallieren. Unter Ubuntu klappt dies problemlos.

Eine Liste aller verfügbaren Optionen erhält mit mit dem Parameter –help all.

./letsencrypt-auto --help all

Die verschieden Methoden um Zertifikate zu erstellen

Der Let’s Encrypt Client kann die Zertifikate über verschiedene Methoden bestätigen und beziehen. Entweder über ein Apache PlugIn, als Standalone-Server oder über eine Datei im DocumentRoot des Servers. Für den Standalone Betrieb muß der eigentliche Webserver kurzzeitig beendet werden.  Bei den anderen Methoden wird der Betrieb dagegen nicht unterbrochen. Die Zertifikate werden in einem /etc/letsencrypt Ordner gespeichert. Zusätzlich fragt der Client nach einer E-Mail Adresse um Zertifikate bei Datenverlust wiederherstellen zu können.

Vollautomatischer Modus

Ruft man den Client ohne Parameter auf, versucht dieser die Art Webservers und dessen konfigurierte Domains zu erkennen und bietet eine Auswahl an der Domains für die Zertifikate installiert werden sollen.

cd /opt/letsencrypt
./letsencrypt-auto

Bei ab vom Standard konfigurierten Servern könnte dies jedoch fehlschlagen. Ein Backup der Konfiguration wäre hier vorher ratsam.

Installation mit Dateien im DocumentRoot

In diesem Modus erstellt der Client Dateien im DocumentRoot der Domain und lässt diese vom CA Server abrufen und überprüfen. Dies entspricht am ehesten der bislang üblichen Vorgehensweise für domain-validierte Zertifikate. Probleme können entstehen wenn die Webseite z.B. Rewrites verwendet um Suchmaschinen freundliche URLs zu erstellen. Hier kann es passieren dass die Dateien dann nicht direkt abrufbar sind und das Zertifikat nicht validiert werden kann.

cd /opt/letsencrypt
./letsencrypt-auto certonly -d domain.tld --webroot

Mit certonly sagen wir dem Client er soll die Zertifikate nicht gleich installieren. Und die Dateien im webroot (DocumentRoot) der Domain domain.tld ablegen. Ggf. kann der Client das Verzeichnis nicht ermitteln dann müsste mit –webroot-path=/var/www/… nachgeholfen werden.

Das Zertifikate findet sich dann unter /etc/letsencrypt/live/domain.tld/.. Auf dieselbe Weise wurde übrigens das Zertifikat für diesen Blog erstellt. Der Nachteil hierbei ist natürlich dass wegen certonly die Zertifikate nur im Livesystem landen. Die Einrichtung muss manuell erfolgen und das zusätzlich noch alle 90 Tage denn länger sind die Zertifikate nicht gültig.

Zertifikate für mehrere Domains und Sub-Domains.

Es ist auch möglich ein Zertifikat für mehrere Domains zu erstellen.

cd /opt/letsencrypt
./letsencrypt-auto certonly -d domain.tld -d www.domain.tld -d mail.domain.tld --webroot -w /var/www/domain.tld/htdocs

Verwendung des Standalone modus

Um gar nicht erst Probleme mit der Konfiguration diverses Webserver und Webseiten zu riskieren lässt sich letsencrypt auch im Standalone-Modus betreiben. Dann simuliert der Client einen Webserver und validiert so das Zertifikat. Hier ein Beispiel:

./letsencrypt-auto certonly --standalone -d domain.tld

Dabei muss Port 80 auf dem Server frei sein also vorhandene Webserver kurzzeitig herunter gefahren werden.

Resultat:

Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --standalone -d domain.tld

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/domain.tld/fullchain.pem. Your
   cert will expire on 2016-03-01. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Zertifikate automatisch erneuern

Da die Zertifikate nur 90 Tage gültig sind macht es wenig Sinn diese manuell immer wieder zu erneuern. Der letsencrypt Client kann dabei helfen diese automatisch zu erledigen. Dabei ist es auch kein Problem die Zertifikate z.B. jeden Monat zu verlängern.

Hier wird auf Seiten von Let’s Encrypt noch gearbeitet. Der Client speichert schon alle wichtigen Daten der Erstellung. Somit könnte ein letsencrypt-auto -d domain.tld eigentlich ausreichen. Aktuell wird man aber an der Konsole gefragt ob man erneuern oder abbrechen will. Verwendet man den Parameter –renew-by-default wird zwar automatisch erneuert also nicht extra gefragt. Jedoch verwendet der Client dann nicht mehr die Einstellung vom letzten mal.

Somit ist aktuell der Weg per cronjob denselben Aufruf wie bei der Erstellung ergänzt durch ein –renew-by-default auszuführen. Ggf. bei standalone davor den Apache bzw NginX noch zu beenden und am Ende neu zu starten.

Bei Multi-Domain/ISP Servern ist das aktuelle Limit von 10 Zertifikaten pro Tag ggf. auch ein Problem. Im Let’s Encrypt Forum gibt es schon erste Scripte die erst prüfen wie lange Zertifikate noch gültig sind. Diese laufen dann jeden Tag und falls ein Zertifikat ansteht wird es erneuert. Diese sind aber noch unausgereift.

Einfaches Let’s Encrypt renewal Script

Es folgt eine kleine PHP Datei die vorhandene Let’s Encrypt Zertifikate sucht überprüft und bei baldigem Ablauf verlängert. Aktuell geht das Script davon aus das die Verlängerung immer klappt. Wegen dem Limit an Anfragen pro Tag und IP kann dies beim Testen schon mal schief gehen. Auch werden nur die Zertifikate erneuert und nichts an der Konfiguration geändert.

Falls standalone Zertifikate erneuert werden wird der Apache vorher beendet und am Schluss wieder gestartet.

#!/usr/bin/php

// Let's Encrypt automated renewal tool
// To be put in /etc/cron.daily
//
// https://ufie.de/en/lets-encrypt-public-beta-starting-today-lets-encrypt-now-open-everyone/
//
// Author: Christian Stengel <christian.stengel@gmail.com>
// 

//  Let's Encrypt config dir
$CONF_DIR="/etc/letsencrypt";
// Let's Encrypt binary
$CMD="/opt/letsencrypt/letsencrypt-auto";
// Openssl binary
$SSLBIN="/usr/bin/openssl";
// Apache restart script
$APACHETOOL="/etc/init.d/apache2";
// Name of apache process
$APACHENAME="apache2";
// Remaining days before renewal
$MAX_DAYS="7";

// Don't change anyting below this point

$certs=array();$standalone=$apache_on=false;$apache_turned_off=false;$certs_total=$certs_renewed=0;

// Is apache running
if (shell_exec('ps ax | grep '.$APACHENAME.' | wc -l'))
   $apache_on=true;

// Search for letsencrypt certs
if (is_dir($CONF_DIR.'/live') && ($dh = opendir($CONF_DIR.'/live')))
{
   echo '###########################################################################'."\n";
   echo 'Renew Let\'s Encrypt Certificates '."\n";
   echo '###########################################################################'."\n";
   while (( $cert = readdir($dh)) !== false)
   {
      if (substr($cert,0,1)==".") continue;
      // Configuration found?
      if ($conf = simple_parse_config($CONF_DIR.'/renewal/'.$cert.'.conf'))
      {
         echo "\n";
         echo '##### Cert: '.$cert."\n";
         $certs_total++;
         $temp_standalone=false;

         // Check if server reload needed (standalone config)
         if (isset($conf["standalone"]) && (strtolower($conf["standalone"])=="true"))
         {
            $standalone=true;
            echo 'Type: standalone'."\n";
            $temp_standalone=true;
         }
         // Cert file found?
         if (is_file($conf['cert']))
         {
            $date=shell_exec($SSLBIN.' x509 -noout -dates -in '.$conf['cert'].' | grep notAfter');
            list($foo,$date)=explode("=",$date);
            $date=strtotime($date);
            echo 'Valid until: '.date("Y-m-d H:i:s",$date)."\n";

            // Calculate remaining days
            $days = floor(($date-time())/24/3600);
            echo 'Remaining days: '.$days."\n";

            // Up for reneal?
            if ($days<=$MAX_DAYS)
            {
               echo 'Renew today: yes'."\n";

               // Shut down apache
               if ($temp_standalone && $apache_on && !$apache_turned_off)
               {
                  echo 'Standalone: Shutting down apache'."\n";
                  shell_exec($APACHETOOL.' stop');
                  $apache_turned_off=true;
               }

               $return=shell_exec('echo "R" | '.$CMD.' certonly '.($temp_standalone?'--standalone':'').' -t -d '.$cert);
               $certs_renewed++;

               // ToDo: check for errors

            } echo 'Renew today: false'."\n";
         } else { echo "Error: cert file missing"; continue; }
      }
   }
   closedir($dh);
   echo "\n";
   echo '###########################################################################'."\n";
   echo "Certs total: ".$certs_total."\n";
   echo "Certs renewed: ".$certs_renewed."\n";
   // Restart Apache if necessary otherweise reload
   if ($apache_turned_off && $apache_on)
   {
      echo 'Standalone: Restarting apache'."\n";
      shell_exec($APACHETOOL.' start');
   }
   else if ($apache_on && ($certs_renewed>0 ))
   {
     echo 'Apache: reload'."\n";
     shell_exec($APACHETOOL.' reload');
   }
   echo '###########################################################################'."\n";
   echo "\n";
}
else
   die('No certs in '.$CONF_DIR.'/live');


function simple_parse_config ($file)
{
   $conf=array();
   if (!file_exists($file)) return false;
   $temp = file($file);
   foreach ($temp as $foo => $bar) { if (strpos($bar,"=")!==false) { list($var,$val) =explode("=",$bar); if (trim($var)) { $conf[trim($var)]=trim($val); } } }
   return $conf;
}

?>

 

Von Christian Stengel

Geek, PHP Entwickler, Linux Admin

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.