adminForge

free | no tracking | no logging | no advertising

Das ist unser Motto. Mit adminForge bieten wir kostenlose Dienste an. Unser Ziel ist es, eine freie und datensparsame Alternative zu bekannten Diensten bereitzustellen. Seit 2014 betreiben wir adminForge gemeinsam mit Spaß an der Technik und an Open-Source.

Let’s Encrypt via acme.sh für Apache und Nginx

Ende 2015 bin ich auf das Thema Webserver SSL Optimierung: HSTS und HPKP eingegangen. Nun möchte ich euch ein kleines Update zu Let’s Encrypt mit dem acme.sh Script für Apache und Nginx geben. Die Anleitung basiert auf dem ACME Webroot Verfahren, ein Stoppen des Webservers wie beim Standalone Verfahren ist nicht nötig.

Apache2

Punkt 1: Apache Webserver vorbereiten

Wir aktivieren zuerst das Headers, SSL und Rewrite Modul.

a2enmod headers
a2enmod ssl
a2enmod rewrite

Erstellen eine globale Alias Datei (gültig für alle vHosts).

Alias /.well-known /var/www/letsencrypt/.well-known
<Directory /var/www/letsencrypt>
        Require all granted

        ##Use this for old Apache 2.2
        # Order allow,deny
        # Allow from all
</Directory>

oder für Apache >=2.4

Alias /.well-known /var/www/letsencrypt/.well-known
<Directory /var/www/letsencrypt>
        Require all granted

        ##Use this for old Apache 2.2
        # Order allow,deny
        # Allow from all
</Directory>

Bei der 2. Variante aktivieren wir die Konfiguration noch.

a2enconf letsencrypt.conf

Jetzt legen wir den Alias-Ordner an und verteilen die korrekten Rechte.

mkdir -p /var/www/letsencrypt/.well-known
chown www-data. /var/www/letsencrypt -R

Die CipherSuite wird auf einen aktuellen Stand gebracht (hier gibt es aktuelle Ciphers cipherli.st).

SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite "HIGH+kEECDH+AESGCM:HIGH+kEECDH:HIGH+kEDH:HIGH:!aNULL"

Apache neustarten.

service apache2 restart
- oder -
systemctl restart apache2

Punkt 2: Let’s Encrypt: acme.sh

Wir installieren acme.sh. Dies ist ein schlankes Shell Script welches jede Let’s Encrypt Funktion wie issue, renew, cronjob etc. mit sich bringt. Es wird automatisch ein Cronjob angelegt der täglich ein renew für alle Domains anfragt.

apt install -y socat
curl https://get.acme.sh | sh
source .bashrc
acme.sh --set-default-ca --server letsencrypt
acme.sh --set-default-chain --preferred-chain "ISRG" --server letsencrypt

Einen Ordner für die Zertifikate legen wir in folgender Datei fest, ich empfehle den bereits vorhandenen Ordner /etc/ssl/private.

CERT_HOME="/etc/ssl/private"

Wir schließen das Konsolenfenster und verbinden uns zum Server neu, um die Umgebungsvariable von acme.sh zu laden. Das Script ist nun direkt ausführbar.

Punkt 3: Zertifikat erstellen

Beginnen wir mit einem Test, die obigen Einstellungen sollten zuerst immer mit „–test“ geprüft werden. Let’s Encrypt lässt nur 5 Versuche in 7 Tagen zu, danach ist die Domain temporär gesperrt. Ich empfehle in diesem Zuge von 2048-Bit oder 4096-Bit RSA Keys gleich auf das modernere ec-256 (ECDSA P-256) zu wechseln. Zum einen bringt dies eine höhere Sicherheit und zum anderen sind die Keys kürzer und somit performanter.

acme.sh --issue --test -k ec-384 -w /var/www/letsencrypt -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload apache2.service"

TIPP: Wenn der Alias /var/www/letsencrypt nicht funktioniert, könnt ihr auch den DocumentRoot verwenden.

acme.sh --issue --test -k ec-384 -w /var/www/html/DOMAIN.de -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload apache2.service"

Sollte die Verifizierung erfolgreich gewesen sein, findet ihr folgende Dateien wieder.

localhost:~# ls -lah /etc/ssl/private/DOMAIN.de
insgesamt 36K
drwxr-xr-x 2 root root 4,0K Jul 12 08:00 .
drwxr-xr-x 6 root root 4,0K Jul 12 15:37 ..
-rw-r--r-- 1 root root 1,7K Jul 12 08:00 DOMAIN.de.cer
-rw-r--r-- 1 root root  528 Jul 12 08:00 DOMAIN.de.conf
-rw-r--r-- 1 root root  574 Jul 12 07:59 DOMAIN.de.csr
-rw-r--r-- 1 root root  302 Jul 12 07:59 DOMAIN.de.key
-rw-r--r-- 1 root root  314 Jul 12 07:59 DOMAIN.de.ssl.conf
-rw-r--r-- 1 root root 1,7K Jul 12 08:00 ca.cer
-rw-r--r-- 1 root root 3,3K Jul 12 08:00 fullchain.cer

Diesen Ordner können wir löschen, da mit „–test“ die Staging API von Let’s Encrypt genutzt wird und nur Fake Zertifikate ausgestellt werden.

rm -r /etc/ssl/private/DOMAIN.de

Das echte Zertifikat kann nun ausgestellt werden. (--force um das Testzertifikat zu überschreiben)

acme.sh --issue -k ec-384 -w /var/www/letsencrypt -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload apache2.service" --force
- oder -
acme.sh --issue -k ec-384 -w /var/www/html/DOMAIN.de -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload apache2.service" --force

Punkt 4: Zertifikat in Apache einbinden

Wir editieren unsere vHost Config und fügen das soeben erstelle Zertifikat sowie Security Headers ein.

Ich möchte an dieser Stelle darauf hinweisen, dass ich Public Key Pinning (HPKP) in dieser Anleitung bewusst außenvor lasse um ein eventuelles Aussperren von Besuchern zu verhindern. Wer sich dieser Gefahr bewusst ist, kann gerne meiner Anleitung folgen.

<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
...
</VirtualHost>

<VirtualHost *:443>
...
# SSL Zertifikat
SSLEngine on
SSLCertificateFile /etc/ssl/private/DOMAIN.de/fullchain.cer
SSLCertificateKeyFile /etc/ssl/private/DOMAIN.de/DOMAIN.de.key
SSLCertificateChainFile /etc/ssl/private/DOMAIN.de/ca.cer

# Hardening Apache2 Headers
Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Xss-Protection "1; mode=block"
Header always set X-Content-Type-Options nosniff
...
</VirtualHost>

Apache neustarten.

service apache2 restart
- oder -
systemctl restart apache2

Das Ergebnis prüfen wir auf SSL Labs und Security Headers.

 

nginx

Punkt 1: Nginx Webserver vorbereiten

Wir erstellen die nötigen Ordner und eine globale Datei die in jeden vHost „included“ wird. Das vereinfacht späteres Anpassen.

mkdir /etc/nginx/global
mkdir -p /var/www/letsencrypt
chown www-data. /var/www/letsencrypt -R

location /.well-known/acme-challenge {
    root /var/www/letsencrypt;
    default_type "text/plain";
    try_files $uri =404;
}

location / {
    return 301 https://$host$request_uri;
}

Für die globalen SSL Einstellungen legen wir ebenfalls eine Datei an. Die Ciphers werden auf einen aktuellen Stand gebracht (hier gibt es aktuelle Ciphers cipherli.st). Auch die Security Headers werden hier hinterlegt.

ssl_dhparam /etc/nginx/dhparams.pem;
ssl_buffer_size 1400;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_early_data on;
ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EDH+CHACHA20:EDH+AESGCM:!DSS;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_ecdh_curve X25519:P-384:P-256:P-521;
resolver_timeout 5s;
add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" always;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;

Falls noch nicht vorhanden, legen wir eine dhparams Datei an.

openssl dhparam -out /etc/nginx/dhparams.pem 4096

Nginx neustarten.

service nginx restart
- oder -
systemctl restart nginx

Punkt 2: Let’s Encrypt: acme.sh

Wir installieren acme.sh. Dies ist ein schlankes Shell Script welches jede Let’s Encrypt Funktion wie issue, renew, cronjob etc. mit sich bringt. Es wird automatisch ein Cronjob angelegt der täglich ein renew für alle Domains anfragt.

apt install -y socat
curl https://get.acme.sh | sh
source .bashrc
acme.sh --set-default-ca --server letsencrypt
acme.sh --set-default-chain --preferred-chain "ISRG" --server letsencrypt

Einen Ordner für die Zertifikate legen wir in folgender Datei fest, ich empfehle den bereits vorhandenen Ordner /etc/ssl/private.

CERT_HOME="/etc/ssl/private"

Wir schließen das Konsolenfenster und verbinden uns zum Server neu, um die Umgebungsvariable von acme.sh zu laden. Das Script ist nun direkt ausführbar.

Punkt 3: Zertifikat erstellen

Beginnen wir mit einem Test, die obigen Einstellungen sollten zuerst immer mit „–test“ geprüft werden. Let’s Encrypt lässt nur 5 Versuche in 7 Tagen zu, danach ist die Domain temporär gesperrt. Ich empfehle in diesem Zuge von 2048-Bit oder 4096-Bit RSA Keys gleich auf das modernere ec-256 (ECDSA P-256) zu wechseln. Zum einen bringt dies eine höhere Sicherheit und zum anderen sind die Keys kürzer und somit performanter.

acme.sh --issue --test -k ec-384 -w /var/www/letsencrypt -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload nginx.service"

TIPP: Wenn die Location /var/www/letsencrypt nicht funktioniert, könnt ihr auch den Root verwenden.

acme.sh --issue --test -k ec-384 -w /var/www/html/DOMAIN.de -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload nginx.service"

Sollte die Verifizierung erfolgreich gewesen sein, findet ihr folgende Dateien wieder.

localhost:~# ls -lah /etc/ssl/private/DOMAIN.de
insgesamt 36K
drwxr-xr-x 2 root root 4,0K Jul 12 08:00 .
drwxr-xr-x 6 root root 4,0K Jul 12 15:37 ..
-rw-r--r-- 1 root root 1,7K Jul 12 08:00 DOMAIN.de.cer
-rw-r--r-- 1 root root  528 Jul 12 08:00 DOMAIN.de.conf
-rw-r--r-- 1 root root  574 Jul 12 07:59 DOMAIN.de.csr
-rw-r--r-- 1 root root  302 Jul 12 07:59 DOMAIN.de.key
-rw-r--r-- 1 root root  314 Jul 12 07:59 DOMAIN.de.ssl.conf
-rw-r--r-- 1 root root 1,7K Jul 12 08:00 ca.cer
-rw-r--r-- 1 root root 3,3K Jul 12 08:00 fullchain.cer

Diesen Ordner können wir löschen, da mit „–test“ die Staging API von Let’s Encrypt genutzt wird und nur Fake Zertifikate ausgestellt werden.

rm -r /etc/ssl/private/DOMAIN.de

Das echte Zertifikat kann nun ausgestellt werden. (--force um das Testzertifikat zu überschreiben)

acme.sh --issue -k ec-384 -w /var/www/letsencrypt -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload nginx.service" --force
- oder -
acme.sh --issue -k ec-384 -w /var/www/html/DOMAIN.de -d DOMAIN.de -d www.DOMAIN.de --reloadcmd "systemctl reload nginx.service" --force

Punkt 4: Zertifikat in Nginx einbinden

Wir editieren unsere vHost Config und fügen das soeben erstelle Zertifikat sowie Security Headers ein.

Ich möchte an dieser Stelle darauf hinweisen, dass ich Public Key Pinning (HPKP) in dieser Anleitung bewusst außenvor lasse um ein eventuelles Aussperren von Besuchern zu verhindern. Wer sich dieser Gefahr bewusst ist, kann gerne meiner Anleitung folgen.

server {
        listen 80;
        server_name DOMAIN.de www.DOMAIN.de;
        include /etc/nginx/global/redirect.conf;
}
...
server {
        listen 443 ssl http2;
        server_name DOMAIN.de www.DOMAIN.de;
        ...
        ssl_certificate      /etc/ssl/private/DOMAIN.de/fullchain.cer;
        ssl_certificate_key  /etc/ssl/private/DOMAIN.de/DOMAIN.de.key;
        ssl_trusted_certificate /etc/ssl/private/DOMAIN.de/ca.cer;
        include /etc/nginx/global/ssl.conf;
        ...

Nginx neustarten.

service nginx restart
- oder -
systemctl restart nginx

Das Ergebnis prüfen wir auf SSL Labs und Security Headers.

UnterstützenDas Betreiben der Dienste, Webseite und Server machen wir gerne, kostet aber leider auch Geld.
Unterstütze unsere Arbeit mit einer Spende.