24. Januar 2016 , 20:20 Uhr
von Marc Eggert

Wie angekündigt folgt hier der „Walkthrough“ zu einem selbst gehosteten Firefox Sync 1.5-System. Es wäre etwas überheblich zu behaupten, dass das inzwischen funktionierende Konstrukt sofort und „out of the box“ funktioniert hat. Es ist etwas zeitaufwändig, überhaupt die Zusammenhänge zwischen den einzelnen Komponenten zu begreifen und in der Folge zusätzlich teils recht spärliche Fehlermeldungen zu finden und im Anschluss richtig zu deuten.

Um auch wirklich „frei“ an einem solchen Projekt arbeiten zu können, war für mich klar, dass dies auf einer virtuellen Maschine entwickelt wird und einzelne „Zustände“ als Snapshots gespeichert werden. Da man sich doch recht oft mit diversen Updates und Abhängigkeiten der verschiedenen Python-Setups verhaspelt, ist es von Vorteil, wenn man weiß, dass man auch relativ schnell wieder zu einem früheren Zustand der Maschine springen kann. Los gehts!

Funktions-Schema eines Firefox Sync 1.5 Stacks

Die nachfolgende Grafik zeigt die grundsätzlichen Komponenten eines selbst gehosteten Firefox Sync 1.5 Stacks. Die einfache Variante ist es, einfach „nur“ den rechten Teil der Grafik (Syncserver) selbst zu hosten. Dies funktioniert auch unter Benutzung der Auth- und Content-Server von Firefox und sollte auch der erste Schritt beim Aufbau der selbst gehosteten Umgebung sein. Die so aufgebaute Umgebung ist im Anschluss allerdings auch noch nicht so ganz komplett: Der Firefox-Profil-Server ist hierbei noch nicht integriert. Das wäre die Seite, die man beim „offiziellen“ Firefox-Sync-Server aufrufen kann, um das Profilbild zu ändern, etc. – betriebswichtig ist dieses Feature allerdings nicht. 😉

Komponenten des Sync 1.5 Systems

Komponenten des Sync 1.5 Systems

Basis-Umgebung für den Start

Wie bereits erwähnt, ist es sinnvoll, den Server virtualisiert aufzusetzen, um so ggf. auch nochmals komplett neu zu beginnen, falls man sich hier oder da „verfahren“ hat und teilweise unlösbare Konstellationen der einzelnen Komponenten geschaffen hat.

Mein erster „Snapshot“ war daher eine frisch aufgesetzte Ubuntu 14.04 Server-Version minimal inkl. aller aktuellen Updates. „Minimal“ bedeutet in dem Fall, dass man nichts außer „SSH-Server“ aus den angebotenen Paketinstallationen auswählt. Dieser Snapshot kann dann jeweils zu einem Neustart unter geltenden Ubuntu-Bedingungen genutzt werden. Als erstes Ziel sollte man sich vornehmen, einen einfachen Syncserver aufzusetzen und den kompletten Auth- und Content-Server über die offiziellen Firefox-Server laufen zu lassen (das wäre dann auch Beispielsweise der zweite Snapshot). Man lernt hierbei schon mal einiges zu den einzelnen Komponenten und weiß zumindest, wie man den Syncserver lauffähig bekommt und dass diese Komponente später auch funktionieren wird, wenn man den eigenen Auth- und Content-Server aufsetzt.

OpenSSL / SAN Zertifikat für Apache Webserver

Um den Content- und den Auth-Server lauffähig zu bekommen, ist es notwendig, für die entsprechenden Domains ein Zertifikat einzusetzen (Firefox akzeptiert für Einträge der Content- und Auth-Server NUR https-Verbindungen – ein http-Proxy funktioniert in diesem Anwendungsfall nicht). Die in meiner Anleitung verwendeten Domain-Namen sind:

  • fxa-auth.DOMAIN.TLD
  • fxa-content.DOMAIN.TLD
  • (syncserver.DOMAIN.TLD – läuft momentan nicht über SSL, sondern wird direkt über Port 5000/gunicorn von außen angesteuert)

Eine Anleitung, wie man selbst ausgestellte SAN-Zertifikate erstellt, findest du hier: https://www.fabiblog.de/ubuntu-server-14-04-san-zertifikate-erstellen/

Erforderliche Pakete vor dem Start

Die folgenden Pakete werden für den Aufbau der verschiedenen Server in diesem Projekt benötigt:

Python >=2.7.9

Aus den offiziellen Ubuntu-Repositories erhält man standardmäßig Python 2.7.6. Für einen kompletten Sync-Stack ist allerdings mindestens Python 2.7.9 erforderlich. Man begegnet diesem Problem spätestens dann, wenn die Authentifizierung über eine SSL-Verbindung und eigenem Zertifikat nicht funktioniert. Aktuell wird mit dem PPA von Felix Krull die Version 2.7.11 installiert.

Zusätzlich zu Python werden einige weitere Pakete benötigt, u.a. git, mysql und apache2. Die Firefox-Dienste laufen wie im Schaubild oben beschrieben unter „localhost“, bzw. 127.0.0.1 über verschiedene Dienst-Ports. Über den Apache-Webserver werden diese Dienst-Ports via Reverse-Proxies (verschiedene VHosts) von „außen“ angesteuert.

Sämtliche Dienst-Server sollten _nicht_ als root betrieben werden! Der „normale“ Benutzer-Account unter Ubuntu hat hierzu ausreichend Rechte. Noch eine Nummer sicherer und wie es auch in verschiedenen anderen Tutorials beschrieben wird: Einen zusätzlichen Account ohne direkten Login und ohne sudoers-Rechte anlegen!

Hinweis: Das Problem mit den SSL-Zertifikaten unter Python bei der Authentifizierung zwischen syncserver und fxa-auth-server konnte ich noch nicht lösen, so dass der Syncserver direkt via Port 5000 von außen angesteuert wird!

NodeJS 4.2.3+ & npm >= 2.4.x

Den Hinweis auf die in der Überschrift genannten Versionen bekam ich aus einem anderen Mozilla-DEV-Repository aus GitHub. Letztendlich hat das Bauen der einzelnen Server-Komponenten mit diesen Versionen dann auch geklappt. Alles in allem war es aber ein sehr häufiges Zurücksetzen, Neuprobieren und Neubauen,  bis alles funktioniert hat. Also nicht verzweifeln, wenn es nach diversen Git-Updates an dieser Stelle nicht mehr funktioniert.

Die entsprechenden Versionen unter Ubuntu 14.04 erhält man so:

 

Der Sync-Server

Für den Sync-Server müssen ein MySQL-Datenbankbenutzer und eine Datenbank angelegt werden (Alternativ eine SQLite-DB – das vorgehen der aktuellen Schritte wird auch auf der Seite des GIT-Repositories beschrieben. Im Beispiel lautet der Benutzer und die Datenbank „syncserver“ – Der Benutzer benötigt vollen Zugriff auf die Datenbank „syncserver“. Die Datenbank kann über die Konsole, phpMyAdmin, Webmin, whatever angelegt werden. Die Datenbank-Struktur wird später selbständig vom syncserver angelegt.

Der Syncserver ist via git zu holen. Das Repository befindet sich hier: https://github.com/mozilla-services/syncserver

Wie bereits erwähnt, sind die folgenden Schritte als „normaler“ Benutzer auszuführen – nicht als root. Man befindet sich also im „home“-Verzeichnis des Benutzers für diese Server-Dienste (beispielsweise Benutzer „firefox“ -> /home/firefox). Alternativ ist die Installation (ebenfalls als unpriviligierter Benutzer mit Rechten für das opt-Verzeichnis) unter /opt sinnvoll/möglich.

Dieser Befehl „baut“ den Syncserver aus den Quellen in das Verzeichnis ./syncserver.

In der Folge ist die Installation via make test zu kontrollieren.

Wenn die Installation keine Fehler meldet, geht es weiter mit dem Anpassen der Konfigurations-Datei. Die Datei, die hier angepasst werden muss, lautet: ./syncserver/syncserver.ini. Meine Konfigurations-Datei sieht derzeit so aus:

Die wichtigen/zu editierenden Zeilen sind farblich hervorgehoben. Im Folgenden noch die Beschreibung, was die Konfigurations-Parameter bewirken:

  • Unter „[server:main]“ die Zeile „host“: Hier ist die IP-Adresse des eigenen Servers (auf welchem man gerade arbeitet) einzutragen. Die Konfigurations-Parameter gelten für den Python-WSGI-Server „Gunicorn„, welcher direkt von syncserver gestartet wird und auf Port 5000 (siehe Zeile 4) reagiert. Es ist möglich, den WSGI-Teil auch über den Apache-Webserver laufen zu lassen. Eine entsprechende Konfiguration hierzu poste ich ggf. am Ende dieses Dokuments.
  • Unter „[syncserver]“ die Zeile „public_url“: Hier ist die öffentliche Adresse für den Sync-Server einzutragen. Der Einfachheit halber trägt man hier wiederum die IP-Adresse wie oben definiert und den Port ein – gefolgt von einem slash(!).
  • Die Zeile „sqluri“: hier ist die Datenbank-Verbindung wie in der Datei beschrieben einzutragen
  • Die Zeile „secret“: Wie in der Konfigurations-Datei beschrieben, ist hier ein eigenes Secret einzutragen – dies wird über folgenden Befehl erreicht: head -c 20 /dev/urandom | sha1sum
  • Unter „[browserid]“ sind die entsprechenden 3 Zeilen zu aktivieren
    • Über diesen Dienst werden Browser-IDs verifiziert. Dies kann entweder über die Firefox-Server, einen lokal installierten Browserid-Verifier oder über den bereits in syncserver integrierten Verifier erledigt werden. Die Option für den Lokalen Verifier lautet wie in der Beispiel-Konfiguration oben „tokenserver.verifiers.LocalVerifier“ – für die Firefox-Server kann man diese Sektion auskommentiert lassen, für einen entfernten Browserid-Verifier würde man die Option „tokenserver.verifiers.RemoteVerifier“ wählen.
    • Unter „audiences“ wird nun der Dienst definiert, welcher die Browserid-Verifikation durchführen soll. In unserem Fall also unser eigener Syncserver – siehe „public_url“ – in diesem Fall ohne „trailing slash“.

Hat man bis hierhin alles geschafft, kann man den Syncserver über den Befehl make serve  starten. Die Debug-Log-Infos werden hierbei direkt auf der Konsole ausgegeben. Später wird dieser Aufruf natürlich in das Upstart-System von Ubuntu aufgenommen. Eine mögliche Upstart-Datei befindet sich im Abschnitt „Upstart-Dateien“.

Hinweis zum Testen: An dieser Stelle kann der Sync-Server bereits in Verbindung mit den Firefox-Account-Servern getestet werden. Dazu verändert man in den Firefox-Einstellungen (about:config in die Adresszeile eingeben) lediglich den Eintrag zu „identity.sync.tokenserver.uri“ auf die „public“-Adresse des eigenen Sync-Servers. Im aktuellen Fall also  http://XX.XX.XX.XX:5000/token/1.0/sync/1.5  – am Besten die komplette Adresse eintragen, denn im Gegensatz zum Firefox-Syncserver benötigen wir an dieser Stelle noch den Zusatz „token/“ in der URL. Nun kann man in den Firefox-Sync-Einstellungen im Browser einen Firefox-Account registrieren und testen, ob über die Firefox-Account-Authentifizierung der Sync auf dem eigenen Server funktioniert. Dies sieht man daran, dass Einträge in die Datenbank auf dem lokalen Server geschrieben werden – UND: Am Besten auf einem zweiten System den Sync-Abgleich beobachten. So kann man sich sicher sein, dass Daten abgelegt und abgerufen werden können.

Der Auth-Server (fxa-auth-server)

Sobald der Syncserver zuverlässig läuft, kann man sich an den etwas komplizierteren Teil wagen. Bis hierhin war alles noch Ponyhof und gut dokumentiert. Die Schritte zum funktionierenden Dreigespann Sync-Server <-> Auth-Server <-> Content-Server sind etwas aufwändiger, bzw. zeitraubender zu konfigurieren, da es an zig verschiedenen Stellen zu Problemen kommen kann, die man auch erst einmal finden muss, bzw. wissen muss, _was_ im Moment überhaupt das Problem ist…

Der Auth-Server besteht aus den Komponenten fxa-auth-server und dem MySQL-Backend „fxa-auth-db-mysql“. Letzteres ist auch als eigenständiges Projekt über Github zu erhalten. Das MySQL-Backend wird allerdings bereits mit fxa-auth-server „gebaut“ und ist später in der Installation im Verzeichnis ./fxa-auth-server/node-modules/fxa-auth-db-mysql  zu finden.

VHost für fxa-auth-server

Für den fxa-auth-Server wird ein Proxy-VHost definiert. Sprich: der lokal laufende Dienst unter Port 3030 wird von der Außenwelt über https + expliziten Domain-Name erreichbar gemacht.

Kurz noch die Vorgehensweise für das Anlegen eines VHosts für den Apache Webserver unter Ubuntu 14.04:

Das Vorgehen bei der Installation und Konfiguration ist grob auch hier bereits auf der GitHub-Seite beschrieben (https://github.com/mozilla/fxa-auth-server) – ich versuche in dieser Anleitung die einzelnen Schritte etwas genauer zu beschreiben.

Die Schritte, um die Quellen von GitHub zu holen sind wie folgt. Die Installation wird via npm vorgenommen. Hier ist es am Besten, nochmals zu checken, ob npm in einer relativ aktuellen Version läuft – bei mir hat der fxa-auth-server auch erst mit min. npm@2.4.x funktioniert. Aktuell läuft bei mir npm in der Version 2.14.12. Zu prüfen ist die npm-Installation mit dem Kommando npm --version .

Ob alles funktioniert hat und ob die entsprechenden geladenen Module funktionieren, kann mit dem Kommando npm test  geprüft werden. Es sollten hierbei keine Fehler auftauchen – ansonsten sollte man an dieser Stelle auf Fehlersuche gehen.

Bei der Konfiguration des Servers gibt es im Grunde 3 Dateien, welche ich im Laufe der Installation angelegt, bzw. editiert habe. Die Konfiguration sollte im Grunde aus dem „config“-Verzeichnis und der entsprechenden Umgebung geladen werden („dev“ oder „prod“). Daher habe ICH im config-Verzeichnis momentan zwei Dateien: prod.json und dev.json. Diese müssen händisch angelegt werden.

Inhalt der Datei:

Mit dem Kommando npm start  kann man jetzt den Auth-Server im „Memory Store Mode“ starten. Das bedeutet, dass in dem Fall noch keine MySQL-Verbindung genutzt wird. Für einen generellen Test und um zu prüfen, ob der Server überhaupt startet kann man diese Methode allerdings schon mal nutzen.

Das MySQL-Backend (fxa-auth-db-mysql)

Wie bereits erwähnt musste in früheren Versionen das MySQL-Datenbank-Backend als eigenes Projekt geladen werden. fxa-auth-db-mysql findet sich allerdings zwischenzeitlich(?) als Node-Modul unter ./fxa-auth-server/node-modules/fxa-auth-db-mysql .

Für das MySQL-Bankend des Auth-Servers ist auch wieder eine MySQL-Datenbank, sowie der entsprechende Datenbank-Benutzer notwendig. In meinem Beispiel nenne ich die Datenbank „fx-auth“ und den Benutzer ebenfalls „fx-auth“. Die Konfigurations-Datei für das MySQL-Backend befindet sich im von GitHub ausgecheckten und gebauten Verzeichnis ./fxa-auth-server/node_modules/fxa-auth-db-mysql/config. Hier wiederum sind je nach Umgebung (prod/dev) die Dateien prod.json und dev.json von Belang. Beide erhalten an dieser Stelle denselben Inhalt.

Die Datei bekommt folgenden Inhalt (MYSQL_PASSWORT_DES_BENUTZERS ist natürlich mit deinem Passwort für den angelegten MySQL-Benutzer zu ersetzen):

Zur Erklärung nochmals: Im Verzeichnis config befindet sich eine Datei „config.js“ mit allen möglichen „Default“-Werten für das Backend-Modul. Über die dev.json oder prod.json werden die benötigten Werte der config.js überschrieben. Abschließend noch für die dev-Umgebung die Datei kopieren: cp prod.json dev.json .

Der Auth-Server inklusive MySQL-Anbindung sollte jetzt über das Kommando „ npm run start-mysql “ gestartet werden können. Beim Output darauf achten ob und welche Fehlermeldungen hierbei erzeugt werden!

Der Content-Server (fxa-content-server)

Auch für den Content-Server wird ein Apache VHost angelegt. Die Vorgehensweise ist dabei gleich, wie beim fxa-auth-server. Die VHost-Datei für diesen Server benenne ich „101-fxa-content.DOMAIN.TLD.conf“.

Der Content-Server ist zuständig für die Web-Inhalte, die an den Benutzer ausgeliefert werden und erledigt die Logins(via Formular), Password-Resets, etc.

Um den Content-Server zu bauen, werden grunt-cli, sowie bower benötigt:

Dann wird das Git-Repository geladen und anschließend via npm gebaut:

Bei diesem Projekt wird bereits eine Beispiels-Konfiguration mitgeliefert:

Die Datei muss den entsprechenden Domains oder Subdomains angepasst werden.

Die Ubuntu Upstart-Scripts

Das Ubuntu-Upstart-System ist für den (automatisierten) Start und Stopp von Diensten zuständig. Den Start eines Dienstes kann man auch abhängig von einem anderen Dienst machen, der gestartet sein muss. Beispielsweise wäre es denkbar, die Syncserver-Dienste erst dann zu starten, wenn die Netzwerk-Dienste gestartet wurden. In den Beispielen belassen wir den Start des ersten Dienstes aus unserem Start beim Standard – sprich: im Runlevel 2.

An dieser Stelle kann man auch schnell prüfen, welches init-System auf dem aktuellen System zum Einsatz kommt: cat /proc/1/comm – Der Rückgabewert sollte hier „init“ sein. Alle derzeitigen init-Dienste kann man sich via initctl list  anzeigen lassen

Um zu prüfen, in welchem Runlevel das System im momentanen Zustand ist, kann mit dem Befehl who -r  geprüft werden.

Anbei noch kurz eine Beschreibung der Optionen in den Upstart-Scripts:

  • start on runlevel [2345] : Im Grunde würde hier „ start on runlevel [2] “ für unser Ubuntu 14.04-System genügen. Aus Kompatibilitätsgründen belässt man allerdings die restlichen Runlevel 3-5 im Script stehen.
  • start on fxa-auth-server : Die einzelnen Dienst-Scripts wollen wir nacheinander gestartet haben. Sprich: der Syncserver soll erst dann laufen, wenn der Auth-Server in Betrieb ist. Daher macht man den Start des Sync-Servers davon abhängig, ob der Auth-Server bereits läuft.
  • console log : die Ausgabe des gestarteten Dienstes soll in ein upstart-Log geschrieben werden. Sprich: Den Output für den via Upstart gestarteten Dienst finden wir unter /var/log/upstart/DIENSTNAME.log .
  • respawn : respawn bedeutet, dass der Dienst im Fehlerfall neu gestartet werden soll. via „limit“ legt man fest, wie oft probiert werden soll, den Dienst neu zu starten – in diesem Fall 10 Mal im Abstand von 5 Sekunden. Wenn der Dienst also beim 10. Mal nicht gestartet werden kann, wird auch nicht weiter probiert, den Dienst zu starten.
  • chdir /home/BENUTZER/SERVER : Der Start des scripts wie unter „exec“ angegeben, soll in diesem Verzeichnis stattfinden. Hat man die Dienste im Home-Verzeichnis des Benutzers konfiguriert, wird hier das Verzeichnis angegeben – entsprechend ist der Eintrag anzupassen, wenn die Dienst-Scripts im /opt/-Verzeichnis angelegt wurden.
  • env HOME=/home/BENUTZER : Für die Scripts muss die HOME-Umgebungsvariable gesetzt sein.

fxa-auth-server

fxa-content-server

syncserver

Dienste starten und stoppen / debugging

Die Dienste können über das Kommando „start DIENSTNAME“ gestartet und über das Kommando „stop DIENSTNAME“ gestoppt werden. Um zu prüfen, ob die Dienste automatisch korrekt gestartet werden, kann man das System neu starten und danach die gestarteten Dienste begutachten. Da wir immer die setuid gesetzt haben, kann man die gestarteten Dienste beispielsweise über das Kommando ps aux | grep BENUTZERNAME  einsehen.

Wenn Fehler auftauchen, bzw. der Sync-Test unter Firefox nicht funktioniert, ist es notwendig, die Logs durchzusehen und die entsprechenden Fehler zu lokalisieren: Sprich: die Logs der Dienste unter /var/log/upstart , sowie die Apache-Logs (falls die Apache-Proxies Probleme verursachen) unter /var/log/apache2/ .

Firefox-Browser für den Sync konfigurieren

Die Einträge im für die eigenen Server im Firefox-Browser müssen aktuell noch händisch über „about:config“(in der Adressleiste) eingegeben werden. Zum Testen des Syncs empfiehlt es sich, zwei Firefox-Browser auf verschiedenen Systemen zum Testen zu verwenden. Ich habe bei mir die Syncs auf einem Mac Mini, einem Windows 10- und einem Ubuntu 15.10-System getestet. Die Einträge sind auf allen Systemen gleich vorzunehmen. Es ist natürlich auch darauf zu achten, dass die entsprechenden Ports ausgehend auf den Test-Systemen freigegeben sind und nicht blockiert werden. Dies gilt hauptsächlich für den Syncserver, welcher auf Port 5000 angesprochen wird.

Hinweis zum Testen: Beim Testen der Syncs habe ich oftmals neu anfangen müssen und musste so relativ schnell den Firefox-Browser wieder in den Ausliefer-Zustand versetzen. Man kommt auf den Systemen relativ schnell zum Profil-Ordner, indem man in der Adress-Zeile: „about:support“ eintippt und in dem daraufhin angezeigten Fenster unter „Profilordner“ auf „Ordner anzeigen“ klickt. Man gelangt so in das Profilverzeichnis des aktuell geladenen Firefox-Profils. Ein bestehendes erstes Profil habe ich mir weggesichert. Für die Tests habe ich dann jeweils den Inhalt des übergeordneten Verzeichnisses komplett gelöscht – also den Verzeichnisinhalt, in welchem auch die „profiles.ini“-Datei liegt. Nach einem Neustart kann man sich dann wieder an das wie oben beschriebene Konfigurieren machen. Oftmals kommt es vor, dass beispielsweise der Firefox-Benutzer „angeblich“ registriert wird, in der Datenbank auf dem eigenen Server aber gar kein Account angelegt wurde. Der Browser behält diese Informationen beispielsweise ebenfalls in seiner Config. Daher auch jeweils der radikale Schritt mit dem Komplett-Löschen des Profils.

Fragen, Hinweise, Links, Weiterführendes

Die folgenden Seiten waren mir an den ein oder anderen Stellen beim Kampf mit dem Sync-Konstrukt hilfreich – evtl. findet sich hier für dich auch der ein oder andere Lösungsansatz:

    Zu diesem Beitrag gibt es noch keine Kommentare...

Kommentar verfassen