Ich habe hier eine opnsense mit ntopng auf einem FreeBSD (als VM auf Proxmox) am laufen. Nun möchte ich die Rest API von ntopng nutzen. Das funktioniert auch soweit, allerdings sind einige Daten ausschließlich SSL Verschlüsselt (HTTPS) abrufbar.
Das alles ist ja soweit ganz gut. Auf dem Webserver (Debian 13 als Container auf Proxmox), auf dem ich die Daten abrufen mag funktioniert soweit auch alles, bis auf SSL.
Per bash funktioniert die Abfrage auf dem Webserver mit -k zum ignorieren der Authentifkation auch tadellos und er gibt das zu erwartende JSON aus.
Auf der gleichen Maschine mit Apache2 als Webserver und php8.4 wirft mir curl mit der Verwendung der Optionen CURLOPT_SSL_VERIFYPEER und CURLOPT_SSL_VERIFYHOST auf false (Was ja das Equivalent zu -k ist) ein Fehler aus:
Okay, dachte ich mir, probiere ich halt ein SSL Zertifikat aus und mache es "ordentlich". Aber da scheitere ich am Zertifikat. Wenn ich das Zerifikat des Servers übernehmen mag, dann schreit mich Curl an das es ein selbst Zertifiziertes ist und er dies nicht aktzeptiert.
Die Abfrage von curl -v auf dem opnsense Server sieht wie folg aus:
* SSL certificate problem: self-signed certificate in certificate chain
16
* closing connection #0
17
curl: (60) SSL certificate problem: self-signed certificate in certificate chain
18
More details here: https://curl.se/docs/sslcerts.html
19
20
curl failed to verify the legitimacy of the server and therefore could not
21
establish a secure connection to it. To learn more about this situation and
22
how to fix it, please visit the webpage mentioned above.
Auf dem opnsense Server habe ich ein Root-CA, ein Intermediate-CA und das Leaf-CA erstellt.
Wie bekomme ich Curl dazu diese Zertifikaten (oder das Root-CA) als Glaubwürdig zu erkennen?
Oder wie bekomme ich curl in php dazu die SSL Zertfizierung (wie curl über die bash) einfach zu ignorieren? Das System läuft sowieso nur intern und ist von außerhalb nicht zu erreichen.
SSL mit self signed Zertifikaten ist so ne Sache und erfordert viele Klimmzüge...
Tu dir einen Gefallen, besorg dir ein echtes Zertifikat.
Entweder kostenlos von letsencrypt. Da musst vielleicht ein bisschen basteln, dass die automatische Aktualisierung klappt, wenn das System von außen nicht erreichbar ist. Oder du kaufst dir eins, ggf sogar ein Wildcard. (und nach 2 Jahren den Wechsel nicht vergessen)
Du brauchst auf jeden Fall auch eine Domain wo du DNS Einträge anlegen kannst. Die kannst dann auch auf 10.x.x.x zeigen lassen.
SSL mit self signed Zertifikaten ist so ne Sache und erfordert viele
Klimmzüge...
So ein Quark...
Entweder kostenlos von letsencrypt. Da musst vielleicht ein bisschen
basteln, dass die automatische Aktualisierung klappt, wenn das System
Ahso, Klimmzüge mit selfsigned, aber Basteln mit letsencrypt.
Prima Idee...
@Rene K.:
Kopier Deine selbst erstellten Zertifikate, z.B. das der Root CA von OpnSense auf Deinem Linux-System nach:
/usr/local/share/ca-certificates/
und ruf dann
1
update-ca-certificates
auf. Dann sollte es funktionieren.
Ebenso kannst Du natürlich Deine eigenen Zertifikate in Deine Browser importieren. Der akzeptiert die dann auch.
Ist echt nicht schwer und erfordert weder Klimmzüge noch Gebastel noch Geldausgeben.
SSL mit self signed Zertifikaten ist so ne Sache und erfordert viele
Klimmzüge...
So ein Quark.
Tu dir einen Gefallen, besorg dir ein echtes Zertifikat.
Das funktioniert auch innerhalb eines lokalen Netzes für einen rein lokalen Hostnamen ganz toll...
(und nach 2 Jahren den Wechsel nicht vergessen)
Mit dem Wissen aus dem letzten Jahrzehnt kommst Du heute nicht weiter und 2027 oder spätestens 2029 fällt Dir Dein ganzes Konzept kolossal auf die Füße.
@TO:
Entweder wie Richie geschrieben hatte das Cert Deines Servers im Betriebssystem installieren und dann update-ca-certificates.
Die andere Variante ist dass Du dieses eine Cert explizit im curl aus einer Datei lädst. Dafür packst Du das in etwa so in Dein setopt-array:
1
CURLOPT_CAINFO=>"/pfad/servercert.pem",
Wenn Du es auf der Kommandozeile probierst, dann aktivierst Du diese Funktion mit dem "--cacert [file]"-Parameter.
Wenn curl auf der Kommandozeile funktioniert, aber in einem Programm eingebunden nicht, werden irgendwelche Optionen falsch gesetzt sein.
Praktischerweise bietet curl auf der Kommandozeile die Möglichkeit, passend zu genau dem jeweiligen Kommandozeilenaufruf C-Quelltext zu erzeugen, in dem die jeweiligen Optionen passend gesetzt sind.
Das sieht im wesentlichen so aus:
1
curl http://example.com --libcurl example.c
Für den Aufruf oben gibt es diesen Code hier:
1
/********* Sample code generated by the curl command line tool **********
2
* All curl_easy_setopt() options are documented at:
Kopier Deine selbst erstellten Zertifikate, z.B. das der Root CA von
OpnSense auf Deinem Linux-System nach:
/usr/local/share/ca-certificates/
und ruf dann
1
>update-ca-certificates
2
>
auf. Dann sollte es funktionieren.
Ebenso kannst Du natürlich Deine eigenen Zertifikate in Deine Browser
importieren. Der akzeptiert die dann auch.
Ist echt nicht schwer und erfordert weder Klimmzüge noch Gebastel noch
Geldausgeben.
Das ist die einzige absolut richtige Antwort in diesem Thread, danke.
Das ist die einzige absolut richtige Antwort in diesem Thread, danke.
Sehe ich nicht so. Der TO möchte sein selbst erstelltes Zertifikat ungeprüft verwenden. Das ist bei SSL generell ein vorgesehenes Szenario und ich weiß mit Sicherheit, daß libcurl das auch kann.
Unabhängig davon möchte ich noch was zu gekauften Zertifikaten los werden:
Selbst erstellte Zertifikate müssen nicht zwingend unsicher sein, wenn man das Zertifikat auf anderem Weg prüft (z.B wie von Richie aufgezeigt). Manche machen es alternativ durch Kontrolle eines Hashes. In beiden Fällen ist man nicht gezwungen, Firmen zu vertrauen, die vom Verkauf der Zertifikate leben und denen man im Fall des Missbrauchs bestenfalls den Allerwertesten lecken darf.
Kopier Deine selbst erstellten Zertifikate, z.B. das der Root CA von
OpnSense auf Deinem Linux-System nach:
/usr/local/share/ca-certificates/
und ruf dann
update-ca-certificates
auf. Dann sollte es funktionieren.
Ebenso kannst Du natürlich Deine eigenen Zertifikate in Deine Browser
importieren. Der akzeptiert die dann auch.
Ist echt nicht schwer und erfordert weder Klimmzüge noch Gebastel noch
Geldausgeben.
Das ist die einzige absolut richtige Antwort in diesem Thread, danke.
Habe ich, also ich habe sowohl das root-CA, den Intermediate-CA und das Zertifikat als PEM Datei auf den Webserver (der mit Curl auf ntopng zugreifenn soll) in /usr/local/share/ca-certificates/ gezogen (0644 als Rechte) danach auf dem Webserver ein update-ca-certificates ausgeführt:
1
draco@WebServer:~# update-ca-certificates
2
Updating certificates in /etc/ssl/certs...
3
0 added, 0 removed; done.
4
Running hooks in /etc/ca-certificates/update.d...
5
done.
Er hat quasi, keine neuen Zertifikate hinzugefügt. Auch ein Kopieren der Zertifikate in /etc/ssl/certs/ hat selbige Ausgabe.
Der Datensatz geht dann weiter und es kommt dann irgendwann nochmalig genau das selbe. Bei mehreren Durchgängen ist der error:0A0000126 immer an Unterschiedlichen, nicht reproduzierbaren Stellen.
Ich wollte sehen ob Du Security level auf 0 gesetzt hast wie vorgeschlagen. Aber wurde schon mit OpenSSL 3.0.0+ auf SECLEVEL=2 gehoben, also vor 3.0.17. Du könntest auch TLS 1.1/1.0 erzwingen.
Bei "unexpected eof" müsste man auf jedenfall eigentlich in den Logs des aufgerufenen Webservers schauen. Der hat die Verbindung vermutlich einfach geschlossen, sobald er gemerkt hat das man mit dem Client nicht auf einen gemeinsamen Nenner kommt.
ggf. kann man auch mit CURLOPT_VERBOSE+CURLOPT_STDERR noch an irgendetwas hilfreiches ran kommen.
Damit funktioniert die Abfrage tadellos. Nach Recherchen ist dies tatsächlich ein Fehler seit OpenSSL 3. Diesen kann man zwar beheben in den man Curl, OpenSSL modifiziert und kompiliert - das kann ich aber nicht :-D
Für meine Zwecke reicht diese Kombination erstmal vollkommen aus.
OpenSSL via SSL_OP_IGNORE_UNEXPECTED_EOF mitteilen das er ein eof ignorieren soll, was aber nicht bei php-curl funktioniert, da dies ihre eigene Version mitbringt. Dann bleibt einem nur übrig php-curl / OpenSSL mit eben dieser Funktion neu zu kompilieren.
Habe ich, also ich habe sowohl das root-CA, den Intermediate-CA und das
Zertifikat als PEM Datei auf den Webserver (der mit Curl auf ntopng
zugreifenn soll) in /usr/local/share/ca-certificates/ gezogen (0644 als
Rechte) danach auf dem Webserver ein update-ca-certificates ausgeführt:
1
> draco@WebServer:~# update-ca-certificates
2
> Updating certificates in /etc/ssl/certs...
3
> 0 added, 0 removed; done.
4
> Running hooks in /etc/ca-certificates/update.d...
5
> done.
6
>
Wenn das Zertifikat Deiner root-CA mit 0644 im PEM-Format vorliegt und seine Dateinamenerweiterung .crt ist und es trotzdem nicht klappt... merkwürdig.
>> Running hooks in /etc/ca-certificates/update.d...
5
>> done.
6
>>
Wenn das Zertifikat Deiner root-CA mit 0644 im PEM-Format vorliegt und
seine Dateinamenerweiterung .crt ist und es trotzdem nicht klappt...
merkwürdig.
Vielleicht hat er es mehrfach hintereinander aufgerufen und die Ausgabe eines der späteren Aufrufe gepostet. Das "added" kommt ja nur beim allerersten Aufruf wenn eine neue CA hinzukommt.
NB: Diesen Fehler kenne ich eigentlich nur, wenn versucht wird, eine Seite mit TLS abzurufen, die kein TLS hat... seltsam das. Vielleicht mal mit tcpdump(8), dumpcap(1), sslsniff(8) oder Wireshark auf die Kommunikation schauen?
Nichtsdestotrotz halte ich es für ein No-Go, Benutzer dazu zu erziehen,
... TLS-Prüfungen zu deaktivieren.
Da bin ich bei dir. Sollte man nur im Notfall tun.
Völlig korrekt, da bin ich vollkommen bei euch!
Da es sich hierbei aber nur um ein Test / kurzfristige Überwachung handelt. Dies nur intern ist, und kein Zugriff von außerhalb stattfinden kann sehe ich da aktuell keine Probleme dies über eine ungesicherte Verbindung laufen zu lassen (somal das eh für andere völlig irrelevante Daten wären).
Dann bleibt einem nur übrig php-curl / OpenSSL
mit eben dieser Funktion neu zu kompilieren.
Das ist jedenfalls nicht schön. Wäre es nicht möglich, Deinen Client in einem Container laufen zu lassen? Darin kannst Du dann auch die alte Debian-Version 11 benutzen, mit der Du die Funktion erfolgreich getestet hast.
Lass einfach gut sein. Ich habe eine persönliche Abneigung gegen dich.
Von dir möchte ich keine Ratschläge und auch keine Hilfe - Dankeschön.
Komm mal runter von deinem hohen Ross und fang an zu lesen. Der Handshake schlägt fehl, daran ändert auch das Unterdrücken der eof Fehlermeldung nichts.
SSL_OP_IGNORE_UNEXPECTED_EOF
Some TLS implementations do not send the mandatory close_notify alert on
shutdown. If the application tries to wait for the close_notify alert
but the peer closes the connection without sending it, an error is
generated. When this option is enabled the peer does not need to send
the close_notify alert and a closed connection will be treated as if the
close_notify alert was received.
You should only enable this option if the protocol running over TLS can
detect a truncation attack itself, and that the application is checking
for that truncation attack.
For more information on shutting down a connection, see SSL_shutdown(3).
Du kannst den Handshake deaktivieren durch Herabsetzen des (mit 3.0.0+ angehobenen) Security levels und/oder Herabstufen der SSL version mittels Parameter in deinen auskommentierten curl Optionen.
1
CURLOPT_SSL_VERIFYPEER => false,
2
CURLOPT_SSL_VERIFYHOST => false,
3
CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_0,
4
CURLOPT_SSL_CIPHER_LIST => 'DEFAULT:@SECLEVEL=0',
Das wäre das Equivalent zu -k und die Antwort auf Deine 2. Frage gewesen, hättest ja einfach mal ausprobieren können würde Dir deine persönliche Abneigung nicht im Weg stehen.
Oder wie bekomme ich curl in php dazu die SSL Zertfizierung (wie curl
über die bash) einfach zu ignorieren? Das System läuft sowieso nur
intern und ist von außerhalb nicht zu erreichen.
Du kannst den Handshake deaktivieren durch Herabsetzen des (mit 3.0.0+
angehobenen) Security levels und/oder Herabstufen der SSL version
mittels Parameter in deinen auskommentierten curl
Optionen.CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_0,
CURLOPT_SSL_CIPHER_LIST => 'DEFAULT:@SECLEVEL=0',
Das wäre das Equivalent zu -k und die Antwort auf Deine 2. Frage
gewesen, hättest ja einfach mal ausprobieren können würde Dir deine
persönliche Abneigung nicht im Weg stehen.
Meine Gütem, echt... Nein! Man kann in php-curl den EOF Fehler nicht über eine CURLOPT weg bekommen. Und ja, natürlich habe ich das selbst schon probiert, selbst bevor DU mir das erzählt hast. Warum denkst du denn war das auskommentiert? Das war nen Copy&Paste - und ja auch da hatte ich den Security Level auf 0 gesetzt.
Bitte...! Bitte!!! Lass es einfach...
EDIT: Fehler.png ignorieren, war falsch hochgeladen. Fehler2.png beachten!
Meine Gütem, echt... Nein! Man kann in php-curl den EOF Fehler nicht
über eine CURLOPT weg bekommen.
SSL_OP_IGNORE_UNEXPECTED_EOF natürlich nicht - aber die Ursache beseitigen für den Abbruch. Und die kommt nun mal vom fehlschlagenden Handshake durch Inkompatibilität in den Versionen. Hast Du auch TLS alle Versionen durchgetestet, nicht nur 1.0?
Also der Verlauf des Threads zeigt mir was anderes...
Mit einem echten Zertifikat würde die Abfrage vermutlich schon
funktionieren.
Aufgrund der Konflikte hinsichtlich close_notify zwischen den beiden OpenSSL-Versionen, die der oben beschriebene github-Link beschreibt, ist das leider eher unwahrscheinlich. Wenn die eine Seite ein close_notify erwartet und die andere die Verbindung ohne close_notify schließt, dann werden möglicherweise zwar die Daten korrekt übertragen, aber die Fehlermeldung wird es vermutlich trotzdem geben.
Meine Gütem, echt... Nein! Man kann in php-curl den EOF Fehler nicht
über eine CURLOPT weg bekommen.
Es ist nur so eine Idee, aber vielleicht funktioniert der Golang-Client im Anhang, schließlich ist das eine ganz andere TLS-Implementierung, und beim resp.Body.Close() werden eventuelle Fehler ignoriert.
Mit "docker compose create" im Wurzelverzeichnis des Archivs kannst Du einen Container "downloader-downloader-1" erzeugen, ohne die Go-Tools installieren zu müssen. Dann kannst Du mit "docker start -ai downloader-downloader-1" den Container starten -- oder mit "docker cp downloader-downloader-1:/otx ." das Executable "otx" aus dem erzeugten Container heraus kopieren.
Eine alternative SSL-Implementierung aus einem Forum runterladen und
installieren. Genau mein Humor ;)
Nichtmal reingeschaut, kleiner Held. Das wiederum genau mein Humor.
Die verwendete (und alternative) TLS-Implementierung ist -- Überraschung -- die aus den Standardlibraries von Golang, und zum Bauen wird das offizielle Golang-Image "golang:latest" vom Docker Hub benutzt.
Angelegentlich reden wir über 27 Zeilen Code in Golang, dazu ein Makefile, das Dockerfile zum Bauen eines Docker-Image, und eine compose.yml zum Erzeugen des Docker-Containers. Insgesamt reden wir über 64 Zeilen Code, wenn die 10 Zeilen YAML in der compose.yml als Code durchgehen lassen wollen.