Ako začať používať režim používateľa v systéme Linux

Úvod od prekladateľa: Na pozadí masívneho vstupu rôznych kontajnerov do našich životov môže byť celkom zaujímavé a užitočné zistiť, odkiaľ sa tieto technológie začali. Niektoré z nich môžeme so ziskom používať aj dnes, ale nie všetky sa pamätajú (alebo vedia, ak ich nezažili počas ich búrlivého rozvoja). Jednou z takýchto technológií je User Mode Linux. Autor originálu sa dosť zamotala, aby zistila, čo zo starých výsledkov ešte funguje a čo už nie, a zozbierala niečo ako krok za krokom návod na to, ako si sám založiť domáci UML v 2k19. A áno, pozvali sme na Habr autora originálneho príspevku. Cadey, takže ak máte otázky — pýtajte sa v angličtine v komentároch.

Ako začať používať režim používateľa v systéme Linux

User Mode v Linuxe je vlastne port jadra Linux na samo seba. Tento režim umožňuje spustiť plnohodnotné jadro Linux ako používateľský proces a zvyčajne ho používajú vývojári na testovanie ovládačov. Tento režim je však tiež užitočný ako nástroj na všeobecnú izoláciu, princíp, ktorý je podobný fungovaniu virtuálnych strojov. Tento režim poskytuje väčšiu izoláciu ako Docker, ale menšiu ako plnohodnotný virtuálny stroj ako KVM alebo Virtual Box.

Vo všeobecnosti sa môže User Mode zdať čudným a komplikovaným nástrojom na používanie, ale predsa má svoje oblasti uplatnenia. Veď je to plnohodnotné jadro Linuxu, ktoré funguje od nepriviligovaného používateľa. Táto vlastnosť umožňuje spúšťať potenciálne nedôveryhodný kód bez akýchkoľvek hrozieb pre hostiteľský stroj. A keďže ide o plnohodnotné jadro, jeho procesy sú izolované od hostiteľského stroja, to znamená procesy bežiace v rámci User Mode nebudú viditeľné pre hostiteľa. To sa nelíši od obvyklého Docker kontajnera, kde hostiteľský stroj vždy vidí procesy vo vnútri úložiska. Pozrite sa na tento kúsok pstree z jedného z mojich serverov:

containerd─┬─containerd-shim─┬─tini─┬─dnsd───19*[{dnsd}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─aerial───21*[{aerial}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─s6-svscan───s6-supervise
           │                 │      └─surl
           │                 └─9*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─h───13*[{h}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─goproxy───14*[{goproxy}]
           │                 └─9*[{containerd-shim}]
           └─32*[{containerd}]

A porovnajte to s pstree jádra Linuxu v uživatelském režimu:

linux─┬─5*[linux]
      └─slirp

Při práci s Docker kontejnery mohu z hostitele vidět názvy procesů běžících v hostované systému. S Linux User Mode to možné není. Co to znamená? Znamená to, že nástroje pro monitorování, které pracují prostřednictvím subsystému auditu Linuxu (Linux’s auditing subsystem) nevidí procesy vykonávané v hostované systému. Ale v některých situacích může tato vlastnost být dvojsečná.

Celý níže uvedený příspěvek je soubor výzkumů a hrubých pokusů dosáhnout požadovaného výsledku. K tomu jsem musel použít různé staré nástroje, přečíst zdrojové kódy jádra, intenzivně debugovat kód napsaný v době, kdy jsem ještě chodil do základní školy, a také se hrabat v sestaveních Heroku s pomocí speciálního binárního souboru, abych našel potřebné nástroje. Tato veškerá práce vedla k tomu, že kluci v mém IRC začali nazývat mě čarodějnicí (magic). Doufám, že tento příspěvek poslouží někomu jako spolehlivá dokumentace k tomu, aby udělal totéž, ale už s novějšími jádry a verzemi OS.

Nastavenie

Nastavení Linux User Mode se provádí ve několika krocích:

  • instalace závislostí na hostiteli;
  • stažení jádra Linux;
  • nastavení sestavení jádra;
  • sestavení jádra;
  • instalace binárního souboru;
  • nastavení hostované souborové soustavy;
  • výběr parametrů spuštění jádra;
  • nastavení hostované sítě;
  • spuštění hostovaného jádra.

Predpokladám, že ak sa rozhodnete to všetko spravit sami, pravdepodobne budete používať nejaký systém založený na Ubuntu alebo Debian. Snažila som sa realizovať všetko vyššie uvedené v mojej obľúbenej distribúcii — Alpine, ale nič nevyšlo, zjavne kvôli tomu, že jadro Linux má prísne prepojenie na glibc-isms pre ovládače v režime používateľa. Plánujem o tom informovať upstream, keď sa konečne dostanem do problémov.

Inštalácia závislostí na hostiteľovi

Ubuntu vyžaduje minimálne nasledujúce balíky na zostavenie jadra Linux (za predpokladu, že máte čistú inštaláciu):

- 'build-essential'
- 'flex'
- 'bison'
- 'xz-utils'
- 'wget'
- 'ca-certificates'
- 'bc'
- 'linux-headers'

Tieto môžete nainštalovať pomocou nasledujúcej príkazu (s právami root alebo pomocou sudo):

apt-get -y install build-essential flex bison xz-utils wget ca-certificates bc 
                   linux-headers-$(uname -r)

Všimnite si, že spustenie programu pre nastavenie menu jadra Linux si vyžaduje inštaláciu libncurses-dev. Prosím, uistite sa, že je nainštalovaný pomocou nasledujúcej príkazu (s právami root alebo pomocou sudo):

apt-get -y install libncurses-dev

Sťahovanie jadra

Určte miesto na stiahnutie a následné zostavenie jadra. Na túto operáciu budete musieť uvoľniť približne 1,3 GB priestoru na pevnom disku, takže sa uistite, že ho máte.

Potom prejdite na kernel.org a získajte URL na stiahnutie poslednej stabilnej verzie jadra. V čase písania tohto príspevku to je: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Stiahnite tento súbor pomocou 'wget':

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

A rozbaľte ho pomocou 'tar':

tar xJf linux-5.1.16.tar.xz

Teraz prejdite do adresára vytvoreného pri rozbalení tarballu:

cd linux-5.1.16

Nastavenie zostavy jadra

Systém zostavy jadra je súbor Make-fájlů s množstvom užívateľských nástrojov a skriptov na automatizáciu procesu. Na začiatok otvorte interaktívny program na nastavenie:

make ARCH=um menuconfig

Čiastočne vykoná zostavenie a zobrazí vám dialógové okno. Keď sa na spodnej strane okna objaví ‘[Select]‘, budete môcť začať nastavovanie pomocou klávesov Space alebo Enter. Navigácia v okne ako obvykle, šípkami klávesnice ‚hore‘ a ‚dole‘, a zvýraznenie prvkov — ‚vľavo‘ alebo ‚vpravo‘.

Ukazovateľ formátu —> znamená, že ste v podmenu, do ktorého sa vstupuje stlačením klávesu Enter. Výstup z neho je zjavne cez ‘[Exit]‘.

Povoľte nasledujúce možnosti v ‘[Select]‘ a uistite sa, že vedľa nich je symbol ‘[*]’:

Možnosti špecifické pre UML:
  - Hostiteľský súborový systém
Podpora sieťovania (povoľte to, aby sa podmenu zobrazilo):
  - Možnosti sieťovania:
    - TCP/IP sieťovanie
UML sieťové zariadenia:
  - Virtuálne sieťové zariadenie
  - SLiRP transport

Zo všetkých možností tohto okna môžete odchádzať výberom po jednom na ‘[Exit]‘. Uistite sa však, že na konci vám ponúkne uložiť konfiguráciu a vyberiete ‘[Áno]‘.

Odporúčam vám experimentovať s parametrami zostavovania jadra po prečítaní tohto príspevku. Tieto experimenty vám poskytnú mnoho poznatkov o pochopení fungovania nízkoúrovňových mechanizmov jadra a vplyv rôznych vlajok na jeho zostavenie.

Zostavenie jadra

Jadro Linuxu je veľký program, ktorý spravuje množstvo úloh. Aj pri takej minimálnej konfigurácii na starom hardvéri môže jeho zostavenie trvať určitý čas. Preto zostavte jadro pomocou nasledujúceho príkazu:

make ARCH=um -j$(nproc)

Prečo? Tento príkaz povie nášmu nástroju na zostavovanie, aby využil všetky dostupné jadrá a vlákna procesora v priebehu zostavovania. Príkaz $(nproc) na konci Build nahrádza výstup príkazu nproc, ktorý je súčasťou coreutils v štandardnej zostave Ubuntu.

Po uplynutí určitých časov bude naše jadro zostavené do spustiteľného súboru ./linux.

Inštalácia binárneho súboru

Keďže User Mode v Linuxe vytvára bežný binárny súbor, môžete ho nainštalovať ako ktorúkoľvek inú utilitu. Takto som to robila ja:

mkdir -p ~/bin
cp linux ~/bin/linux

Tiež by ste sa mali uistiť, že ~\/bin je vo vašom $PATH:

export PATH=$PATH:$HOME/bin

Nastavenie hostiteľského súborového systému

Vytvorte adresár pre hostiteľský súborový systém:

mkdir -p $HOME/prefix/uml-demo
cd $HOME/prefix

Otvorenie alpinelinux.org a v časti sťahovania nájdite aktuálny odkaz na stiahnutie MINI ROOT FILESYSTEM. V čase písania tejto publikácie to bolo:

http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz

Stiahnite si tento tarball pomocou wget:

wget -O alpine-rootfs.tgz http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz

Teraz prejdite do adresára hostiteľského súborového systému a rozbaľte archív:

cd uml-demo
tar xf ../alpine-rootfs.tgz

Opísané kroky vytvoria malý šablónový súborový systém. Z dôvodu fungovania systému bude veľmi ťažké inštalovať balíky cez správcu apk Alpine. Avšak táto FS bude postačujúca na zhodnotenie celkovej myšlienky.

Tiež budeme potrebovať nástroj tini na zastavenie spotreby pamäte zombie procesmi nášho hostiteľského jadra.

wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static
chmod +x tini

Vytvorenie príkazového riadku jadra

V jadre Linux, ako aj v mnohých iných programoch, existujú argumenty príkazového riadku, s ktorými sa môžete oboznámiť zadáním kľúča --help.

Samotný —help

linux --help
User Mode Linux v5.1.16
        k dispozícii na http://user-mode-linux.sourceforge.net/

--showconfig
    Vytlačí konfiguračný súbor, z ktorého bol tento UML binárny súbor vygenerovaný.

iomem=,
    Nakonfigurujte  ako IO pamäťovú oblasť s názvom .

mem=
    Toto ovláda, koľko "fyzickej" pamäte jadro prideľuje
    pre systém. Veľkosť sa určuje ako číslo nasledované
    jedným z 'k', 'K', 'm', 'M', ktoré majú očividné významy.
    To nie je priamo spojené s množstvom pamäte v hostiteľovi. Môže
    to byť viac a nadbytok, ak sa niekedy použije, bude len vymenený.
        Príklad: mem=64M

--help
    Vytlačí túto správu.

debug
    tento príznak nie je potrebný na spustenie gdb na UML v skas móde

root=
    Toto sa naozaj používa generickým jadrom presne rovnakým
    spôsobom ako v akomkoľvek inom jadre. Ak nakonfigurujete niekoľko blokových
    zariadení a chcete bootovať z niečoho iného ako ubd0, použijete
    niečo ako:
        root=/dev/ubd5

--version
    Vytlačí číslo verzie jadra.

umid=
    Toto sa používa na priradenie jedinečnej identity tejto UML
    mašine a používa sa na pomenovanie pid súboru a správy konzoly.

con[0-9]*=
    Pripojí konzolu alebo sériovú linku k hostiteľskému kanálu. Pozrite
    http://user-mode-linux.sourceforge.net/old/input.html pre úplný
    popis tohto prepínača.

eth[0-9]+=,
    Nakonfigurujte sieťové zariadenie.
    
aio=2.4
    Toto sa používa na vynútenie UML, aby používal 2.4-štýlový AIO aj keď je k dispozícii 2.6 AIO.
    2.4 AIO je jeden vláknový proces, ktorý spracováva jeden požiadavok
    naraz, synchronne. 2.6 AIO je vlákno, ktoré využíva 2.6 AIO
    rozhranie na spracovanie ľubovoľného počtu čakajúcich požiadaviek. 2.6 AIO
    nie je k dispozícii v tt mode, na 2.4 hostiteľoch, alebo keď je UML zostavený s
    /usr/include/linux/aio_abi.h nemusí byť k dispozícii. Mnohé distribúcie
    neobsahujú aio_abi.h, takže ho budete musieť skopírovať z jadrového stromu do
    vašej /usr/include/linux, aby ste zostavili AIO-schopný UML

nosysemu
    Vypína emuláciu syscall patch pre ptrace (SYSEMU).
    SYSEMU je výkonový patch predstavený Laurentom Vivierom. Mení
    správanie ptrace() a pomáha znížiť sadzby prepínania kontextu hostiteľa.
    Aby to fungovalo, potrebujete aj patch pre hostiteľské jadro.
    Pozrite http://perso.wanadoo.fr/laurent.vivier/UML/ pre ďalšie
    informácie.

uml_dir=
    Miesto na umiestnenie súborov pid a umid.

quiet
    Vypína informačné správy počas spustenia.

hostfs=,,...
    Toto sa používa na nastavenie parametrov hostfs. Argument
    koreňového adresára sa používa na obmedzenie všetkých
    hostfs mountov v rámci špecifikovanej adresárovej štruktúry
    na hostiteľovi. Ak to nie je špecifikované, používateľ vo vnútri UML
    môže pripojiť čokoľvek na hostiteľovi, ktoré je prístupné užívateľovi,
    ktorý to vykonáva.
    Jediný aktuálne podporovaný príznak je 'append', ktorý určuje,
    že všetky súbory otvorené hostfs budú otvorené v režime append.

Toto plátno osvětluje hlavné parametre spustenia. Poďme spustiť jadro s minimálnym potrebným súborom možností:

linux 
  root=/dev/root 
  rootfstype=hostfs 
  rootflags=$HOME/prefix/uml-demo 
  rw 
  mem=64M 
  init=/bin/sh

Riadky vyššie hovoria nášmu jadru nasledovné:

  • Predpokladajme, že koreňový súborový systém je pseudopdevice /dev/root.
  • Vyber hostfs ako ovládač koreňového súborového systému.
  • Pripoj hostiteľský súborový systém, ktorý sme vytvorili v root zariadení.
  • A áno, v režime na čítanie a zápis.
  • Použi len 64 megabajtov operačnej pamäte (môžeš použiť oveľa menej v závislosti od toho, čo plánuješ robiť, ale 64 MB sa zdá byť optimálnym objemom).
  • Jadro sa automaticky spúšťa /bin/sh ako init-proces.

Spusti tento príkaz a mal by si získať niečo ako nasledujúce:

Ešte jeden hárok

Limity core dumpu :
        mäkký - 0
        tvrdý - ŽIADNY
Kontrola, či ptrace môže meniť čísla systémových volaní...OK
Kontrola emulácie systémových volaní pre ptrace...OK
Kontrola pokročilej emulácie systémových volaní pre ptrace...OK
Kontrola premenných prostredia pre dočasný adresár...žiadny nájdený
Kontrola, či je /dev/shm na tmpfs...OK
Kontrola PROT_EXEC mmap v /dev/shm...OK
Pridanie 32137216 bajtov do fyzickej pamäte na pokrytie medzery exec-shield
Verzia Linuxu 5.1.16 (cadey@kahless) (gcc verzia 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Ne 7. júl 2019 18:57:19 UTC
Zostavené 1 zoznamy zón, skupinová mobilita zapnutá.  Celkový počet strán: 23898
Príkazový riadok jadra: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh
Dentry cache hash tabuľky: 16384 (poradie: 5, 131072 bajtov)
Inode-cache hash tabuľky: 8192 (poradie: 4, 65536 bajtov)
Pamäť: 59584K/96920K dostupná (2692K kód jadra, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K rezervovaných, 0K cma-rezervovaných)
SLUB: HWalign=64, Poradie=0-3, MinObjects=0, CPU=1, Uzly=1
NR_IRQS: 15
časový zdroj: časovač: maska: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Kalibrácia oneskorenia... 7479.29 BogoMIPS (lpj=37396480)
pid_max: predvolené: 32768 minimum: 301
Mount-cache hash tabuľky: 512 (poradie: 0, 4096 bajtov)
Mountpoint-cache hash tabuľky: 512 (poradie: 0, 4096 bajtov)
Kontrola, či hostiteľské ptys podporujú výstup SIGIO...Áno
Kontrola, či hostiteľské ptys podporujú SIGIO pri zatvorení...Nie, povoľovanie obídenia
devtmpfs: inicializované
náhodné: get_random_bytes volané zo setup_net+0x48/0x1e0 s crng_init=0
Používanie 2.6 host AIO
časový zdroj: jiffies: maska: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash tabuľky: 256 (poradie: 0, 6144 bajtov)
NET: Registrovaná rodina protokolov 16
časový zdroj: prechod na časový zdroj časovača
NET: Registrovaná rodina protokolov 2
tcp_listen_portaddr_hash hash tabuľky: 256 (poradie: 0, 4096 bajtov)
TCP etablované hash tabuľky: 1024 (poradie: 1, 8192 bajtov)
TCP bind hash tabuľky: 1024 (poradie: 1, 8192 bajtov)
TCP: Hash tabuľky konfigurované (etablované 1024 bind 1024)
UDP hash tabuľky: 256 (poradie: 1, 8192 bajtov)
UDP-Lite hash tabuľky: 256 (poradie: 1, 8192 bajtov)
NET: Registrovaná rodina protokolov 1
konzola [stderr0] zakázaná
mconsole (verzia 2) inicializovaná na /home/cadey/.uml/tEwIjm/mconsole
Kontrola podpory hostiteľa MADV_REMOVE...OK
pracovná sada: timestamp_bits=62 max_order=14 bucket_order=0
Bloková vrstva vodič SCSI generic (bsg) verzia 0.4 načítaná (hlavný 254)
jazdec io noop registrovaný (predvolené)
jazdec io bfq registrovaný
loop: modul načítaný
NET: Registrovaná rodina protokolov 17
Inicializovaný vodič konzoly stdio
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 1: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 2: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 3: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 4: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 5: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 6: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 7: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 8: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 9: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 10: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 11: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 12: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 13: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 14: Konfigurácia zlyhala
Použitie typu kanála, ktorý je nakonfigurovaný mimo UML
setup_one_line zlyhal pre zariadenie 15: Konfigurácia zlyhala
Konzola inicializovaná na /dev/tty0
konzola [tty0] povolená
konzola [mc-1] povolená
Nepodarilo sa inicializovať zariadenie ubd 0: Nedá sa určiť veľkosť súboru zariadenia
VFS: Pripojený root (hostfs súborový systém) na zariadení 0:11.
devtmpfs: pripojené
Táto architektúra nemá ochranu pamäte jadra.
Spustite /bin/sh ako init proces
/bin/sh: nemožno pristupovať k tty; ovládanie úloh vypnuté
náhodné: rýchly init dokončený
/ # 

Manipulácie vyššie nám poskytnú hostený systém na minimálnych nárokoch, bez takých vecí, ako sú /proc alebo priradený hostname. Napríklad, skúste vykonať nasledujúce príkazy:

- uname -av
- cat /proc/self/pid
- hostname

Aby ste sa dostali z hosteného systému, zadajte exit alebo stlačte control-d. To zabije shell s následným kernel panic:

/ # exit
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
fish: “./linux root=/dev/root rootflag…” terminated by signal SIGABRT (Abort)

Tento kernel panic sme dostali, pretože jadro Linuxu považuje, že proces inicializácie je vždy spustený. Bez neho systém už nemôže fungovať a ukončí svoju činnosť. Avšak, keďže ide o proces užívateľského módu, získaný výsledok sa sám seba posiela do SIGABRT, čo vedie k výstupu.

Nastavenie hostiteľskej siete

A tu už veci idú podľa plánu. Sieť v User Mode Linux — to je miesto, kde sa celá koncepcia obmedzeného „užívateľského módu“ začne rozpadávať. Veď obvykle na systémovej úrovni je sieť obmedzená privilegovanými režimami vykonávania z nám všetkým známych dôvodov.

Pozn. prekl.: viac o rôznych možnostiach práce so sieťou v UML si môžete prečítať tu.

Cesta do slirp

Existuje však starý a prakticky nepodporovaný nástroj s názvom Slirp, pomocou ktorého môže User Mode Linux komunikovať so sieťou. Funguje to približne ako TCP/IP zásobník na úrovni užívateľa a nevyžaduje žiadne systémové povolenia na spustenie. Tento nástroj bol vydaný v roku 1995, pričom posledná aktualizácia sa datuje do roku 2006. Slirp je veľmi starý. Počas obdobia bez podpory a aktualizácií sa kompilátory dostali do takej vzdialenosti, že tento nástroj môžeme charakterizovať iba ako „code rot“.

Takže poďme nainštalovať Slirp z repozitárov Ubuntu a vyskúšajme ho spustiť:

sudo apt-get install slirp
/usr/bin/slirp
Slirp v1.0.17 (BETA)

Copyright (c) 1995,1996 Danny Gasparovski a ďalší.
Všetky práva vyhradené.
Tento program je chránený autorským právom, voľný softvér.
Prosím, prečítajte si súbor COPYRIGHT, ktorý prišiel s balíkom Slirp
pre podmienky a ustanovenia autorského práva.

IP adresa hostiteľa Slirp: 127.0.0.1
IP adresa vášho DNS (í): 1.1.1.1, 10.77.0.7
Vaša adresa je 10.0.2.15
(alebo čokoľvek iné, čo chcete)

Zadajte päť núl (0) pre ukončenie.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]

SLiRP Pripravený ...
fish: “/usr/bin/slirp” ukončený signálom SIGSEGV (Chyba adresového okraja)

Och, bože. Nainštalujme debuggger pre Slirp a zistíme, či dokážeme pochopiť, čo sa tu deje:

sudo apt-get install gdb slirp-dbgsym
gdb /usr/bin/slirp
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/slirp...Reading symbols from /usr/lib/debug/.build-id/c6/2e75b69581a1ad85f72ac32c0d7af913d4861f.debug...done.
done.
(gdb) run
Starting program: /usr/bin/slirp
Slirp v1.0.17 (BETA)

Copyright (c) 1995,1996 Danny Gasparovski and others.
All rights reserved.
This program is copyrighted, free software.
Please read the file COPYRIGHT that came with the Slirp
package for the terms and conditions of the copyright.

IP address of Slirp host: 127.0.0.1
IP address of your DNS(s): 1.1.1.1, 10.77.0.7
Your address is 10.0.2.15
(or anything else you want)

Type five zeroes (0) to exit.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]

SLiRP Ready ...

Program received signal SIGSEGV, Segmentation fault.
                                                    ip_slowtimo () at ip_input.c:457
457     ip_input.c: No such file or directory.

Chyba sa objavuje v tento riadok. Pozrime sa na stacktrace, možno nám to niečo pomôže:

(gdb) bt full
#0  ip_slowtimo () at ip_input.c:457
        fp = 0x55784a40
#1  0x000055555556a57c in main_loop () at ./main.c:980
        so = 
        so_next = 
        timeout = {tv_sec = 0, tv_usec = 0}
        ret = 0
        nfds = 0
        ttyp = 
        ttyp2 = 
        best_time = 
        tmp_time = 
#2  0x000055555555b116 in main (argc=1, argv=0x7fffffffdc58) at ./main.c:95
No locals.

Tu vidíme, že chyba nastáva počas spúšťania hlavnej slučky, keď sa slirp pokúša skontrolovať časové limity. V tom momente som sa mala vzdať pokusov o ladenie. Ale pozrime sa, či funguje Slirp zostavený zo zdrojov. Znovu som stiahla archív priamo z webu Sourceforge, pretože ťahať niečo odtiaľ cez príkazový riadok je bolestivé:

cd ~/dl
wget https://xena.greedo.xeserv.us/files/slirp-1.0.16.tar.gz
tar xf slirp-1.0.16.tar.gz
cd slirp-1.0.16/src
./configure --prefix=$HOME/prefix/slirp
make

Tu vidíme upozornenia o neurčených vnorených funkciách, teda o neschopnosti zlinkovať výsledný binárny súbor. Zdá sa, že medzi rokom 2006 a týmto momentom gcc prestal vytvárať symboly používané vo vnorených funkciách dočasne skompilovaných súborov. Skúsme nahradiť kľúčové slovo inline prázdnym komentárom a pozrime sa na výsledok:

vi slirp.h
:6
a

#define inline /**/

:wq
make

Nie, to tiež nefunguje. Stále sa nedá nájsť symboly týchto funkcií.

V tomto bode som to vzdala a začala som hľadať na Github. balíky zostavenia Heroku.Moja teória bola založená na tom, že v nejakom zostavovacom balíku Heroku by sa mali nachádzať potrebné binárne súbory. Nakoniec ma hľadanie priviedlo sem.Stiahla som a rozbalila uml.tar.gz a našla som nasledujúce:

celkom 6136
-rwxr-xr-x 1 cadey cadey   79744 Dec 10  2017 ifconfig*
-rwxr-xr-x 1 cadey cadey     373 Dec 13  2017 init*
-rwxr-xr-x 1 cadey cadey  149688 Dec 10  2017 insmod*
-rwxr-xr-x 1 cadey cadey   66600 Dec 10  2017 route*
-rwxr-xr-x 1 cadey cadey  181056 Jun 26  2015 slirp*
-rwxr-xr-x 1 cadey cadey 5786592 Dec 15  2017 uml*
-rwxr-xr-x 1 cadey cadey     211 Dec 13  2017 uml_run*

Toto je binárny súbor slirp! A funguje?

./slirp
Slirp v1.0.17 (BETA) FULL_BOLT

Copyright (c) 1995,1996 Danny Gasparovski a ďalší.
Všetky práva vyhradené.
Tento program je chránený autorskými právami, voľný softvér.
Prečítajte si súbor COPYRIGHT, ktorý prišiel s balíkom Slirp
pre podmienky a podmienky autorského práva.

IP adresa hostiteľa Slirp: 127.0.0.1
IP adresa vášho DNS(s): 1.1.1.1, 10.77.0.7
Vaša adresa je 10.0.2.15
(ale aj niečo iné, čo chcete)

Zadajte päť núl (0) na ukončenie.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500]

SLiRP pripravené ...

Nepadá — takže by to malo fungovať! Poďme pridať tento binárny súbor do ~/bin/slirp:

cp slirp ~/bin/slirp

Pre prípad, že by autor balíka odstránil, som vytvorila zrkadlo..

Nastavenie siete

Teraz nastavme sieť na našom hosťovskom jadre. Aktualizujeme parametre spustenia.:

linux 
  root=/dev/root 
  rootfstype=hostfs 
  rootflags=$HOME/prefix/uml-demo 
  rw 
  mem=64M 
  eth0=slirp,,$HOME/bin/slirp 
  init=/bin/sh

Teraz zapneme sieť:

mount -t proc proc proc/
mount -t sysfs sys sys/

ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
route add default gw 10.0.2.2

Prvé dve príkazy na nastavenie /proc a /sys sú potrebné pre fungovanie ifconfig, ktoré nastavuje sieťové rozhranie na komunikáciu so Slirp. Príkaz route nastavuje smerovaciu tabuľku jadra na vynútenie zasielania celej prevádzky cez tunel Slirp. Poďme to skontrolovať pomocou DNS dotazu:

nslookup google.com 8.8.8.8
Server:    8.8.8.8
Adresa 1: 8.8.8.8 dns.google

Názov:      google.com
Adresa 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Adresa 2: 2607:f8b0:4006:81b::200e lga25s63-in-x0e.1e100.net

Funguje!

Poznámka: Zjavne bol pôvodný príspevok písaný na desktopovom počítači s káblovou sieťovou kartou, alebo nejakou inou konfiguráciou, ktorá nevyžaduje ďalšie ovládače. Na laptopu s WiFi 8265 od Intelu sa pri spustení siete vyskytuje chyba.

/ # ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
slirp_tramp failed - errno = 2
ifconfig: ioctl 0x8914 failed: No such file or directory
/ #

Zdá sa, že jadro sa nemôže pripojiť k ovládaču sieťovky. Pokus o skompilovanie firmvéru do jadra situáciu, žiaľ, neurobil. V čase publikácie nebol v tejto konfigurácii na nájdenie riešenia. V jednoduchejších konfiguráciách (napríklad vo Virtualboxe) sa rozhranie zdvihne správne.

Automatizujme presmerovanie pomocou nasledujúceho shell skriptu:

#!/bin/sh
# init.sh

mount -t proc proc proc/
mount -t sysfs sys sys/
ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
route add default gw 10.0.2.2

echo "networking set up"

exec /tini /bin/sh

A označme ho ako spustiteľný:

chmod +x init.sh

A potom vykonajme zmeny v príkazovom riadku jadra:

linux 
  root=\/dev\/root 
  rootfstype=hostfs 
  rootflags=$HOME\/prefix\/uml-demo 
  rw 
  mem=64M 
  eth0=slirp,,$HOME\/bin\/slirp 
  init=\/init.sh

A zopakujme:

SLiRP Ready ...
networking set up
\/bin\/sh: can't access tty; job control turned off

nslookup google.com 8.8.8.8
Server:    8.8.8.8
Address 1: 8.8.8.8 dns.google

Name:      google.com
Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Address 2: 2607:f8b0:4004:800::200e iad30s09-in-x0e.1e100.net

Sieť funguje stabilne!

Docker súbor

Aby ste to mali jednoduchšie na overenie, zložila som Dockerfile, ktorý automatizuje väčšinu opísaných krokov a mal by vám poskytnúť funkčnú konfiguráciu. Mám aj hotovú konfiguráciu jadra, ktorá obsahuje všetko, čo je opísané v príspevku. Dôležité je pochopiť, že tu som uviedla iba minimálnu konfiguráciu.

Dúfam, že tento príspevok vám pomohol pochopiť, ako spustiť hosťovské jadro. Výsledkom je akýsi monštrum, ale publikácia bola zamýšľaná ako univerzálny sprievodca na tému zostavovania, inštalácie a nastavenia User Mode v Linuxe pre moderné verzie operačných systémov tejto rodiny. Následné kroky by mali obsahovať inštaláciu služieb a ďalšieho softvéru už vo vnútri hosťovskej systému. Keďže obrazy kontajnerov Docker sú jednoducho rozbalené tar archívy, mali by ste byť schopní extrahovať obraz cez docker export, a potom určiť cestu jeho inštalácie v koreňovom adresári súborového systému hosťovského jadra. A potom spustite shell skript.

Osobitné poďakovanie Rkeene s #lobsters na Freenode. Bez jeho pomoci pri ladení Slirp by som sa nedostala tak ďaleko. Nemám tušenie, ako jeho systém Slackware správne pracuje so slirp, ale moje systémy Ubuntu a Alpine neprijali slirp a navrhnutý mi Rkeene binárny súbor. Ale pre mňa je dosť, že mi niečo funguje.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster