Let’s Encrypt SSL Zertifikate mit Certbot erstellen

Mit dem Certbot kann man Zertifikate von Let’s Encrypt erstellen und automatisch auf dem Server installieren. Die Zertifikate sind kostenlos. Sie sind zwar nur 90 Tage gültig, aber dank Certbot werden diese vor Ablauf automatisch aktualisiert.

Die Installation & Konfiguration geht total schnell. Einmal eingerichtet, darf man dank dem auto-renew alles drum herum einfach vergessen. So einfach war’s bis jetzt noch nie 🙂

Installation unter FreeBSD mit NGINX

pkg install py27-certbot

Konfiguration

Es existiert aktuell noch kein eigenes Plugin für Nginx. Und ich möchte eigentlich auch nicht, dass der Client an der Nginx Config herumbastelt. Daher nutze ich den certonly Befehl mit dem Webroot Plugin. Dieses Plugin erstellt in einem Verzeichnis auf dem öffentlich zugänglichen Web eine Datei, welches bei der Zertifizierung beweist, dass die Domain unter unserer Kontrolle ist (ähnlich der Google Legimitation).

Als erstes erstellen wir die Verzeichnisse

mkdir /global/configs/letsencrypt/
mkdir /global/configs/letsencrypt_data/

Da ich die Configs auf einer global Verfügbaren Festplatte verwalte, auf die mehrere Server zugreifen, kommen die Zertifikate dann dort drauf:

ln -s /global/configs/letsencrypt_data/ /usr/local/etc/letsencrypt

Ich nutze eine globals.server Config, die ich bei jedem Virtual Host include. Dort kommt nun folgendes rein:

vi /global/nginx_global_config/globals.server
        # let's encrypt config
        location ^~ /.well-known {
auth_basic "off";
                allow all;
                root /global/configs/letsencrypt;
        }

Falls noch weitere Globale Config Files vorhanden sind, die statt globals.server included werden, dort ebenfalls die Zeilen rein machen.

vi /global/nginx_global_config/globals.serverLongTimeout

Webserver neu starten:

nxctl restart

So ist das globale Verzeichnis nun für alle Virtual Hosts dieses Webservers unter domain.ltd/.lets-encrypt erreichbar.

Nach einer Neuinstallation des FreeBSD Servers sowie Certbot, konnte der Certbot plötzlich die Zertifikate im globalen Verzeichnis nicht mehr finden.

Meine Config sieht ja so aus:

ln -s /global/configs/letsencrypt_data/ /usr/local/etc/letsencrypt

bisher hat das einwandfrei funktioniert.

Doch auf dem neu installierten Server kam nun dieser Error:

# certbot certificates

Saving debug log to /var/log/letsencrypt/letsencrypt.log
The following error was encountered:
[Errno 77] No locks available
Either run as root, or set --config-dir, --work-dir, and --logs-dir to writeable paths.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

-> er kann aber offensichtlich auf das Verzeichnis zugreifen, denn er erstellt ein .certbot.lock file. Aber trotzdem gibt es den Error.

Das Problem, wurde dadurch ausgelöst, dass es Schwierigkeiten beim Erstellen von Sperren (Locks) auf dem Dateisystem gibt, das über den Symlink /usr/local/etc/letsencrypt auf das globales Verzeichnis /global/configs/letsencrypt_data/ zugreift. Das Fehler „No locks available“ (Keine Sperren verfügbar) tritt häufig auf, wenn ein Dateisystem oder ein Speichermedium verwendet wird, das keine Dateisperren unterstützt, wie es bei einigen Netzwerkdateisystemen (NFS, CIFS) der Fall sein kann.

Lösung (bei der Verwendung von NFSv3)

Damit Locks unterstützt werden (unter NFSv3), benötigt man zusätzlich zu rpcbind_enable noch folgende Einträge im /etc/rc.conf:

Hinweis: NFSv4 integriert das Locking direkt in das Protokoll und benötigt keine zusätzlichen Dienste wie rpc.statd oder rpc.lockd. Welche NFS Version verwendet wird, kann man mit dem Befehl nfsstat -m herausfinden.

rpcbind_enable="YES"
rpc_statd_enable="YES"
lockd_enable="YES"

Danach die fehlenden Services starten (auf Server und Client!):

service rpc.statd start
service lockd start

 

Nun Zertifikat anfordern

Einzelnes Zertifikat

certbot certonly --webroot -w /global/configs/letsencrypt -d www.teslina.com 

Man kann auch gleich mehrere Domains in einem Zertifikat auf einmal anlegen

certbot certonly --webroot -w /global/configs/letsencrypt -d www.domain.com -d www2.domain.com -d www3.domain.com -d mail.domain.com

so werden alle weiteren Domains in einem einzigen Zertifikat zusammengestellt. Man macht hier aber jeweils am Besten immer nur diese Domains zusammen, die auch zusammen gehören. Denn das Zertifikat listet dann unter „Ausgestellt für“ -> „Allgemeiner Name (CN)“ den ersten Domain in der Liste auf. Im oberen Beispiel also www.domain.com

 

Nun muss man einige Fragen beantworten, danach wird das Cert generiert:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.teslina.com
Using the webroot path /global/configs/letsencrypt for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /usr/local/etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /usr/local/etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /usr/local/etc/letsencrypt/live/www.teslina.com/fullchain.pem. Your
   cert will expire on 2017-08-02. To obtain a new or tweaked version
   of this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

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

Jetzt noch die Zertifikate im Config angeben (ich verweise hier auf meinen globalen Speicherort, ansonsten wäre es natürlich unter /usr/local/etc/[..].) und Webserver neu starten:

   server {
            listen       80;
            server_name  teslina.com www.teslina.com;
            return       301 https://www.teslina.com$request_uri;
    }

    server {
        listen       443 ssl http2;
        server_name  www.teslina.com;
        ssl on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_certificate /global/configs/letsencrypt_data/live/www.teslina.com/fullchain.pem;
        ssl_certificate_key /global/configs/letsencrypt_data/live/www.teslina.com/privkey.pem;

       [..]

     }

Wildcard Zertifikate mit NGINX und BIND (*.domain.com)

Auch das ist möglich:

  1. Zertifikat anfordern:
    sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.domain.com --manual --preferred-challenges dns-01 certonly

    Das ergibt dann so einen Output:

    Please deploy a DNS TXT record under the name
    _acme-challenge.domain.com with the following value:
    KEY_DER_GENERIERT_WURDE
    Before continuing, verify the record is deployed.

  2. DNS Eintrag machen:
    _acme-challenge IN TXT "KEY_DER_GENERIERT_WURDE"

    Und am Ende des DNS Eintrags muss natürlich auch der Wildcard Eintrag drin sein, falls noch nicht vorhanden:
    * IN A IP_ADRESSE

  3. Nachdem der DNS gerefreshed wurde, Cert-Generierung im Certbot abschliessen.
  4. Am Ende NGINX Config Entry machen für die Wildcard Domain mit den Configfiles wie sie vom Certbot ausgegeben wurden:

    server {
      listen 443 ssl;
      server_name test.domain.com *.domain.com;
      root /www/domain.com/test;
      access_log /logs_www/domain.com/access_log piwik;

      ssl on;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

      ssl_certificate /global/configs/letsencrypt_data/live/domain.com/fullchain.pem;
      ssl_certificate_key /global/configs/letsencrypt_data/live/domain.com/privkey.pem;

      location / {
        try_files $uri $uri/ index.php;
      }

      # include my global configuration file
        include global/globals.server;
    }

  5. NGINX neu starten

    nxctl configtest
    nxctl testart

 

Nun müsste alles wie gewünscht funktionieren.

Auto Renew Wildcard Certs

Wildcard Zertifikate lassen sich nicht wie reguläre Zertifikate automatisch erneuern (Beschreibung weiter unten). Wenn man das versucht, kommt folgender Fehler:

The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.

Das geht nur über ein Plugin, wie hier beschrieben. Ohne Plugin muss man die Zertifikate manuell erneuern:

certbot certonly --manual -d '*.domain.com'

Den neu generierten Key wieder manuell im DNS Eintrag hinterlegen und im Certbot bestätigen.

Email Notification bei Wildcard Certs

Bisher hat man von Let’s Encrypt Emails erhalten, wenn die Zertifikate ablaufen. Dies war vorallem bei den Wildcard Zertifikaten wichtig, da hier das Auto-Renew nicht funktionierte. Let’s Encrypt stellt diesen Service per 04.06.25 ein.

Wenn man weiterhin Email Notifications erhalten möchte, kann man externe Dienste, wie z.B. Red Sift nutzen, um die Zertifikate zu überwachen.

 

Mail Zertifikate

Die Zertifikate kann man auch mit Sendmail nutzen! Einfach noch die Subdomain -d mail.domain.com beim generieren dazufügen und danach Sendmail noch entsprechend konfigurieren:

define(`CERT_DIR', `/global/configs/letsencrypt_data/live/mail.domain.com')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confCACERT', `CERT_DIR/chain.pem')dnl
define(`confSERVER_CERT', `CERT_DIR/cert.pem')dnl
define(`confSERVER_KEY', `CERT_DIR/privkey.pem')dnl

Damit Sendmail happy ist, noch die Berechtigung ändern:

cd /global/configs/letsencrypt_data/live/mail.domain.com
chmod 600 privkey.pem

Danach Sendmail neu starten & fertig 🙂

rcsendmail restart

Zertifikate automatisch erneuern

Den Script um die Zertifikate zu erneuern, sollte man zur Sicherheit 2x täglich laufen lassen. Die Zertifikate werden nur dann erneuert, wenn sie kurz vor Ablauf stehen.

Damit alle Berechtigungen nach der Erneuerungen greifen, erstmal ein kleines Script erstellen:

vi /global/cronjobs/global/certbot.sh 
#!/bin/sh
/usr/local/etc/rc.d/nginx reload
/bin/chmod 600 /global/configs/letsencrypt_data/live/*/privkey.pem
# restart sm-mta
/etc/rc.d/sendmail restart
# restart dovecot
/usr/local/etc/rc.d/dovecot restart 2>/dev/nul
chmod 775 /global/cronjobs/global/certbot.sh 

Nun den Cronjob einrichten. Als renew-hook, das soeben erstellte Script angeben.

crontab -e

und folgende Zeile hinzufügen

0       */12    *       *       *       /usr/local/bin/certbot renew --renew-hook "/global/cronjobs/global/certbot.sh" > /dev/null 2>&1

So werden Zertifikate bei Bedarf automatisch erneuert und – sofern etwas erneuert wurde – auch nginx & sendmail automatisch gereloaded.

Zertifikate löschen

Benötigt man gewisse Zertifikate nicht mehr, kann man sie einfach löschen mit:

certbot delete

Bestehende Zertifikate auflisten

certbot certificates

Bestehendes Zertifikat ergänzen

Manchmal kommt eine weitere Subdomain dazu. Man könnte einfach ein neues Zertifikat anfordern oder aber die Domain per –expand hinzufügen:

certbot certonly --webroot --cert-name www.domain.com -w /global/configs/letsencrypt --expand -d www.domain.com -d www2.domain.com -d www3.domain.com -d www4.domain.com

Bitte beachte: Man muss ALLE Domains erneut auflisten, sonst werden sie aus dem Zertifikat gelöscht.

bei –cert-name gibt man den Namen des zu ergänzenden Zertifikates an (Namen kann man mit certbot certificates anzeigen)

Probleme / Fehlermeldungen

Certbot hängt bei „Running deploy-hook command“

Das Problem tauchte auf, nachdem ich von Sendmail zu Dovecot gewechselt bin. Der Renew Script hat sich nicht mehr beendet und lief endlos im Hintergrund (und hat daher auch nicht mehr sauber renewed)

Waiting for verification...
Cleaning up challenges
Running deploy-hook command: /global/cronjobs/global/certbot.sh

Lösung

Die Lösung habe ich in diesem Forum gefunden: GitHub

Einfach im Hook Script – in meinem Fall: /global/cronjobs/global/certbot.sh – den Output von Dovecot unterdrücken:

vorher:

#!/bin/sh
/usr/local/etc/rc.d/nginx reload
/bin/chmod 600 /global/configs/letsencrypt_data/live/*/privkey.pem
/etc/rc.d/sendmail restart
/usr/local/etc/rc.d/dovecot restart

nachher:

#!/bin/sh
/usr/local/etc/rc.d/nginx reload
/bin/chmod 600 /global/configs/letsencrypt_data/live/*/privkey.pem
/etc/rc.d/sendmail restart
/usr/local/etc/rc.d/dovecot restart 2>/dev/null

 

Servername mismatch

Wenn man beim Testen zwar ein OK erhält, aber der Servername falsch ist:

Testen:

openssl s_client -connect www.teslina.com:443 -servername www.teslina.com

Output:

CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = www.falschedomain.com
verify return:1
---
Certificate chain
0 s:/CN=www.falschedomain.com
i:/C=US/O=Let's Encrypt/CN=R3

Auch wenn das Zertifikat zum Beispiel als reine Mail Domain (z.B. mail.teslina.com) verwendet wird, ist es notwenig, den Webserver trotzdem dafür zu konfigurieren. Folgende Zeilen in der Webserver (NGINX) Config sind daher mindestens notwenig:

server {
listen 443 ssl;
ssl on;
ssl_certificate /global/configs/letsencrypt_data/live/mail.teslina.com/fullchain.pem;
ssl_certificate_key /global/configs/letsencrypt_data/live/mail.teslina.com/privkey.pem;
server_name mail.teslina.com;
}

Danach Webserver neu starten. Nun müsste das korrekte Zertifikat ausgegeben werden:

nxctl configtest
nxctl restart

openssl s_client -connect mail.teslina.com:443 -servername mail.teslina.com

Output:

CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = mail.teslina.com
verify return:1
---
Certificate chain
0 s:/CN=mail.teslina.com
i:/C=US/O=Let's Encrypt/CN=R3

„OpenSSL SSL_connect: SSL_ERROR_SYSCALL“ // no „ssl_certificate“ is defined in server listening on SSL port while SSL handshaking, client: xx.xx.xx.xx, server: 0.0.0.0:443

Nach einer Änderung in meiner SSL Config, hab ich plötzlich im Firefox den Fehler

OpenSSL SSL_connect: SSL_ERROR_SYSCALL

erhalten. Im nginx-error.log gabs danach massenweise den Fehler;

no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: xx.xx.xx.xx, server: 0.0.0.0:443

In meinem Fall lag das Problem darin, dass ich in der NGINX Config keinen Default Server für den Port 443 definiert hatte. Ärgerlich war jedoch, dass ich den Fehler beim configtest nicht angezeigt bekommen hatte; erst als ich die Page im Browser öffnen wollte :-/

Daher ist es total wichtig, dass pro Webserver immer für jeden Port ein „default_server“ ausgewählt. Jedoch nur bei EINEM EINZIGEN Virtual host. Daher am Besten diesen Entry für den Reverse Server Name eintragen.

# default / reverse server name
server {
    listen 443 default_server; # Hier wird `ssl` nicht angegeben
    server_name servername.meindomain.com;
    #...
}

#regulaere virtual hosts
server {
    listen 443 ssl;
    server_name meinedomain.com;
    #...
}

openssl Verify return code: 10 (certificate has expired) [2021-09-30 Issue]

Plötzlich funktionierten diverse Server Scripts nicht mehr, die zum Beispiel per fsockopen auf ssl Webseiten connecteten. Versuchce vom selben Server per links oder openssl die Seiten zu öffnen, gaben immer einen Cert Expiry Fehler an – obwohl sich die Webseite im Browser problemlos öffnen liess und das  Expiry Datum auch korrekt angezeigt wurde.

links https://www.teslina.com

gab zurück

+---------------------------------------  Invalid certificate ---------------------------------------+
| The server www.teslina.com doesn't have a valid certificate. Do you want to connect to it anyway? |

Test mit openssl:

openssl s_client -connect www.teslina.com:443 -servername www.teslina.com

gab zurück

CONNECTED(00000003)
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
---
Certificate chain
 0 s:/CN=www.teslina.com
   i:/C=US/O=Let's Encrypt/CN=R3
 1 s:/C=US/O=Let's Encrypt/CN=R3
   i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
 2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFJDCCBAygAwIBAgISAwU2TOm3cD6dryRbM73RsnEhMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTEwMDQwNjU3MTdaFw0yMjAxMDIwNjU3MTZaMBoxGDAWBgNVBAMT
D3d3dy50ZXNsaW5hLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJ8Q5sWvFz5MnV436JI/EBmzJ1e7hrfh2fgQCMCzxJcW86x1AmTKDJ2Hv2GuU1Gc
syY8z4WVCw4t99A4Miw0Qo1V0T0lLr4C7emYVdMBToeIAV0KyW1m0c0RYpBmfA9e
7dU4upx6YTK3N23mR5qkfnW3X8S3xwkUDTbhDwvF4XklBUBQM7Fw0jOGRvvmQKpC
z3LXyH2fU8W3byFNhDpqYTdF2IhAA8dTZ+DCvRhu4cOZbSaSenFsql+o3JJ0HWkc
O6+PnwEFoC/alGTPJcaoiz6xUp5bFdKoIDxlOAtrqNWSP1bqwz1eJHSbo3MawKUM
D49/nE6OTqtXawXu1+D9FIUCAwEAAaOCAkowggJGMA4GA1UdDwEB/wQEAwIFoDAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNV
HQ4EFgQUluOq5ctybqR0mx2BcFxm43Pyh0cwHwYDVR0jBBgwFoAUFC6zF7dYVsuu
UAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8v
cjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9y
Zy8wGgYDVR0RBBMwEYIPd3d3LnRlc2xpbmEuY29tMEwGA1UdIARFMEMwCAYGZ4EM
AQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0
c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYAQcjKsd8iRkoQ
xqE6CUKHXk4xixsD6+tLx2jwkGKWBvYAAAF8Sk6aBQAABAMARzBFAiAssEXfHLif
D5er4ZVwMJ7NSczlQeXt4XXtLlfjn/7aAwIhAME4k/mjoE69o73ekMro8Ilu2EPG
Ci2LKf/HNi1KuMgCAHYARqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUcA
AAF8Sk6akwAABAMARzBFAiBjnulkj4o7ghaz0gWLG0Nz4uainnvxApIO9lXjvy/A
QgIhAN5lft16dg52jehQxZLWxNydOfX3C2h3jFf0YH/Uq3evMA0GCSqGSIb3DQEB
CwUAA4IBAQCwEsWbIZPV9sd53GZP3yUMxRUDQlGnNARIjWTCw2zBkZvz4bZHFWcw
y3aQ+XXsulgBloH0hnF8iaVbKmyaZ4PBIKA3DSm/+0BSNUA3yozMtN11QkYlA28L
JOimwoEaEKPxTAA7js1QYlIrni/cUYkCX8DCwpWZTyaN/m6D0NfzSx8FCkR8fhQs
0tRwEPevHI6iNnzRyNfziQsJ44DsMVLlNhePp6sA8OlnIJQ4zW0eG5CCMA8gqyfC
6T4TObrJssr0QBRzCAxx95zvmhfIbox7uVkij1/Sw07up+Nq+WwNj6R8kigkNeB3
0riut8waJUZAZTDSKfFR7z2wA0qJjxey
-----END CERTIFICATE-----
subject=/CN=www.teslina.com
issuer=/C=US/O=Let's Encrypt/CN=R3
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4707 bytes and written 457 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: ECF9540797A6B01ACED8653C1887885A107402D0E7CA35FCE42C618AC164523E
    Session-ID-ctx: 
    Master-Key: D24F4B23134C3579475DB48345A117A8067A2818F11B2B525D5A6F4C7CB63A8B9DF3FFCD5334AAFEF02D1FA63640DF92
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - e3 f0 1e e4 7a 79 ff b5-76 bc c5 7d e5 db 27 f1   ....zy..v..}..'.
    0010 - c9 1b 6a f6 3a 01 e5 d2-f2 4d 0b a2 01 fa a0 cb   ..j.:....M......
    0020 - 5d 7d 16 11 92 7c 62 76-ea 61 fc 36 82 a2 3d 9c   ]}...|bv.a.6..=.
    0030 - 53 ca e0 51 6b be 73 21-0e 7b 36 ed 74 c6 71 cb   S..Qk.s!.{6.t.q.
    0040 - 41 17 16 e3 f7 fe ab 99-a0 ac f2 ad b6 88 b4 2e   A...............
    0050 - fe 18 97 22 be 2f e4 99-93 d4 5c 8c 0d 20 24 c1   ..."./...... $.
    0060 - a6 23 99 1c 6b 4f 7a 5c-d1 0e 34 eb c3 d2 55 70   .#..kOz..4...Up
    0070 - 5b ec a6 57 e9 80 e5 80-82 11 c7 e6 1a e3 3a c3   [..W..........:.
    0080 - 4e 15 e9 f2 18 69 6e bd-86 96 e0 9d 10 2f 44 79   N....in....../Dy
    0090 - 5c c8 67 e6 66 1d 04 ce-a2 5e 7e 5d df b6 84 bd   .g.f....^~]....
    00a0 - bd 4c 8e 6f 9e f0 88 35-06 3d 6b 8c a9 40 2d 66   .L.o...5.=k..@-f
    00b0 - 3e fd fc c9 02 ef df a7-b6 57 c5 37 9a 29 99 5f   >........W.7.)._

    Start Time: 1633338121
    Timeout   : 300 (sec)
    Verify return code: 10 (certificate has expired)

Und hier bekam ich kurioserweise sogar 2 unterschiedliche „notAfter“ Daten zurück. (02. Januar 2022 wäre das korrekte Expiry Date – und nicht der 30. September).

openssl s_client -connect www.teslina.com:443 -servername www.teslina.com| openssl x509 -noout -dates 

output:

depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
notBefore=Oct 4 06:57:17 2021 GMT
notAfter=Jan 2 06:57:16 2022 GMT

Nach langem Suchen bin ich endlich auf die Lösung gekommen, dass das Problem am DST Root CA X3 Zertifikat liegt, welches expired ist. Den ersten Hinweis dazu fand ich in einem Blogbeitrag bei OpenSSL. Von Let’s Encrypt gibt es hier auch einen offiziellen Beitrag zu diesem Problem.

OpenSSL hat diverse Lösungswege aufgezeigt für OpenSSL Clients mit Version 1.0.2.

Eigene OpenSSL Version auslesen:

$ openssl version
OpenSSL 1.0.2o-freebsd 27 Mar 2018

 

Lösung: Root Zertifikate aktualisieren

Lösung 1: Update einfach die Server Root Zertifikate:

 pkg install security/ca_root_nss

Lösung 2: Lösche einfach das DST Root CA X3 vom bestehenden Root Zertifikat

Zeige aktuelles SSL Verzeichnis an, welches OpenSSL benutzt:

$ openssl version -d 
OPENSSLDIR: "/etc/ssl"
$ cd /etc/ssl
$ ls -l

total 12
lrwxr-xr-x 1 root wheel 38 Feb 7 2019 cert.pem -> /usr/local/share/certs/ca-root-nss.crt
-rw-r--r-- 1 root wheel 10910 Jul 10 2018 openssl.cnf

Also das Root Zertifikat bearbeiten

vi /usr/local/share/certs/ca-root-nss.crt

–> suche nach DST Root CA X3 und LÖSCHE DAS CA X3 CERT aus der Liste:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3
        Validity
            Not Before: Sep 30 21:12:19 2000 GMT
            Not After : Sep 30 14:01:15 2021 GMT
        Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:df:af:e9:97:50:08:83:57:b4:cc:62:65:f6:90:
                    82:ec:c7:d3:2c:6b:30:ca:5b:ec:d9:c3:7d:c7:40:
                    c1:18:14:8b:e0:e8:33:76:49:2a:e3:3f:21:49:93:
                    ac:4e:0e:af:3e:48:cb:65:ee:fc:d3:21:0f:65:d2:
                    2a:d9:32:8f:8c:e5:f7:77:b0:12:7b:b5:95:c0:89:
                    a3:a9:ba:ed:73:2e:7a:0c:06:32:83:a2:7e:8a:14:
                    30:cd:11:a0:e1:2a:38:b9:79:0a:31:fd:50:bd:80:
                    65:df:b7:51:63:83:c8:e2:88:61:ea:4b:61:81:ec:
                    52:6b:b9:a2:e2:4b:1a:28:9f:48:a3:9e:0c:da:09:
                    8e:3e:17:2e:1e:dd:20:df:5b:c6:2a:8a:ab:2e:bd:
                    70:ad:c5:0b:1a:25:90:74:72:c5:7b:6a:ab:34:d6:
                    30:89:ff:e5:68:13:7b:54:0b:c8:d6:ae:ec:5a:9c:
                    92:1e:3d:64:b3:8c:c6:df:bf:c9:41:70:ec:16:72:
                    d5:26:ec:38:55:39:43:d0:fc:fd:18:5c:40:f1:97:
                    eb:d5:9a:9b:8d:1d:ba:da:25:b9:c6:d8:df:c1:15:
                    02:3a:ab:da:6e:f1:3e:2e:f5:5c:08:9c:3c:d6:83:
                    69:e4:10:9b:19:2a:b6:29:57:e3:e5:3d:9b:9f:f0:
                    02:5d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:
                C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10
    Signature Algorithm: sha1WithRSAEncryption
         a3:1a:2c:9b:17:00:5c:a9:1e:ee:28:66:37:3a:bf:83:c7:3f:
         4b:c3:09:a0:95:20:5d:e3:d9:59:44:d2:3e:0d:3e:bd:8a:4b:
         a0:74:1f:ce:10:82:9c:74:1a:1d:7e:98:1a:dd:cb:13:4b:b3:
         20:44:e4:91:e9:cc:fc:7d:a5:db:6a:e5:fe:e6:fd:e0:4e:dd:
         b7:00:3a:b5:70:49:af:f2:e5:eb:02:f1:d1:02:8b:19:cb:94:
         3a:5e:48:c4:18:1e:58:19:5f:1e:02:5a:f0:0c:f1:b1:ad:a9:
         dc:59:86:8b:6e:e9:91:f5:86:ca:fa:b9:66:33:aa:59:5b:ce:
         e2:a7:16:73:47:cb:2b:cc:99:b0:37:48:cf:e3:56:4b:f5:cf:
         0f:0c:72:32:87:c6:f0:44:bb:53:72:6d:43:f5:26:48:9a:52:
         67:b7:58:ab:fe:67:76:71:78:db:0d:a2:56:14:13:39:24:31:
         85:a2:a8:02:5a:30:47:e1:dd:50:07:bc:02:09:90:00:eb:64:
         63:60:9b:16:bc:88:c9:12:e6:d2:7d:91:8b:f9:3d:32:8d:65:
         b4:e9:7c:b1:57:76:ea:c5:b6:28:39:bf:15:65:1c:c8:f6:77:
         96:6a:0a:8d:77:0b:d8:91:0b:04:8e:07:db:29:b6:0a:ee:9d:
         82:35:35:10
SHA1 Fingerprint=DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

Und Tadaaaaaaa, die openssl Verbindung funktioniert nun einwandfrei:

openssl s_client -connect www.teslina.com:443 -servername www.teslina.com

Returns now ok:

[...]
Start Time: 1633339204
Timeout : 300 (sec)
Verify return code: 0 (ok)

Nun funktionieren auch die Server Scripts wieder wie gewohnt.

.

 

nach oben