Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added package cacerts. It will download ca-bundel from curl.haxx.se a… #218

Merged
merged 3 commits into from
Aug 18, 2019
Merged

added package cacerts. It will download ca-bundel from curl.haxx.se a… #218

merged 3 commits into from
Aug 18, 2019

Conversation

flosch-dev
Copy link
Contributor

…nd place in /etc/ssl/certs/cacert.pem.

further it's recommended to add location in .profile:
export SSL_CERT_FILE=/etc/ssl/certs/cacert.pem

…nd place in /etc/ssl/certs/cacert.pem.

further it's recommended to add location in .profile:
export SSL_CERT_FILE=/etc/ssl/certs/cacert.pem
@er13
Copy link
Member

er13 commented Aug 12, 2019

$(pkg)-uninstall ist in zweierlei Hinsicht falsch:

  1. Im Rumpf einer Regel kann keine doppelte Evaluierung ($($(PKG)...)) verwendet werden.
  2. $($(PKG)_TARGET_PATH) bzw. $(CACERTS_TARGET_PATH) ist nirgends definiert. Bzw. seit der Umstellung auf $(PKG)_TARGET_BINARY sollte vielleicht diese Variable verwendet werden.

@er13
Copy link
Member

er13 commented Aug 12, 2019

Was ist mit 3e12798? Oder reicht

export SSL_CERT_FILE=/etc/ssl/certs/cacert.pem

?

@er13
Copy link
Member

er13 commented Aug 12, 2019

Zum Setzen von SSL_CERT_FILE empfiehlt sich die Datei /etc/profile.d/cacerts.sh (als Teil des Pakets cacerts), diese wird dann von /etc/profile eingelesen.

@flosch-dev
Copy link
Contributor Author

Nachdem ich den initialen branch mit etlichen unsinnigen commits drucheinander gebracht hatte, habe ich die Änderung am curl package in einem seperaten branch eingepflegt. Aber ich kann das noch in diesen branche mergen.
SSL_CERT_FILE wird von allen Programmen die openssl nutzen eingelesen (z.b. wget). Für OpenSSL habe ich keine Möglichkeit gefunden nur den CA-Path zu setzen, da gibt es nur openssldir, aber diesen auf /etc/ssl/ zu setzen fand ich nicht so gut.
Den Hinweis mit /etc/profile.d/cacerts.sh find ich sehr gut, das baue ich noch ein, Danke! Auch $(pkg)-uninstall schaue ich mir nochmal an und werde es korrigieren.

@flosch-dev
Copy link
Contributor Author

Als Nachtrag ... curl nutzt natürlich auch openssl libs und liest SSL_CERT_FILE ein. Der Eintrag "with-ca-bundle=..." hat aber Vorrang. Insofern könnte man tatsächlich die curl.mk Änderung auch weglassen.
Ich bin mir gerade nicht sicher was besser ist, aber schaue mir das heute Abend nochmal an.

…rts/cacert.pem' as per suggestion of er13

- update curl.mk to configure with-ca-bundle="/etc/ssl/certs/cacert.pem"
- corrected cacerts.mk "$(pkg)-uninstall"
@flosch-dev
Copy link
Contributor Author

Ich habe cacerts.mk korrigiert, bitte nochmal prüfen ob das jetzt so passt. /etc/profile.d/cacerts.sh mit der entsprechende Variable SSL_CERT_FILE ist jetzt im package und auch getestet.
curl.mk habe ich auch noch angepasst um das ca-bundle auch zu nutzen.

@er13
Copy link
Member

er13 commented Aug 13, 2019

curl.mk habe ich auch noch angepasst um das ca-bundle auch zu nutzen.

Sofern man sich fürs Anpassen von curl.mk entscheiden würde, so müsste FREETZ_PACKAGE_CACERTS zusätzlich noch als REBUILD_SUBOPT deklariert werden.

Ich fände es jedoch besser, wenn man curl.mk gar nicht anpassen würde, mangels zwingender Notwendigkeit. Denn, wie du selbst schreibst, wird SSL_CERT_FILE auch von curl unterstützt.

@flosch-dev
Copy link
Contributor Author

Ich hatte gestern noch etwas rum probiert und mir fiel auf dass SSL_CERT_FILE aus /etc/profile.d/cacerts.sh nicht in init-scripts (z.b. rc.xxxx) gesetzt ist. Was wäre aus eurer Sicht der richtige Weg das zu beheben?

  1. Anpassung des package spezifischen init-scripts durch einlesen von /etc/profile.d/cacerts.sh?
  2. Anpassung des package spezifischen init-scripts durch setzen von SSL_CERT_FILE manuell im init-script?
  3. curl.mk mit --with-ca-bundle="/etc/ssl/certs/cacert.pem"
  4. Gibt es einen anderen Weg SSL_CERT_FILE global in init-scripten verfügbar zu machen?
  5. Andere Vorschläge?

@er13
Copy link
Member

er13 commented Aug 17, 2019

und mir fiel auf dass SSL_CERT_FILE aus /etc/profile.d/cacerts.sh nicht in init-scripts (z.b. rc.xxxx) gesetzt ist. Was wäre aus eurer Sicht der richtige Weg das zu beheben?

Hmm, aktuell gibt es keinen ready-to-use Mechanismus, der das globale Setzen einer Umgebungsvariable ermöglichen würde. Ein denkbarer Weg wäre das Erweitern von /etc/init.d/rc.conf bzw. das Hinzufügen eines Hooks ans Ende von dieser analog dem von /etc/profile. Mir fällt allerdings spontan kein weiterer Use-Case ein, für den dieser Mechanismus von Nutzen wäre.

Könntest Du bitte aufzählen, für welche rc-Scripts das Deiner Ansicht nach benötigt wird? U.U. wäre das Einlesen aus diesen heraus oder aus /etc/init.d/modlibrc dann vielleicht doch die einfachere/bessere Lösung.

@flosch-dev
Copy link
Contributor Author

Es ging um ein Paket wofür ich noch keinen PR erstellt habe: adaway. Ich habe mich aber jetzt dafür entschieden SSL_CERT_FILE Paketspezifisch zu setzen bzw als Paket Parameter editierbar zu machen.
In jedem Fall denke ich jetzt auch, dass curl.mk wieder mit --without-ca-bundle gebaut werden sollte, um es flexibler zu halten.
Ob SSL_CERT_FILE in Zukunft nicht nur über /etc/profile.d/cacerts.sh sondern eventuell über /etc/init.d/rc.conf gesetzt wird, kann man ja später nochmal überdenken!?

@er13 er13 merged commit 7b5820b into Freetz:master Aug 18, 2019
@flosch-dev flosch-dev deleted the cacerts branch August 18, 2019 13:13
@er13
Copy link
Member

er13 commented Aug 18, 2019

@PeterPawn: könntest Du mir bitte sagen, wofür Du die Option FREETZ_OPENSSL_CONFIG_DIR damals (s. 030ac94) benötigt hast? Ich habe den konkreten Use-Case leider vergessen.

Hättest Du etwas dagegen bzw. würde es mit Deinen Use-Cases kollidieren, wenn ich diesen Pfad hart auf /etc/ssl setze? Wenn man alternative Pfade verwenden möchte, kann man alles mitels eigener openssl.cnf mit anschließendem -config /path/to/openssl.cnf steuern.

er13 added a commit that referenced this pull request Aug 18, 2019
1. This way curl works the same way regardless of the environment it is started from.
2. SSL_CERT_FILE is also evaluated by AVM's version of libcrypto, setting it globally
   is a potential source of problems with AVM binaries.

OpenSSL related changes are pending.

Refs #218
@PeterPawn
Copy link
Contributor

PeterPawn commented Aug 19, 2019

Ja, würde kollidieren.

Ich habe diese Option deshalb hinzugefügt, weil in eigenen ("custom") Images der Pfad zur Konfigurationsdatei eben noch den Mountpoint dieses alternativen Images VOR dem /etc/ssl enthält.

Beispiele für solche Images findet man im IPPF, mit dieser Option (unter Verwendung von "/var/custom" als Mountpoint) übersetzte Binaries findet man in meinem Repository mit den signierten Dateien.

Aber ich kann die Option auch in meinen Fork selbst weiterführen ... nur halte ich die Verwendung eines fest kodierten /etc/ssl ohnehin für einen Fehler.

Wenn man so etwas machen möchte (wie Du selbst festgestellt hast, kann man natürlich auch die Pfade jeweils selbst setzen, wobei das mit der -config-Option auch nur für das OpenSSL-Binary gilt ... aber für die libcrypto.so kann man (iirc) den Pfad zur Konfigurationsdatei auch über eine Environment-Variable OPENSSL_CONF setzen), dann sollte das nach meiner Ansicht über einen Link zu einer beschreibbaren Stellen (am besten mit zusätzlichen Integritätsprüfungen beim "Aufbau" der Struktur am Zielort, wobei man die nach dem (dynamischen) Aufbau dann auch wieder "read-only" setzen kann) erfolgen.

Denn unter diesem Pfad sucht eben OpenSSL (bzw. alles, was die Libs ohne zusätzliche Angaben verwendet) nicht nur die vertrauenswürdigen Root-CA (die sich sicherlich seltener ändern), sondern auch deutlich volatilere Daten, wie CRLs. Und OpenSSL wird eben i.d.R. nicht nur von curl verwendet, sondern auch noch von diversen anderen Paketen.

Zwar sollte jede CA, die mit CRLs anstelle von OCSP arbeitet, auch entsprechende Verteilerpunkte in den erweiterten X509-Attributen eines (CA-)Zertifikats bereitstellen, aber oft sind solche Dienste auch nicht erreichbar (vermutlich hat jeder schon mal erlebt, daß sein Browser eine Verbindung nicht aufbauen wollte, weil er keine Informationen beziehen konnte, ob das vorgelegte Zertifikat zurückgezogen wurde oder nicht) und auch die Prämisse, daß man bei Verwendung des (Mozilla-)Bundles ALLEN CAs in diesem Bundle vertrauen soll, würde vermutlich nicht jeder teilen. Ich kenne genug Leute, die auch schon vor den von Mozilla gezogenen Konsequenzen (https://blog.mozilla.org/security/2018/03/12/distrust-symantec-tls-certificates/) die Symantec-Roots aus ihren Geräten verbannt hatten.

Ich denke nicht, daß das SquashFS-Image (als "read-only"-Medium, außer man baut ein neues Images bei jeder Änderung) der richtige Ort für die Ablage solcher Daten ist.

Ich mache mal einen (zugegebenermaßen etwas aufwändigeren, vielleicht für Freetz sogar zu aufwändigen) Vorschlag ... OpenSSL muß in dem hier diskutierten Kontext ja ohnehin im Image enthalten sein.

Mit sign_image kann man auch eine Datei (einen Tarball) mit dem boxeigenen Zertifikat (bzw. dem dort verwendeten PrivKey) signieren (sollte mit der BusyBox-ash auch problemlos laufen) und diese sogar - sofern man den öffentlichen Schlüssel passend bereitstellt, vielleicht unter dem Namen des meist nicht verwendeten Plugin-Keys, wobei hier auch eine zeitweilige Bereitstellung ausreichend wäre - mit "Bordmitteln" von AVM (tr069fwupdate stream) wieder überprüfen, entpacken und das darin enthaltene "/var/install"-File ausführen lassen. Letzteres kann dann auch das Kopieren der Dateien an die richtige Stelle (halt einmalig beim Start der Box) übernehmen.

Damit hätte man also eine dynamische Quelle für die Zertifikate, denen man tatsächlich vertrauen möchte (die anderen werden halt rausgeworfen, ich brauche jedenfalls nicht mal 1/10 der im Bundle enthaltenen CAs) und auch nach Änderungen an diesen Dateien (ich meine mich zu erinnern, etwas von Update-Absichten für diese Zertifikate in den vorhergehenden PR-Versuchen gelesen zu haben) hat man die Möglichkeit, diese Liste wieder so zu signieren, daß man ihrem Inhalt einigermaßen vertrauen kann.

Die Form mit der einzelnen PEM-Datei, die alle "trusted root CAs" enthält, ist - wenn ich mich richtig erinnere - ohnehin nicht die schnellste ... meines Wissens wird eine auf diesem Weg angegebene Datei beim SSL_CTX_load_verify_locations (https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html) jedesmal komplett geladen und geparsed. Ein Verzeichnis mit diesen Root-Zertifikaten (standardmäßig dann unter /etc/ssl/certs gesucht) wird hingegen nur bei Bedarf durchsucht und dabei wird ein Hash über das Subject des Root-Zertifikats (steht im vorgelegten Zertifikat als "Issuer") verwendet. Hier wird also nur ein Zertifikat (bzw. "wenige", wenn es tatsächlich mehr als eines mit demselben Hash geben sollte) geladen und "interpretiert".

Daher ist diese Form der Root-Zertifikate in einer einzigen Datei, wie sie curl (auch) kennt, ohnehin nur die zweitbeste (die Mozilla-Programme verwenden selbst auch wieder eine DB, IMO eine SQLite3-DB: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/tools/NSS_Tools_certutil und diese Form der einzelnen Datei bei curl wird ja aus ebendieser DB extrahiert) ... auch curl kann ja (mit der --capath-Option, zumindest wenn es auf OpenSSL basiert) die verzeichnisbasierte Suche nach "trusted root CAs" verwenden, die in weniger Aufwand (beim "Verwenden" jedenfalls) mündet.

@flosch-dev
Copy link
Contributor Author

Ohje, ich hoffe ja mit diesem Paket nicht mehr Aufwand als Nutzen erstellt zu haben. Eure Argumente machen durchaus Sinn. Meine Intension war es erstmal nur ein CA bundle im image bereitzustellen um https downloads mit curl oder wget "etwas" sicherer zu machen. Zumindest wollte ich nicht den server-cert check wie bisher abschalten.
Vielleicht wäre es ja auch besser erstmal nur das CA bundle im image bereit zustellen ohne SSL_CERT_FILE & curl.mk zu setzen?

  • Welcher neutrale Pfad würde denn aus eurer Sicht besser passen als /etc/ssl/?
  • Bezüglich Bundle vs single CA cert, Man könnte das cabundle auch beim image bauen wieder splitten, aber das wäre wohl was für später.

@PeterPawn
Copy link
Contributor

PeterPawn commented Aug 19, 2019

Laß Dich nicht ins Bockshorn jagen, das von mir beschriebene Vorgehen klingt schlimmer, als es wirklich ist.

Die für mich entscheidende (Design-)Frage wäre es halt, ob man derartige "veränderliche" Daten tatsächlich ins Basissystem integriert oder doch - so wie es Freetz bisher auch hielt, denn da lag es ja unter /mod/etc/ssl - getrennt davon hält. Wenn es nicht so viele Daten wären und damit nicht die 32 KB komprimiert (die für die Freetz-Einstellungen verfügbar sind) noch knapper würden, wäre das ja sogar im Freetz-Settings-File an einen guten Platz.

Ich würde halt hingehen (daß ich mich zuvor nicht geäußert habe, hatte auch damit zu tun, daß ich das erste Erfolgserlebnis nicht verkomplizieren wollte - jetzt stellt sich halt die Frage, wohin sich das Ganze entwickeln soll) und in den Start des Systems (bzw. genauer in die Auswertung von "onlinechanged" - ohne "online" braucht man i.d.R. auch keine Zertifikate (fremder Systeme) zu validieren) eine Prüfung einbauen, ob es ein lokales "Archiv" von "trusted root CAs" gibt.

Ist es vorhanden, packt man es erst mal aus (das ist - wie gesagt - im besten Falle ein tr069fwupdate stream file:///var/media/ftp/Freetz/trusted-ca.image (oder wo auch immer das liegt, ggf. macht man es konfigurierbar, um es bei VR9-Boxen in der Wrapper-Partition ablegen zu können) als einzelnes Kommando) und hat damit erst mal die Basis, um sich nach Aktualisierungen umzusehen. Gibt es die, lädt man sie halt und zerlegt die Datei in ihre "Bestandteile" (sprich: einzelne Zertifikate) ... und man merkt sich, daß man das lokale Image später aktualisieren muß.

Das Zerlegen an den "Schnittmarken" einer PEM-Datei ist easy und auch das "Hashen" ist i.d.R. kein Problem - ich weiß allerdings gerade nicht, ob das "rehash" als OpenSSL-Operation erst in der 1.1.x in das Binary Einzug gehalten hat. Aber auch wenn das so ist, sollte mit der 1.0.x noch ein mutiges

openssl x509 -subject_hash -noout -in CERTFILE

den Hash für den Dateinamen liefern. Einzig die Logik, da den richtigen Index anzuhängen, wenn es mehr als ein Zertifikat mit dem Hash gibt, ist vielleicht etwas aufwändiger ... kann man auch erst später implementieren, wenn es tatsächlich notwendig sein sollte.

Jedenfalls ist das "Zerlegen" wirklich so einfach ... und diese Art der Speicherung hat natürlich eindeutige Vorteile (ggü. dem "single file with all certs"), auch wenn es um "Selektion" von CAs geht (falls man tatsächlich mal ein GUI dafür bauen wollte) oder wenn man gar das Zertifikat seiner eigenen Root-CA hinzufügen will (das natürlich in einer cacert.pem von curl auch nicht enthalten sein dürfte, aber bei manchem bestimmt auch im OpenVPN-Kontext zum Einsatz kommt oder beim Apache mit User-Zertifikaten anstelle von Benutzer/Kennwort).

Das dann am Ende wieder zu einem lokalen Image zusammenzupacken, was man signieren kann, ist auch nicht wirklich "schlimm" ... man muß halt eine bestimmte Verzeichnisstruktur einhalten und eine Datei ./var/install mit in das Image packen, die einfach nur die entpackte Struktur von /var/packet/var (die letzte Ebene var ist Pflicht für Images, die von den AVM-Komponenten geprüft werden und die landet beim Entpacken dann unterhalb von /var/packet, daraus ergibt sich dieser merkwürdige Pfad) an die richtige Stelle kopiert (oder sie als ZIP-File dorthin entpackt oder wie auch immer man das machen will). Wie man so ein "selbstentpackendes Image" aufbauen kann, kann man sich hier: https://github.com/PeterPawn/yf_bin/blob/master/scripts/create_YourFritz_base_image ansehen (das muß natürlich nicht so "ausführlich" sein, weil es auf der Box ohnehin niemand sieht/liest). So ein zusätzliches Skript, welches die /etc/ssl-Struktur in ein ZIP-File steckt, dieses in ein TAR-File und letzteres dann auf der Box signiert, ist jedenfalls nicht wirklich kompliziert.

Am Ende ist das mit dem fehlenden Vertrauen in das komplette Bundle (ich brauche nur selten die "China Financial Certification Authority" als Root - wobei deren CA-Zertifikat wenigstens schon SHA-256 als Hash verwendet, viele sind immer noch mit SHA-1 signiert in dem Bundle) und der Notwendigkeit, eine eigene Root-CA hinzuzufügen, aber sicherlich schon "etwas spezieller" ... aber ich prüfe eben auch lieber "von Hand" ein Zertifikat und pinne dann dessen "public key", wenn ich von einem fremden Server per TLS Dateien lade, denen ich hinterher ein "besonderes Vertrauen" aussprechen muß: https://github.com/PeterPawn/YourFritz/blob/signimage_database/signimage/database/download_firmware_files#L89

Also laß Dich von mir nicht verunsichern ... zumal man das auch nicht alles "auf einen Schlag" auf die Beine stellen muß. Man kann das auch Stück für Stück implementieren und zusammensetzen ... sogar dann, wenn man dafür irgendwelche vorhergehenden "Provisorien" wieder abräumen muß.

PS: Hier gibt's auch das Zerlegen eines solchen Files aus mehreren Zertifikaten (in "Shell") als Beispiel zum Nachlesen ... ich hatte in Erinnerung, so etwas gezeigt zu haben: https://github.com/PeterPawn/YourFritz/blob/signimage_database/tools/showcertchain - man muß halt an der Stelle mit "openssl x509" etwas anders verfahren.

PPS: Um noch ein Argument für die getrennte Datenhaltung hinterherzuschieben ... integriert man es nicht in das Image, können mehrere Images eine einmal erstellte "eigene Zusammenstellung" verwenden (ggf. sogar mehrere Boxen, wobei jede ihr lokales Image selbst signieren sollte, es also etwas wie einen "Import" geben müßte, wenn man das über mehrere Boxen verwenden will) - ansonsten müßte man bei jedem neuen (Freetz-)Image auch wieder "tätig werden", wenn man "Abweichungen" zum "normalen CA-Bundle" (sei es durch Hinzufügen oder Entfernen) hat.

@er13
Copy link
Member

er13 commented Aug 19, 2019

Habe jetzt noch nicht alles gelesen, geschweige denn verstanden.

Kleine Anmerkung zum Thema "einzelne Zertifikate mit hash-Symlinks" vs. "alles in einer Datei". Möchte man die aus Performance-Sicht bessere Variante "einzelne Zertifikate mit hash-Symlinks" umsetzen, so könnte man sich an dem BuildRoot-Paket orientieren.

@flosch-dev
Copy link
Contributor Author

flosch-dev commented Aug 19, 2019

Also ich bin wirklich froh über den regen Austausch und je öfter ich die Beitrage lese, desto mehr verstehe ich alles :)
Wirklich gut fand ich ein ca-bundle im r/o filesystem auch nicht, aber /mod/etc/ssl/certs/ war mir zu klein aber da sind hash-symlinks auf jeden Fall der richtige Weg.

Also folgendes habe ich mir mal für cacerts notiert (bitte korrigiert mich falls ich was falsch verstanden habe):

  • ca-bundle sollte "vertrauenswürdig" von der box geladen werden ( außerhalb des image ) -> ich denke cert pinning ist hier der richtige Weg, aber sehe hier noch unterschiedliche Ansätze ( public cabundles, selbst erstellt und signed mit box-key, ...)
  • ca-bundle in certs splitten
  • splitted ca-certs sollten nach /var/cacerts/....
  • hash symlinks (subject name hash) nach /mod/etc/ssl/certs/
  • hash symlinks sind leider unterschiedlich kompatibel entsprechend OpenSSL version (≥ 1.0.0 ist anders als < 1.0.0 - https://www.openssl.org/docs/man1.0.2/man1/x509.html )
  • hash symlinks als freetz config? Also man muss ja nicht für alle certs aus dem bundle ein hash symlink erstellen sondern über WebUI konfigurierbar machen. Man könnte sogar unterschiedliche folder mit hash-symlinks anlegen unterschiedliche trusted folder zu benutzen.

Geht das in die richtige Richtung?

@PeterPawn
Copy link
Contributor

PeterPawn commented Aug 20, 2019

Das mit den Symlinks innerhalb der Freetz-Konfiguration wäre sicherlich machbar und ist auch in meinen Augen eine gute Idee (auch zum Beschränken des Vertrauens), die mit dem Platz sparsam umgeht.

Die Tatsache, daß die 0.98.x-Version ein anderes Hash-Verfahren benutzte, würde ich ignorieren und einfach das ganze Package nur für OpenSSL >= 1.0.x weiterentwickeln. Die alte Version wird früher oder später noch an ganz anderen Problemen scheitern (und das betrifft ja auch nur die älteren FRITZ!Box-Modelle, die haben dann noch ganz andere Sicherheitsprobleme in der als Vorlage verwendeten AVM-Firmware) ... bis hin zu einem Inhalt neuerer Zertifikate, den sie per Definition nicht versteht, weil neuere Erweiterungen o.ä. zum Einsatz kommen.

fda77 referenced this pull request in Freetz-NG/freetz-ng Sep 30, 2019
It will download ca-bundle from curl.haxx.se and make it available on the box under /etc/ssl/certs/cacert.pem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants