BahnBonus ohne Google-Id und auf dem eigenen Rechner

Screenshot: Ein bunter App-Bildschirm mit wenig Information und einem Spendenaufruf.  Es handelt sich um die BahnBonus-App der Bahn.

Objekt der Begierde: Die BahnBonus-App, die mich wieder in die DB-Lounges Einlass finden wird. Und zwar ganz ohne Apple und nur mit einer einfachen Überdosis Google.

Vor einem knappen Jahr habe ich eine Großbeichte abgelegt: Ja, ich nehme an so einem blöden, schnüffelnden Kundenbindungsprogramm teil, und dann noch an dem von der Bahn, bei dem VielfahrerInnen gemütlich im Sessel Kakao schlürfen, während gewöhnliche Reisende draußen am Bahnsteig frieren oder sich um die wenigen Sitzgelegenheiten in den Bahnhofsgebäuden streiten müssen: Ehemals bahn.comfort, jetzt BahnBonus.

Im zitierten Post habe ich dem Lounge-Zugang hinterhergeweint, denn seit einem knappen Jahr lässt die Bahn nur noch Menschen in die Lounges, die ferngewartete Computer („Smartphones“), und dann noch ziemlich neue davon, verwenden. Statt der alten Plastikkarte brauchte es jetzt eine, hust, App. Die tut nun (wie ich jetzt weiß und vorher ahnte) nicht nicht viel mehr als den Login-Bildschirm der Bahn-Webseite anzuzeigen und dann Links auf QR-Codes zu generieren. Wahrscheinlich etwas naiv habe damals gehofft, dass die Bahn die paar Zeilen Javascript, die es dafür braucht, auch auf ihre normale Webseite packt.

Das ist aber nicht passiert. Als die Bahn neulich BahnBonus-Papierwerbung geschickt hat („Sie haben Gold-Status!”), habe ich erneut eine Mail an den Bahn-Support geschrieben, wie es denn mit QR-Codes auf der Webseite stehe. Erneut war die Antwort ein nicht weiter erklärtes Nein. Dass die Bahn mit der Negativantwort aber etliche Gutscheine (insbesondere zum Lounge-Zugang) schickte, nahm ich als „nee, wir machen das nie, auch wenn es einfach ist“. Mag sein, dass es dabei ums Datensammeln geht, mag sein, dass das einfach Konzernpolitik ist.

Jedenfalls: Wenn ich wieder im Warmen Kakao schlürfen will, muss ich irgendwie auf Dauer an die QR-Codes kommen. Ferngewartete Computer kommen für mich allenfalls in virtuellen Maschinen in Frage, und so dachte ich mir: Ich probier mal, ob ich die BahnBonus-App nicht auch auf meinem normalen Rechner zum Laufen kriege.

Stellt sich raus: Das geht, und wenn mensch sich Google in einer VM austoben lässt, sogar mit vertretbarem Aufwand. Ich schreibe hier mal auf, was es für mich gebraucht hat; das mag ja bei anderen Digitalzwängen auch ein wenig helfen.

Android in QEMU aufsetzen

Ich gehe für die folgenden Schritte aus von einem Debian (bullseye) auf einem Intel- oder AMD-System, das nicht wesentlich älter ist als 15 Jahre. Im Prinzip dürfte aber fast alles auch auf jeder anderen Plattform gehen, auf der Qemu läuft.

Wenn ihr bei den folgenden Schritten irgendwo ins Schleudern kommt, lasst es mich bitte wissen – ich erweitere diese Erzählung gerne so, dass sie auch nicht übermäßig nerdigen Menschen etwas sagt.

(1) Qemu installieren – Qemu ist zunächst ein Emulator von allerlei Hardware. Da aber Android enorm ressourcenhungrig ist (also: jetzt für meine Verhältnisse), wäre alles furchtbar lahm, wenn der Android-Code nicht direkt von der CPU in eurem Rechner ausgeführt würde – ich werde Qemu also als Virtualisierer verwenden und nur in sehr zweiter Linie als Emulator. Achtet jedenfalls darauf, dass qemu KVM machen kann. Zum Ausgleich braucht ihr nur die amd64-Fassung, nicht all die anderen Architekturen, und insbesondere nicht ARM. In Bullseye sollte sowas hier reichen:

apt install qemu-system-gui qemu-system-amd64

[ich selbst habe an der Stelle aus Geiz qemu-system-x86 genommen; das geht auch, und damit ist alles etwas kompakter].

(2) Android-x86 besorgen – ich gestehe ehrlich, dass ich mich nicht sehr um die Vertrauenswürdigkeit der Leute rund um den Port von Android auf x86-Prozessoren gekümmert habe. Ich habe einfach ein passendes ISO-Image von deren FOSSHUB-Seite (Krapizität 10 lässt hoffen) runtergeladen; wenn ihr die amd64-Qemu installiert habt, wollt ihr jetzt das „64-bit ISO file“.

(3) Container fürs Android-Filesystem anlegen – euer Android muss seine Dateien irgendwo hinspeichern, und ihr wollt ihm gewiss keinen Zugriff auf euer echtes Dateisystem geben. Erzeugt also eine „virtuelle“ Festplatte für die Qemu-Daten. Dabei kommt ihr mit einem Gigabyte auch bei i386 nicht aus. Wenn ihr euch um Plattenplatz keine Sorgen macht: baut lieber gleich eine mit vier Gigabyte (4G am Ende der Kommandozeile).

Sucht euch auch irgendeinen Platz, wo ein Klops von der Größe nicht schlimm stört. Ich nehme hier mal ~/containers (was ihr dann wohl aus eurem Backup rausnehmen solltet):

mkdir -p ~/containers
qemu-img create -f qcow2 ~/containers/android.img 2G

Display-Probleme

Jetzt stellt sich das Problem, dass euer künftiges Android die Bildschirmausgabe irgendwo hinschicken muss. Qemu kann in ein ordinäres X-Fenster ausgeben, aber das ist – aus Gründen, die ich nicht untersucht habe – furchtbar lahm. Was für mich gut funkioniert hat: VNC. Wenn ihr damit nicht zurechtkommt, probiert unten mal QDISPLAY="-display gtk" (könnte halt kreuzlahm sein).

(4) Android-Installer starten – das braucht ein paar Optionen, damit das Ding auch ins Netz kommt und die beiden nötigen Dateien (die virtuelle Platte und den Android-Installer) findet:

QDISPLAY="-display vnc=localhost:0"
qemu-system-amd64 $QDISPLAY -enable-kvm -m 2000 \
  -net nic -net user -drive file=$HOME/containers/android.img,format=qcow2 \
  -boot d -cdrom /media/downloads/android-x86-9.0-r2.iso

Den Pfad in der -cdrom-Option müsst ihr ganz sicher anpassen, damit er auf das ISO zeigt, das ihr gerade runtergeladen habt. Lasst jetzt einen VNC-Client auf localhost:5600 los; ich empfehle in diesen Tagen remmina (aus dem gleichnamigen Debian-Paket).[1]

(5) Den Android-Container konfigurieren – wählt Installation to Hard disk aus, dann Create/Modify Devices. Ihr kommt in einen guten, alten, textbasierten Partitionierer. Als Disklabel wollt ihr nicht GPT haben (weil das später Ärger mit dem Bootloader GRUB gibt). Der Speicher, den ihr da partitioniert, ist der, den ihr in Schritt 3 angelegt habt. Packt die ganze „Platte“ in eine Partition, sagt Write (keine Sorge, mit den Optionen oben könnt ihr keine Daten von euch kaputtmachen) und dann Quit.

Ihr kommt dann zurück in den Android-Installer. Nach einem Ok könnt ihr das Filesystem auswählen – nehmt ext4.

Dann fragt der Installer, ob ihr einen GRUB haben wollt – ja, wollt ihr, sonst kommt euer Android nachher nur mit viel Mühe hoch.

Das System Directory wollt ihr wahrscheinlich nicht read/write haben (es sei denn, ihr wollt ernsthaft mit dem Android spielen). Das spart einiges an Platz.

(6) Android ins Netz lassen – an der Stelle sollte euch der Installer anbieten, Android-x86 zu starten. Tut das. Wählt eine Sprache aus – ich habe es bei „English (United States)“ belassen.

Es kann sein (ist bei mir passiert), dass das Ding nach der Sprachabfrage abstürzt und wieder beim Grub-Prompt vom Installer ist. Wenn das passiert, beendet die qemu (also: Control-C in deren Fenster) und schaut unten bei VM starten nach der Kommandozeile, die die Qemu ohne Installer hochzieht. Wir haben es hier mit kommerzieller Software zu tun, Gesundbooten ist also durchaus eine legitime Option.

Jedenfalls: nach der Sprachwahl will das Ding ins Netz, und ich fürchte, es hat keinen Sinn, ihm das zu verbieten. Sucht also nach Netzen. Ihr solltet genau eines sehen, VirtWifi oder sowas. Wählt das aus, seufzt und lasst schon mal auf eurem richtigen Rechner ein tcpdump -n laufen, um zu sehen, womit euer neues Android so alles plaudert (vgl. Die Wunden lecken).

Das „Checking for Updates“ hat bei mir über Minuten hinweg 100% CPU verbraten (mensch will gar nicht wissen, was es dabei zu rechnen gibt). Da ich den „ich tu gerade was“-Feedback im emulierten Android generell nicht so prall finde, könnt ihr die Zeit ja damit verbringen, eure CPU-Last-Anzeige am Desktop auf Vordermann zu bringen (mein Tipp: wmcore).

Dann fragt Android, ob es von irgendwoher eure Daten ziehen kann. Klar: das hätte Google gerne. Zum Glück gibts einen kleinen „Don't Copy“-Knopf. Genauso ist auch der Skip-Knopf im nächsten Dialog, dem Google-Signin, ziemlich klein, und Google nervt extra nochmal, wenn mensch ihn wählt. Wählt ihn trotzdem. Date and Time sind zur Abwechslung problemlos abnickbar, dann kommt ein Dialog zu „Google Services“, die mensch alle manuell ausschalten muss.

Das ist offenbar die Benutzerfreundlichkeit („User Experience“), über deren Mangel im Free Software-Bereich ich immer so viel höre. Ums Akzeptieren, dass Google immer und zu jeder Zeit Kram auf die VM packen kann, kommt mensch glaube ich nicht rum. Aber dafür ist es ja auch eine VM.

Den folgenden „Protect your Tablet“-Dialog finde ich interessant, weil die Benutzerführung, die mir gerade noch Vertrauen zu Google überhelfen wollte, nun Misstrauen gegen andere Menschen sät, und das gleich noch mit einem zweiten Extra-Mahn-Dialog, wenn ich keine Lust auf Geräte-PINs habe. Also ehrlich: wenn ich mit Google zu tun habe, mache ich mir doch über menschliche DiebInnen keine Sorgen…

Die abschließende Frage nach der Home-App verstehe ich auch nicht. Macht einfach irgendwas. Damit seid ihr im Android-Geschäft.

Apps ohne App-Store

(7) Home-Screen aufräumen – Wenn ihr gleich mal den „Home-Screen“ aufräumen wollt: jeweils lang ein Icon klicken und ziehen. Dann erscheint ein „Remove“-Feld, auf das ihr das Icon ziehen könnt. Macht das am besten mit allem außer dem Chrome. Den brauchen wir gleich. Die widerliche Google-Bar lässt sich, glaube ich, mit diesem Mitteln nicht entfernen. Wozu auch – der Container gehört ja, wie ihr gerade abgenickt habt, sowieso Google.

(8) Bahn-App finden – Die Bahn veröffentlicht, so weit ich weiß, keine APKs (also Pakete) von ihrer App. Insofern müsst ihr ins leicht schattige Geschäft der APK-Repulizierer gehen. Der derzeit erste Match bei duckduckgo, apkmirror.com, macht ohne Javascript und local storage gar nichts und hat auch die Bahn-Bonus-App gar nicht. Insofern würde ich trotz höherer Krapizität (um die 20 vs. 11.5) lieber zu https://apkpure.com gehen.

Startet also im Android den Chrome (mal wieder eine finstere Einwilligung – ihr müsst aber nicht viel mit dem Ding machen –, noch ein kleines „No thanks“ zum Einliefern hochpersonalisierter Daten bei Google) und tippt apkpure.com in die Adresszeile ein.

Klar, Cookiebanner mit Antipattern, und für eine Suchbox muss mensch auf die Lupe klicken (wer ist eigentlich auf diese Idee gekommen?), aber geschenkt. Sucht nach BahnBonus; ihr solltet genau einen Match haben. Klickt dann auf „Download“ und nochmal auf „Download APK“, und dann nochmal „Download APK“. Mein Quotum für Rants über „UX“ habe ich oben schon ausgeschöpft.

(9) Das APK installieren – bevor der Download anfängt, müsst ihr Chrome Zugriff auf den Massenspeicher geben. Big deal, nachdem der ohnehin Google gehört. Ich musste dann eine Weile rumklicken, bis ich die Downloads gefunden hatte und nochmal bestätigt hatte, dass ich ein APK runterladen will, auch wenn „could harm your Computer“ und so. Die Suche lohnt sich insbesondere dann, wenn sich sonst nichts mehr tut.

Im Zweifel macht „Downloads“ aus dem Chrome-Menü auf und doppelklickt auf das BahnBonus-APK (ja, das sind derzeit so rund 15 MB – was ist da nur alles drin?). Dann verweigert sich Android wieder, Chrome APKs installieren zu lassen, wieder müsst ihr ein paar Knopfe klicken. Dann könnt ihr endlich „Install“ klicken. Tut das.

Wenn das fertig ist, lasst die App noch nicht laufen, sondern sagt einfach „Done“.

(10) App auf den Homescreen legen – ich habe wirklich eine Weile rumgesucht, wie ich die doofe BahnBonus-Geschichte jetzt auf meinen Homescreen bekomme. Am Ende habe ich wieder lang auf den Hintergrund geklickt, bis „Widgets“ kam, habe dann nach „Taskbar“-Widgets gesucht, dort einen App-Launcher gepackt, und als ich den abgesetzt habe, konnte ich die BahnBonus-App auswählen. Ist das wirklich so gedacht?

Ach so: Ich habe in dem Launcher-Dialog der BahnBonus-App „Freeform“ erlaubt. Ich glaube, das Ding ist so geschrieben, dass das anders nicht gut geht.

(11) VM runterfahren – wenn ihr soweit gekommen seid, ohne dass der Kram allzu oft abgestürzt ist, ist es Zeit, den Qemu mal ordentlich runterzufahren. Leider habe ich dafür keinen normalen Weg gefunden, weil VNC wohl keinen Ein-Ausschalter im Protokoll vorsieht. Vielleicht könnte mensch da einen geeigneten Keycode finden, aber ich hatte schon ein Terminal entdeckt, und so schien mir das naheliegender, jedenfalls, nachdem ich rausbekommen habe, dass shutdown -h mit dem Android-init reboot -p (p wie „power“) heißt. Um ein entsprechendes Icon zu erzeugen, klickt ihr wieder lange auf den Homescreen, bis das Menü mit den „Widgets“ kommt.

In der Liste, die dann kommt, scrollt ihr, bis ihr „Terminal Emulator“ findet. Das zugehörige Icon zieht ihr, bis es irgendwo auf dem Homescreen landet. Dann kommt ein Dialog, in dem ihr bei Command bash eintippt, bei Arguments su -c "reboot -p" und bei Shortcut Label Shutdown. Ihr kriegt dann ein neues Icon, auf das ihr klicken könnt, und wenn ihr das macht und dem Ding dann das Nötige erlaubt – so einfach kann das rooten sein! – , wird sich euere Qemu ganz ordentlich von selbst verabschieden. Das ist zumindest etwas besser, als sie einfach per Control-C abzuwürgen, auch wenn das ext4-Filesystem im Android-Image Schlimmeres verhindern sollte.

VM starten

Im Regelbetrieb starte ich den Emulator mit einem kurzen Skript der Art:

QDISPLAY="-display vnc=localhost:0"
qemu-system-amd64 $QDISPLAY -enable-kvm -m 2000 -net nic -net user\
  -drive file=$HOME/containers/android.img,format=qcow2

– und lasse anschließend wie eben auch schon ein remmina auf den VNC-Port los. Ich habe kurz überlegt, ob ich einfach ein remmina-Profil machen sollte, das das unter „Execute a command before connecting“ laufen lässt; aber ich plane eigentlich nicht, das viel laufen zu lassen.

Ihr solltet jetzt die Bahn-App durch draufklicken laufen lassen können. Erschreckt nicht: die erzwingt wie angekündigt so eine Telefon-Auflösung. Auflösungsunabhängiges Programmieren ist also noch im Jahr 2023 ein Thema. Wann war das am Atari ST eigentlich schon im Wesentlichen gelöst? 1986? Wenn wer weiß, wie ich das Android dazu bringe, gleich von vorneherein in Telefonauflösung zu laufen: lasst es mich wissen.

Interessanterweise müsst ihr auch in der App durch die grässliche hCaptcha-Tortur, was mich schon ein wenig besänftigt, denn bisher hing ich der Verschwörungstheorie an, das sei eine gezielte Belästigung der Desktop-KundInnen. Die App merkt sich den Login-Status aber, glaube ich, etwas länger als ein Browser.

Fluch und schräger Segen proprietärer Software

Ich muss an der Stelle nochmal meine Überraschung loswerden, wie oft mein Android spontan neu gebootet hat. Mag sein, dass das in den ARM-Versionen besser ist, aber etwas enttäuschend finde ich diese Instabilität doch (Uptime von meiner richtigen Kiste hier: 78 Tage, was wohl heißt, dass ich mal wieder einen neuen Kernel bauen sollte). Es hat sich aber jedenfalls bei mir immer wieder gleich gesundgebootet, ohne dass ich etwas anfassen oder verstehen musste. Die Freuden der kommerziellen Software.

Der spezielle Fluch kommerzieller Software, ständig „lass uns an dir Geld verdienen“-Blödsinn wegklicken zu müssen, hat mir wieder in Erinnerung gerufen, in was für einer schönen Uptopie ich dank all der Leute lebe, die zu Debian beitragen.

Ach weh. Wir könnten das mit einem Mindestmaß von Antikapitalismus auch bei der Welt insgesamt haben…

Die Wunden lecken

Ich hatte das oben erwähnte tcpdump tatsächlich laufen, während ich die Installationsprozedur durchgegangen bin. Und dann habe ich mit:

sed -e 's/.*IP6* \([^ ]*\).*/\1/' setuplog | sort | uniq

die IP-Adressen rausgesucht, mit denen mein Computer im Auftrag von Google so kommuniziert hat. Ich habe weiter manuell ein paar ARP- und EAPOL-Zeilen sowie Zeilen für meine eigenen Rechner rausgeworfen. Das Ergebnis: 105 Maschinen, bei denen Google und apkpure und die Bahn für mich Datenspuren angelegt haben.

Ich habe mir die Mühe gemacht, den IP-Adressen mittels whois nachzugehen. Hier mein Ergebnis (wohlgemerkt: bei einer maximal, hust, Daten-achtsamen Android-Installation):

  • Ungefähr 10 cloudflare-Maschinen in 104er-Netzen.
  • Eine cloudfront-Maschine in 108.x.
  • Irgendwer wollte mit zwei Kisten im Netz von clients.your-server.de sprechen.
  • Eine Handvoll Hosts im Netz von tencent.com, also dem chinesischen Hersteller von tiktok. Echt jetzt, Google?
  • Um die 50 Maschinen, deren 142.250er IPs zu irgendwas.1e100.net auflösen; das ist nur ein Nerdwitz. Es sind schlicht Kisten von Google.
  • Eine fastly-Maschine habe ich gefunden; fastly ist noch so ein CDN, also ein Betreiber von Rechnern in KundInnennähe zum Auspielen beliebter Dateien.
  • Kisten von OVH, quasi der französische Hetzner (das ist wiederum der Laden, auf dessen Rechnern die Maschine läuft, die diesen Blog ausliefert).
  • Eine Handvoll Kisten von facebook, die irgendwie meinen DNS-Blocks für den Laden entkommen sind.
  • Dann wieder zehn Google-Kisten im 172.217er-Bereich
  • Ein paar Zeilen weiter nochmal ein paar Cloudflare-Maschinen (172.67)
  • Nochmal drei weitere Google-Kisten aus 173.194.* (ich beginne zu verstehen, warum IPv4-Adressen so knapp sind).
  • Dann, unvermeidlich, amazon – ich hatte mich schon gefragt, wo die bleiben, aber dass Google sich wohl nicht so sehr der Elastic Cloud bedienen wird, ist vielleicht nicht überraschend. Nun, jedenfalls drei Mal amazon im 18.*-Bereich.
  • Dann „dataweb“. Nie von gehört, Webseite mit Krapizität 115, ohne Javascript eine weiße Seite. Ich wills gar nicht wissen.
  • Ein Laden namens fdcservers.net, ansässig in Destin, FL. Mit zwei Kisten. Florida. Ich sage lieber nichts, bevor ich mich wegen Ageismus angreifbar mache.
  • Interessanterweise zwei Mal Akamai (auch sowas wie cloudflare, nur nicht ganz so schmierig) mit unverschlüsseltem HTTP. Ich bin ja immer noch für einen vernünftigen Umgang mit HTTPS und würde entsprechend das HTTP völlig entspannt sehen. Im Gegenteil: all der Mist, den ich bisher beschrieben habe, war HTTPS, und der Haupteffekt der Verschlüsselung war, dass Google Informationen von meinem Rechner aus verschickt hat, die ich wirklich nur mit extrem viel Mühe hätte einsehen können.
  • Noch mehr Akamai über IPv6, und dann auch wieder HTTPS; insgesamt bin ich überascht, dass fast alles bei der Installation immer noch über IPv4 ging. Auch Akamai hat dann nochmal im 95.101er-Bereich IPv4. Einen geplanten Eindruck hinterlässt das nicht.
  • NTP-Anfragen an gleich drei verschiedene Google-Maschinen
  • Mehr Google-Maschinen in den Netzen 216.58, 25.190, 52.222, 74.125.
  • Interessanterweise die Google-Maschinen 64.233.166.188, 64.233.184.188 und 74.125.133.188 jeweils auf Port 5228 – dazu steht nichts in meiner /etc/services. Was Google meine Maschine da wohl hat machen lassen?
  • Zwei Rechner des russischen vkontakte-Mists. Ein Glück, dass ich so unpatriotisch bin.
  • Irgendwas von yahoo – das Erste, was ich von denen seit Jahren mitbekomme. Ich hätte nicht gedacht, dass die überhaupt noch Rechner im Internet betreiben.
  • Ah! Die Wikimedia Foundation. Ja, ich habe was in der Online-Wikipedia nachgelesen während der Installation, und so war dieser eine Rechner bestimmt nicht die Schuld von Google und der Bahn. NB: Das ist genau ein Host. So gehört sich das in einem vernünftig organisierten Internet.
  • Schließlich was von „Edgecast“ aus Los Angeles. Am Ende dieser Übersicht muss ich jetzt einfach einen faulen Witz über Tarnunternehmen von Marcellus Wallis reißen.

Danke, Bahn, dass ihr mich in dieses Netz des Wahnsinns reingezogen habt. Hättet ihr nicht einfach die QR-Codes aus eurer Webseite rausziehbar machen können? Aber Oh! Mit wem rede ich da?

Nachtrag (2023-03-29)

Zur Ehrenrettung von Google merke ich an, dass der vkontakte-Kontakt von apkpure kam. Warum nochmal kann die Bahn das apk nicht einfach auf ihre Webseite stellen?

[1]Sicherheitshinweis: in dieser Konfiguration kann jedeR, der_die auf eurer Maschine ist, euer Android bedienen. Verglichen mit allen anderen Risiken der Android-Nutzung ist das für mich vernachlässigbar, aber ich wollte es gesagt haben. Wenn euch das dennoch gruselt: lest die manpage von qemu-system und nehmt ein spice-Display (remmina kann auch damit reden).

Zitiert in: Ach Bahn, Teil 14: „HalloDummy ABC-Dummy“ Ach Bahn, Teil 12: „Digitales“ 49-Euro-Ticket

Kategorie: edv

Letzte Ergänzungen