Frage zu Zertifikaten / SSL / Fehlermeldung bei openssl

Hallo.
Unser v7-Server hat ein gültiges LE-Zertifikat. Ein Zugriff per https:// auf den Server bestätigt das. Wenn ich aber vom bionic-Client (oder einem anderen Client im grünen Netz) aus diesen Befehl verwende:

openssl s_client -connect server:636
erhalte ich ganz oben:
verify error:num=20:unable to get local issuer certificate
verify return:1
und ganz unten:
Verify return code: 21 (unable to verify the first certificate)
(gleiches auf Port 443).
Ich frage mich warum bzw wie es richtig sein müsste?
@mdt – du kennst dich doch damit aus, oder? Was fehlt da bzw was ist falsch konfiguriert?

Übrgigens: die o.g. Meldungen erscheinen sogar dann, wenn ich auf dem Server selbst bin und es dort mit openssl s_client -connect server:443 versuche. Auf Port 636 scheint es hingegen zu funktionieren. Auf 636 erscheint unten Verify return code: 0 (ok) – also so wie es sein sollte. Ist das bei Euch auch so?

Schönen Gruß,
Michael

Das klingt, als sei noch das „self-signed“ Zertifikat aktiv. Schick doch mal den Part hinter „Certificate chain“, das ist die Kette der Zertifikate. Taucht da nur ein „0 … CN=…lan“ auf, ist es self-signed. LE hat ja

Certificate chain
 0 s:CN = emdete.de
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
 2 s:O = Digital Signature Trust Co., CN = DST Root CA X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

also eine Kette von 3 Zertifikaten.

Hi.
Ok, wenn ich das auf der firewall mache, erhalte ich auch das hier:

---
Certificate chain
 0 s:CN = firewall.linuxmuster.meine-domain.de
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---

Wenn ich aber auf dem Server das gleiche versuche, erhalte ich

---
Certificate chain
 0 s:O = Gymnasium ..., OU = LINUXMUSTER, CN = server.linuxmuster.meine-domain.de, subjectAltName = server.linuxmuster.meine-domain.de
   i:O = Gymnasium ..., OU = LINUXMUSTER, CN = LINUXMUSTER.MEINE-DOMAIN.DE, subjectAltName = LINUXMUSTER.MEINE-DOMAIN.DE
---

Es sieht also alles danach aus, als wäre LE hier gar nicht im Spiel? Wir hatten dieses Thema ja vor längerer Zeit schon mal. Mittlerweile habe ich aber die LE-Zertifikate nach /etc/linuxmuster/ssl/ kopiert – aber die anderen certs (die seit der Installation da sind), habe ich nicht gelöscht. Das ist wahrscheinlich der Fehler! Ich bin aber nicht wie vor nicht ganz sicher, welche da weg können und welche nicht. Kannst du vielleicht den Inhalt des Ordners posten?
Schöne Grüße,
Michael

Wenn die Namensgebung sinnvoll ist, sind es die Dateien

-rw-r--r-- 1 root root     2822 Feb 17 15:04 server.cert.bundle.pem
-rw-r----- 1 root ssl-cert 1143 Feb 17 15:01 server.cert.pem
-rw-r----- 1 root ssl-cert  976 Feb 17 15:01 server.csr
-rw------- 1 root ssl-cert 1679 Feb 17 15:01 server.key.pem

Die .csr brauchst du nicht (mehr), das ist der cert.signing request. Alle sind im .pem Format. .key ist der (private!) key. Wenn dein LE-Cert für diesen Key ist, bleibt der auch. Das Cert ist in .cert. Das .bundle ist eine Kombination aus private Key und Cert (manche Programme mögen das so).

Self-signed heisst ja im Grunde, dass du selbst deine CA bist. Die CA hat ihr Cert in cacert.crt (und cacert.pem - identische Datei)

/etc/ajenti/config.yml
/etc/samba/smb.conf

ajenti hat nur ein Setting und braucht das bundle:

certificate: /etc/linuxmuster/ssl/server.cert.bundle.pem

Hier mußt du die Teile einfach aneinanderhängen.

Samba macht’s hübsch, da stehn die 3 Teile separat:

tls enabled = yes
tls keyfile = /etc/linuxmuster/ssl/server.key.pem
tls certfile = /etc/linuxmuster/ssl/server.cert.pem
tls cafile = /etc/linuxmuster/ssl/cacert.pem
tls verify peer = ca_and_name

Hier solltest du deine Keys/Certs von LE konfigurieren und gut sollte sein.

Ok – an dieser Stelle war ich vor einiger Zeit schon mal. Was ist besser: die certs einfach umzubenennen und die Einträge in den .conf-Dateien so zu lassen oder umgekehrt? ich denke fast, dass der erste Weg besser ist, da man dann keine Stelle übersieht, oder?

Ja, vermutlich, dann stimmen die Namen auch. Du kannst von dem Verzeichnis ja vorher eine Sicherheitskopie machen, dann kommst du schnell zurück. Du musst allerdings auch die Bundle-Datei erzeugen.

Oh, und die Konfiguration von Samba braucht das andre Cert (LE), das würde ich wohl da drin umstellen.

Wie meinst Du das?

Hi.
Also ich habe vorhin nochmal auf den Server und auf den Host geschaut, der die LE-Zertifikate anfordert (das macht hier direkt die OPNSense-Firewall über das LE-Plugin). Die unterschiedliche Benennung der Dateien hatten wir ja kürzlich schon diskutiert … ich blicke leider trotzdem noch nicht ganz durch. so dass ich nochmal beides gegenüberstelle:

Auf dem Server gibt es (wie schon von dir zitiert):

-rw-r--r-- 1 root root     2822 Feb 17 15:04 server.cert.bundle.pem
-rw-r----- 1 root ssl-cert 1143 Feb 17 15:01 server.cert.pem
-rw-r----- 1 root ssl-cert  976 Feb 17 15:01 server.csr
-rw------- 1 root ssl-cert 1679 Feb 17 15:01 server.key.pem

Daneben gibt es auf dem Server aber auch noch:

-rw-r----- 1 root ssl-cert 1648 Feb 19 12:54 cacert.crt
-rw-r----- 1 root ssl-cert 1648 Feb 19 12:54 cacert.pem
-rw-r----- 1 root ssl-cert 1812 Sep 14 16:28 cacert.pem.b64
-rw-r----- 1 root ssl-cert   41 Sep 14 16:28 cacert.srl
-rw------- 1 root ssl-cert 1766 Sep 14 16:28 cakey.pem

Auf der anderen Seite, sieht das gleiche Verzeichnis so aus:

-rwxr-x---  1 root  wheel  1648 Jan 29 10:08 ca.cer*
-rwxr-x---  1 root  wheel  3933 Jan 29 10:08 fullchain.cer*
-rwxr-x---  1 root  wheel  2285 Jan 29 10:08 server.linuxmuster.meine-domain.de.cer*
-rwxr-x---  1 root  wheel  1700 Jan 29 10:08 server.linuxmuster.meine-domain.de.csr*
-rwxr-x---  1 root  wheel  3243 Nov 21 11:32 server.linuxmuster.meine-domain.de.key*

Ich habe also alles auf den Server nach /etc/linuxmuster/ssl rüberkopiert und umbenannt, und zwar:

server.linuxmuster.meine-domain.de.cer --> server.cert.pem
server.linuxmuster.meine-domain.de.csr --> server.csr
server.linuxmuster.meine-domain.de.key --> server.key.pem

(bis hierhin eindeutig, meine ich)
Aber dann:

ca.cer --> cacert.crt (??)
ca.cer --> cacert.pem (??)

Wenn ich jetzt den Befehl openssl s_client -connect server:443 loslasse, erhalte ich leider weiterhin nur:

---
Certificate chain
 0 s:CN = server.linuxmuster.meine-domain.de
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---

… aber die o.g. verify error bleiben.
Leider ist mir die Rolle der ca-Zertifikate sowie der fullchain (im Vergleich zum bundle) nicht ganz klar.

Hier ein gescheites HowTo, wo mal die Basics vernünftig erklärt werden. Natürlich gibt’s was offizielles – das ist aber über 300 Seiten stark und liest sich nicht mal kurz nebenbei.

Wie gesagt: openssl s_client -connect firewall:443 liefert die Fehler nicht, so dass der Fehler auf der Serverseite liegen muss.
@mdt: Blickst du noch durch?

Schönen Gruß,
Michael

:smiley: Ich versuch’s mal: Die Full-Chain plus der (Private-)Key ist das bundle. Da du https testest und das bundle nicht erneuert hast, das vom https-Dienst genutzt wird, ist das Verhalten erklärlich.

Ich denke ein

cat fullchain.cer server.linuxmuster.meine-domain.de.key > server.cert.bundle.pem

plus Neustart des https-Dienstes macht, was du brauchst. Das Full ist ca + server (1648 + 2285 = 3933 passt).

Ja, cacert.crt und cacert.pem sind identisch (schau diff cacert.crt cacert.pem zeigt keine Unterschiede - jedenfalls bei mir). Also ca.cer auf beide kopieren (schau dir das ca.cer an mit openssl x509 -noout -in "ca.cer" -subject, da sollte dann ja was mit LE auftauchen).

Dass die FW korrekt ist, liegt daran, dass du ja das LE-Script da laufen lässt und das Script da alles richtig einrichtet. Aber eben nicht für den Server (der ja auch die andren Zertifikate bekommt).

Hi.
Ok, ich habe den cat Befehl ausprobiert. Das bundle ist jetzt 7175 groß.
Danach systemctl restart linuxmuster-webui – der Zugriff auf die WebUI über https://server…:443 liefert weiterhin ein gültiges LE-Zertifikat aber die Verbindung via openssl liefert weiterhin den gleichen Fehler.

Das LE-Plugin erstellt die Zertifitkate für den Server im grünen Netz.

Das funktioniert und liefert:
subject=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

Merkwürdig finde ich aber trotzdem, dass ich trotz des neuen bundles immernoch dies erhalte:

openssl s_client -showcerts -connect server:443
CONNECTED(00000005)
depth=0 CN = server.linuxmuster.meine-domain.de
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = server.linuxmuster.meine-domain.de
verify error:num=21:unable to verify the first certificate
verify return:1
---

vgl auch hier: Five Essential OpenSSL Troubleshooting Commands - MovingPackets.net
---> This can be fixed by adding the -CAfile option ... Vielleicht ist es das?
Immerhin Licht am Ende des Tunnels:
openssl verify -CAfile ./cacert.pem server.cert.pem
server.cert.pem: OK
aber ohne die Option -CAfile bekomme ich:
error server.cert.pem: verification failed

Kann es sein, dass das cacert.pem global bekannt gemacht werden muss? Sowas hatten wir doch schon mal diskutiert – und zwar hier?!

(Ich denke, dass das Verhalten auch mit dem HAProxy (reverse Proxy) zusamenhängen könnte – bin aber nicht ganz sicher…)

Schönen Gruß,
Michael

Moment - das verstehe ich nicht. Das hattest du bislang nicht gesagt, dass für den Server etwas funktioniert. Ich hatte verstanden FW geht, Server nicht.

Ich bin durch die Architektur von LM noch nicht ganz durchgestiegen. Im Grunde müssen alle Komponenten, die hinter der Domain SSL/TLS anbieten das Zertifikat mit dem gleichnamigen oder passenden Wildcard CN anbieten und eine Kette runter zu einem akzeptierten root-Zertifikat sonst wirds nix.

Der Hinweis mit dem CAfile gilt, wenn du ein eigenes root-CA nennen möchtest.

Du hast aber noch das Zertifikat, was du garnicht haben möchtest: Die self-signed Zertifikate. openssl sollte eben eine Chain anzeigen… die beruhen auf einem Zertifikat, das openssl kennt und dann brauchst du CAfile garnicht.

Ich vermute erstmal, dass da eine Komponente ist, die ein restart braucht oder auch eine Konfigurationsänderung.

Bei mir läuft unter :443 ein ajenti-panel, dass in /usr/local/bin installiert ist. Das hat die config in /etc/ajenti/config.yml, die sollte nach deiner Kopiererei passen, da dort certificate: /etc/linuxmuster/ssl/server.cert.bundle.pem referenziert wird.

Das Logfile ist in /var/log/ajenti/ajenti.log, vielleicht findest du da was?

Jetzt klappt’s :+1: … und im Nachhinein hätte ich mal besser schon im November 2019 direkt auf Dich gehört, als Du meintest:

:wink:

Letztlich fehlte auf dem Server die gleiche Vorgehensweise wie damals mit dem self-signed-cert. Also hier nochmal die Vorgehensweise, die zum Ziel führt.
Eine kleine Ergänzung aber noch:
Ich habe unter
/usr/local/share/ca-certificates/ ein Verzeichnis server.linuxmuster.LE angelegt und dort einen Link erstellt:
linuxmuster-LE.crt -> /etc/linuxmuster/ssl/server.cert.pem
Anschließend dann update-ca-certificates und DANN funktioniert auch die Verbindung über openssl auf Port 443

Unter’m Strich ist es gar nicht soooooooo kompliziert, wenn man erstmal durchgestiegen ist, wie sich so eine trusted chain zusammensetzt. Da hat der Link von oben ordentlich geholfen…

Besten Dank mal wieder!
Michael

P.S.:

Doch – im allerersten Satz ganz oben…

Eine Sache musst du mir aber doch noch(mal) erklären: Wenn ich es nun von einem anderen Client aus versuche, erhalte ich erneut Verify return code: 21 (unable to verify the first certificate):thinking:?! Heißt das: die gleiche Prozedur auf jedem Client, der openssl verwenden will, von vorne??

Sag’ ich doch! :wink:

Nein. Das muß etwas anderes sein, denn der Server schickt ja das Zertifikat. Du hast auf dem Client openssl gegen den server gemacht, richtig? Das mit dem richtigen servernamen (domain), die auch CN in dem zertifikat ist, ja? Gibt er die Kette denn an? Oder ist es wieder dies eine Ding wo „CN = LINUXMUSTER.MEINE-DOMAIN.DE“ steht?

Nicht ganz: da steht, dass Samba geht, denn der hat port 636.

Ja – aber auch, wenn ich den kompletten FQDN server.linuxmuster.meine-domain.de wähle, kommt wieder genau wie zuvor:

```
openssl s_client -showcerts -connect server.linuxmuster.meine-domain.de:443
CONNECTED(00000005)
depth=0 CN = server.linuxmuster.meine-domain.de
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = server.linuxmuster.meine-domain.de
verify error:num=21:unable to verify the first certificate
verify return:1
---

Kann es damit zusammenhängen, dass ich vorher schon mit self-signed-certs herumexperimentiert hatte und das auf dem Client evtl schon mal akzeptiert wurde?

Ich denke, dass die weiterhin zu kurz ist, oder?

---
Certificate chain
 0 s:CN = server.linuxmuster.meine-domain.de
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---

Ist bei dir länger, oder?

Noch höher: → „Ein Zugriff per https:// auf den Server bestätigt das.“

Ergänzend:

https://blog.pki.dfn.de/2014/10/skript-zum-testen-der-zertifikatkette-und-sslv3-faehigkeit-eines-servers/

Hallo Michael,

relativ einfach: Das Zertifikat gilt nur für den FQDN als server.meine-doma.in nicht für den Kurznamen. Wenn du den Server mit dem FQDN abfragst, solltest du keinen Zertifikatsfehler bekommen.

Gruß

Thomas

Mit freundlichen Grüßen
Thomas Jordan
Technik

email_indasys_innovative.jpg
Innovative Datensysteme GmbH indasysLeitzstraße 4c

D-70469 Stuttgart

Telefon:

Telefax:

E-Mail:

Web:
+49 711 896659 193

+49 711 896659 149

Thomas.Jordan@indasys.de

www.indasys.de

didacta-2020.jpg

Jetzt anmelden:

https://www.indasys.de/anmeldung-didacta-2020/

USID: DE199226070

HRB: 19846 AG Stuttgart

Geschäftsführer: Victor Ferreira, Dominik Appich

Hallo Thomas
Nein, daran liegt es aber leider nicht … erst wenn ich das intermediate cacert.pem unter /usr/local/share/ca-certificates verlinke und danach ein update-ca-certificates durchführe, funktioniert die Verbindung ohne die verfify-error-Meldung vom Client aus.
Die Chain ist dann aber auch weiterhin so kurz wie schon zuvor geschrieben

Eigentlich sollte es aber so sein, dass das intermediate-cert mit vom server heruntergeladen wird, oder?!

Die Datei server.cert.bundle.pem unter /etc/linuxmuster/ssl besteht übrigens aus dem eigenen cert, dem intermediate-cert und dem RSA Key – auch in der richtigen Reihenfolge und die WebUI wurde auch neu gestartet

Schönen Gruß,
Michael

Das war ja vermutlich im Browser. Der Browser hat mit OpenSSL nichts zu tun.

Ich bin nicht ganz sicher, dass ich verstehe von wo aus du welche Tests abfeuerst. Ich würde erstmal schauen, was in deinen Zertifikaten steht. Mach dich auf dem Server einmal:

cd /etc/linuxmuster/ssl; for n in *.crt* *.cert*; do echo -n $n; openssl x509 -noout -in $n -subject; done

Das gibt dir (bis auf bei dem Bundle und dem .b64) aus, was das subject der Zertifikate ist.

(Die Antwort kam per PN und die Ausgabe sah korrekt aus)

Dieser Befehl zeigt dir die Chains der Dienste auf dem Server, es sollte auf dem Server laufen:

for n in  443 464 631 636 3269 ; do echo $n; echo -n|openssl s_client -connect localhost:$n 2> /dev/null | sed -n '/^Certificate chain/,/^---$/p' ; done

Selbst bei mir, wo ich die Zertifikate nicht angefasst habe zeigt das eine Inkonsistenz. Wie siehts bei dir aus?

Port 631 sieht bei mir auch falsch aus. Das scheint noch ein Fehler im Gesamtsetup zu sein.

Certificate chain
 0 s:CN = server.....
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---

Da fehlt das Intermediate-Certificate, es sollte so aussehen

Certificate chain
 0 s:CN = server.....
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
 2 s:O = Digital Signature Trust Co., CN = DST Root CA X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

Also stimmt die Konfiguration noch nicht.

443 bedient ajenti, das in /etc/ajenti/config.yml konfiguriert wird unter „certificate“, da steht das Bundle. Ich verstehe nicht warum der das Intermediate nicht nutzt, wenn es im Bundle drin ist. Kann ajenti Intermediates?

636 bedient samba, das hat in smb.conf „tls *file“. Das Intermediate soll in cafile konfiguriert werden - das hast du ja. Selbe Frage wie oben…