Hlavní navigace

Jak vypnout IPv6 privacy extensions na novém Androidu

26. 12. 2013 19:52 | Ondřej Caletka

Pod stromečkem jsem rozbalil nový mobil s Androidem 4.4 Kitkat. Bohužel musím konstatovat, že ani zcela nová verze operačního systému, která v USA pracuje v IPv6-only, pořád kašle na dodržování RFC 4941, se kterým byl Android až do verze 4 konformní:

Použití dočasných adres (pro ochranu soukromí) může způsobovat nečekané obtíže s některými aplikacemi. Servery mohou odmítnout spojení od klientů bez reverzního DNS záznamu. Navíc se některé aplikace nemusí chovat robustně pokud dočasná adresa vyprší před ukončením aplikace, nebo pokud otevře více spojení a očekává, že všechny budou používat stejné adresy. Z toho důvodu BY MĚLY (SHOULD) být dočasné adresy ve výchozím stavu zakázány.

Normativní jazyk zde používá slovo SHOULD, které se obvykle překládá jako: „Měli byste, pokud nemáte skutečně závažný důvod to nedělat.“ Přesto v podstatě veškeré aktuální platformy implementující IPv6 (počínaje Windows, přes Mac, až po nejnovější linuxové distribuce) tento příkaz porušují a dočasné adresy zapínají automaticky. To bych jim ani neměl za zlé, přeci jen se  tu a tam objeví někdo s názorem, že vyzrazení MAC adresy do Internetu je ten nejstrašnější zásah do soukromí, co existuje. I když tento názor nesdílím, jsem ochoten takovéto výchozí nastavení strpět. Co však již nestrpím, je přímý rozpor s jinou částí výše uvedeného RFC:

Zařízení implementující dočasné adresy pro ochranu soukromí MUSÍ poskytovat způsob, kterým může koncový uživatel explicitně povolit nebo zakázat použití dočasných adres.

Zatímco Windows tuhle podmínku beze zbytku splňují už od experimentálního IPv6 stacku ve verzi XP, na Linuxu založené systémy s tím mají překvapivě dost velký problém. Viděl jsem například distribuci s Network Managerem, který po každém připojení k síti automaticky zapnul dočasné adresy, aniž by tato volba byla někde uživatelsky editovatelná. Uživatel sice mohl nastavení změnit příslušným voláním sysctl, Network Manager jej však při příštím spojení opět přepsal.

Smutné je, že vývojáři systému Android se zachovali stejně špatně. Tamější správce sítí při každém úspěšném připojení k síti zapíše dvojku do souboru /proc/sys/net/ipv6/conf/<rozhraní>/use_tempaddr. Čekal jsem, že aspoň nejnovější verze nabídne někde hluboko v menu možnost tuto volbu vypnout, ale není tomu tak. Chyby jsou stále nahlášeny (ještě v diskuzi zde), kód se však moc nemění. Nezbývá tedy než vyhrnout si rukávy a upravit si systém svépomocí.

Protože jsem se chtěl vyhnout překompilovávání celého OS, vydal jsem se cestou přímého patchování binárky. Vlastní zapnutí obstarává program /system/bin/netd. Když v něm budete hledat klíčové slovo use_tempaddr, najdete jej na hromadě spolu ostatními texty:

$ hexdump -C netd
…
000111c0  79 00 25 73 2f 25 73 2f  25 73 00 64 69 73 61 62  |y.%s/%s/%s.disab|
000111d0  6c 65 5f 69 70 76 36 00  32 00 75 73 65 5f 74 65  |le_ipv6.2.use_te|
000111e0  6d 70 61 64 64 72 00 2e  00 2e 2e 00 61 6c 6c 00  |mpaddr......all.|
…

Když jsem před textem uviděl samostatný řetězec s dvojkou, zajásal jsem, že to je ono, že to je ta dvojka, která se do souboru zapíše. Přepsal jsem ji tedy na nulu a restartoval. Operační systém naběhl bez problému a na rozhraní skutečně nebyla dočasná IPv6 adresa. Mělo to však drobnou vadu na kráse, na rozhraní totiž nebyla žádná IPv6 adresa. :) Jak je to možné? Může za to optimalizace kompilátoru. Stejná dvojka, která se zapisuje do souboru use_tempaddr se totiž také zapisuje do souboru accept_ra, kde zapíná příjem RA i v režimu směrovače. Když jsem ji přepsal na nulu, kromě vypnutí dočasných adres jsem tedy také zároveň vypnul příjem veškerých RA. Tudy cesta nevede.

Poněkud méně čistá cesta spočívá v přepsání řetězce use_tempaddr za jiný, neexistující název souboru. Při pokusu o zápis do něj dojde k chybě, systém se s chybou bez problému vyrovná. Eventuálně je možné přepsat řetězec za accept_ra, do kterého by se dvojka zapsala dvakrát po sobě, což by nebylo na škodu.

Postup úpravy krok za krokem

  • Výchozím předpokladem je telefon s oprávněním roota, USB laděním. Ten by měl být připojen k PC vybaveném utilitkou adb (balík android-tools). Také se hodí zálohovat veškerá data pro případ, že se něco nepovede.
  • Z telefonu stáhneme původní binárku a zazálohujeme ji:
    $ adb pull /system/bin/netd
    $ cp netd netd.orig
  • Pomocí hexeditoru v binárce nalezneme řetězec use_tempaddr a přepíšeme na libovolnou hodnotu. Je také dobré zkontrolovat, že upravená binárka má stejnou velikost jako před úpravou a že se liší skutečně jen v obsahu zmíněného řetězce. Například Vim mi soustavně binárku prodlužoval o konec řádku.
  • Upravenou binárku nahrajeme na dočasné umístění v telefonu:
    $ adb push netd /sdcard/netd
  • Na telefonu přepíšeme původní binárku a opravíme práva:
    $ adb shell
    user@phone$ su
    root@phone# mount -o remount,rw /system
    root@phone# cp /system/bin/netd /system/bin/netd.orig
    root@phone# rm /system/bin/netd
    root@phone# cp /sdcard/netd /system/bin/netd
    root@phone# chown root:shell /system/bin/netd*
    root@phone# chmod 755 /system/bin/netd*
    root@phone# exit
    user@phone$ exit
  • Restartujeme telefon:
    $ adb reboot

Závěrem mi nezbývá než vyjádřit přání, že se někdo v Google konečně chytne za nos a chybu opraví systémově. Můžete tomu možná pomocí, přidáte-li hvězdičky k výše uvedeným hlášením chyb.

Přeji vše dobré v novém roce.