Kako započeti koriŔtenje User Mode-a u Linuxu

Uvod od prevoditelja: S obzirom na masovni ulazak raznih vrsta kontejnera u naÅ” život, može biti prilično zanimljivo i korisno saznati s kakvim su se tehnologijama sve to nekada počelo. Neke od njih mogu biti korisno primjenjive i danas, no ne sjećaju se svi tih načina (ili ne znaju, ako nisu iskusili vrijeme njihovog brzog razvoja). Jedna od takvih tehnologija je User Mode Linux. Autorica originala se ozbiljno potrudila, istražujući Å”to od starih rjeÅ”enja joÅ” uvijek radi, a Å”to ne, i okupila neÅ”to poput korak-po-korak upute o tome kako sami sebi postaviti domaći UML u 2k19. I da, pozvali smo autora originalne objave na Habr. Cadey, pa ako imate pitanja — slobodno ih postavite na engleskom u komentarima.

Kako započeti koriŔtenje User Mode-a u Linuxu

User Mode u Linuxu — to je zapravo port jezgre Linuxa na samu sebe. Ovaj način omogućuje pokretanje potpune jezgre Linuxa kao korisničkog procesa i obično ga koriste programeri za testiranje drajvera. No, ovaj način je također koristan kao alat za opću izolaciju, čiji je princip sličan radu virtualnih maÅ”ina. Ovaj način pruža veću izolaciju od Dockera, ali manju od pune virtualne maÅ”ine poput KVM-a ili VirtualBoxa.

U cjelini, User Mode može izgledati kao čudan i kompliciran alat za koriÅ”tenje, ali ipak ima svoja područja primjene. Naime, to je potpuna Linux jezgra koja radi pod neprivilegiranim korisnikom. Ova posebnost omogućuje pokretanje potencijalno nesigurnog koda bez ikakvih prijetnji za host-maÅ”inu. A budući da se radi o punoj jezgi, njezini procesi su izolirani od host-maÅ”ine, Å”to znači da procesi koji rade unutar User Mode-a neće biti vidljivi hostu. To se ne razlikuje od uobičajenog Docker kontejnera, u kojem host-maÅ”ina uvijek vidi procese unutar skladiÅ”ta. Pogledajte ovaj dio pstree s jednog od mojih servera:

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}]

I usporedite to s pstree jezgre Linux u korisničkom modu:

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

Pri radu s Docker kontejnerima mogu vidjeti s hosta nazive procesa koji su pokrenuti u gostujućem sustavu. To s Linux korisničkim načinom nije moguće. Å to to znači? To znači da alati za nadgledanje koji rade putem Linuxove sustavne audicije ne vide procese koji se izvrÅ”avaju u gostujućem sustavu. No, u nekim situacijama ova značajka može postati izvor problema.

U osnovi, cijeli post ispod je skup istraživanja i grubih pokuÅ”aja da se postigne željeni rezultat. Za to sam morala koristiti razne starinske alate, čitati izvorne kodove jezgre, intenzivno debagirati kod napisan u vrijeme kada sam joÅ” bila u osnovnoj Å”koli, a također kopati po Heroku buildovima uz pomoć posebnog binarnog alata u potrazi za potrebnim alatima. Sav ovaj rad doveo je do toga da su me momci u mom IRC-u počeli nazivati čarobnicom. Nadam se da će ovaj post poslužiti nekome kao pouzdana dokumentacija da napravi isto to, ali uz novije jezgre i verzije OS-a.

PodeŔavanje

Postavljanje Linux korisničkog moda provodi se u nekoliko faza:

  • instalacija ovisnosti na hostu;
  • preuzimanje jezgre Linux;
  • konfiguracija build-a jezgre;
  • izrada jezgre;
  • instalacija binarne datoteke;
  • konfiguracija gostujućeg datotečnog sustava;
  • odabir parametara za pokretanje jezgre;
  • konfiguracija gostujuće mreže;
  • pokretanje gostujuće jezgre.

Pretpostavljam da ako se odlučite sami provesti sve ovo, vjerojatno ćete raditi sve navedeno na nekom Ubuntu ili Debian-sličnom sustavu. PokuÅ”ala sam implementirati sve navedeno na svom omiljenom distribuciji — Alpine, ali niÅ”ta nije uspjelo, očito zbog toga Å”to Linux kernel ima čvrstu vezu prema glibc-isms za vozače u korisničkom modu. Planiram o tome obavijestiti upstream nakon Å”to konačno razjasnim problem.

Instalacija ovisnosti na hostu

Ubuntu zahtijeva, najmanje, sljedeće pakete za izgradnju Linux kernela (pod uvjetom čiste instalacije):

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

Možete ih instalirati pomoću sljedeće komande (s root pravima ili uz pomoć sudo):

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

Imajte na umu da pokretanje programa za konfiguraciju izbornika za Linux kernel zahtijeva instalaciju libncurses-dev. Molimo osigurajte da je instaliran pomoću sljedeće komande (s root pravima ili uz pomoć sudo):

apt-get -y install libncurses-dev

Preuzimanje kernela

Odredite mjesto za preuzimanje i kasniju izgradnju kernela. Za ovu operaciju trebat ćete osloboditi oko 1,3 GB prostora na tvrdom disku, pa se pobrinite da ga imate.

Nakon toga, pređite na kernel.org i dobijte URL za preuzimanje najnovije stabilne verzije kernela. U trenutku pisanja ovog posta to je: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Preuzmite ovu datoteku koristeći 'wget':

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

I raspakirajte je pomoću 'tar':

tar xJf linux-5.1.16.tar.xz

Sada uđite u direktorij koji je stvoren raspakiranjem tarball-a:

cd linux-5.1.16

Konfiguracija izgradnje kernela

Sustav za izgradnju kernela je skup Make datoteka s brojne korisničke alate i skripte za automatizaciju procesa. Za početak otvorite interaktivni program za konfiguraciju:

make ARCH=um menuconfig

Djelomično će provesti izgradnju i prikazati vam dijalog. Kada se u donjem dijelu prozora pojavi '[Select]', moći ćete se baviti konfiguracijom pomoću tipki razmaknica ili Enter. Navigacija po prozoru, kao i obično, tipkama 'gore' i 'dolje', a odabir stavki 'lijevo' ili 'desno'.

Pokazivač oblika —> označava da ste u podizborniku, ulaz u koji se obavlja pritiskom na Enter. Izlaz iz njega, očito, preko '[Exit]'Uključite sljedeće parametre u '[Select]' i osigurajte da pored njih ima znak '[*]':ā€˜.

[Exit][Select]'

Opcije specifične za UML:
  - Host datotečni sustav
PodrÅ”ka za umrežavanje (omogućite ovo da biste prikazali podizbornik):
  - Opcije umrežavanja:
    - TCP/IP umrežavanje
UML mrežni uređaji:
  - Virtualni mrežni uređaj
  - SLiRP transport

Iz ovog prozora možete izaći tako da sequentialno odaberete ā€˜Uključite sljedeće parametre u '[Select]' i osigurajte da pored njih ima znak '[*]':ā€˜. Samo se pobrinite da na kraju od vas bude zatraženo da spremite konfiguraciju i odaberete ā€˜[Da]ā€˜.

Preporučujem da se poigrate s postavkama izrade jezgre nakon Å”to pročitate ovu objavu. Ovim eksperimentima možete steći puno znanja o razumijevanju rada niskorazinskih mehanika jezgre i utjecaju različitih zastavica na njezinu izradu.

Izrada jezgre

Linux jezgra je velika aplikacija koja se bavi mnogim stvarima. Čak i s ovom minimalnom konfiguracijom na staroj opremi, izrada može potrajati značajno vrijeme. Stoga, izradite jezgru pomoću sljedeće naredbe:

make ARCH=um -j$(nproc)

ZaÅ”to? Ova naredba će reći naÅ”em izraditelju da koristi sve dostupne jezgre i niti procesora tijekom izrade. Naredba $(nproc) na kraju Build zamjenjuje izlaz naredbe nproc, koja je dio coreutils u standardnoj verziji Ubuntu-a.

Nakon nekog vremena, naÅ”a jezgra će biti izgrađena u izvrÅ”nu datoteku ./linux.

Instalacija binarnog datoteke

Budući da User Mode u Linuxu stvara običnu binarnu datoteku, možete je instalirati kao i bilo koju drugu uslugu. Evo kako sam to učinila:

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

Također, trebate osigurati da ~/bin je u vaÅ”em $PATH:

export PATH=$PATH:$HOME/bin

Konfiguracija gostujućeg datotečnog sustava

Stvorite direktorij za gostujući datotečni sustav:

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

Otvorite alpinelinux.org i u odjeljku za preuzimanje pronađite važeću vezu za preuzimanje MINI ROOT FILESYSTEM. U trenutku pisanja ovog članka, to je bilo:

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

Preuzmite ovaj tarball pomoću wget-a:

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

Sada pređite u direktorij gostujućeg datotečnog sustava i raspakirajte arhivu:

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

Opisane radnje će stvoriti mali uzorak datotečnog sustava. Zbog karakteristika sustava, instalacija paketa putem apk upravitelja u Alpine bit će vrlo teÅ”ka. No, ova datotečna struktura bit će dovoljna za ocjenjivanje opće ideje.

Također ćemo trebati alat tini za sprječavanje potroÅ”nje memorije zombie procesima naÅ”eg gostujućeg jezgra.

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

Stvaranje komandne linije jezgre

U Kernel Linux, kao i u većini drugih programa, postoje naredbeni argumenti koje možete pregledati koristeći ključ --help.

Sam —help

linux --help
User Mode Linux v5.1.16
        dostupan na http://user-mode-linux.sourceforge.net/

--showconfig
    Ispisuje konfiguracijsku datoteku iz koje je ova UML bina generirana.

iomem=,
    Konfigurirajte  kao IO memorijsku regiju nazvanu .

mem=
    Ovo kontrolira koliko "fizičke" memorije kernel dodjeljuje
    za sustav. Veličina se specificira kao broj praćen
    jednim od 'k', 'K', 'm', 'M', koji imaju očita značenja.
    Ovo nije povezano s količinom memorije na hostu. Može
    biti viÅ”e, a viÅ”ak, ako se ikada koristi, bit će zamijenjen.
        Primjer: mem=64M

--help
    Ispisuje ovu poruku.

debug
    ova zastava nije potrebna za pokretanje gdb-a na UML-u u skas modu

root=
    Ovo zapravo koristi generički kernel na točno isti
    način kao i u bilo kojem drugom kernelu. Ako konfigurirate nekoliko blok
    uređaja i želite pokrenuti s nečega osim ubd0, koristili
    biste neŔto poput:
        root=/dev/ubd5

--version
    Ispisuje broj verzije kernela.

umid=
    Ovo se koristi za dodjeljivanje jedinstvenog identiteta ovoj UML maŔini i
    koristi se za imenovanje pid datoteke i sučelja za upravljanje.

con[0-9]*=
    Priključite konzolu ili serijsku liniju na host kanal.  Pogledajte
    http://user-mode-linux.sourceforge.net/old/input.html za kompletnu
    opisivanje ove opcije.

eth[0-9]+=,
    Konfigurirajte mrežni uređaj.
    
aio=2.4
    Ovo se koristi za prisiljavanje UML-a da koristi AIO u stilu 2.4 čak i kada je 2.6 AIO
    dostupan.  2.4 AIO je jedan nit koji obrađuje jedan zahtjev u
    isto vrijeme, sinkrono.  2.6 AIO je nit koja koristi 2.6 AIO
    sučelje za upravljanje proizvoljnim brojem čekajućih zahtjeva.  2.6 AIO
    nije dostupan u tt modu, na 2.4 domaćinima ili kada je UML izgrađen s
    /usr/include/linux/aio_abi.h nije dostupan.  Mnoge distribucije ne
    uključuju aio_abi.h, tako da ćete trebati kopirati iz stabla kernela u
    svoj /usr/include/linux kako biste izgradili AIO sposobnog UML

nosysemu
    Isključuje emulaciju sistemskih poziva za ptrace (SYSEMU).
    SYSEMU je izvedeni ispravak performansi koji je uveo Laurent Vivier. Mijenja
    ponaÅ”anje ptrace() i pomaže smanjiti stope promjena konteksta domaćina.
    Da bi to radilo, trebati ćete i ispravak kernela za vaÅ” host.
    Pogledajte http://perso.wanadoo.fr/laurent.vivier/UML/ za viŔe
    informacija.

uml_dir=
    Lokacija za postavljanje pid i umid datoteka.

quiet
    Isključuje informacijske poruke tijekom pokretanja.

hostfs=,,...
    Ovo se koristi za postavljanje hostfs parametara.  Argument korijenske
    direktorije koristi se za ograničavanje svih hostfs montaža unutar
    specificiranog direktorijskog stabla na hostu.  Ako to nije
    specificirano, tada korisnik unutar UML-a može montirati bilo Ŕto na
    hostu Å”to je dostupno korisniku koji ga pokreće.
    Jedina zastava koja se trenutno podržava je 'append', koja specificira
    da će sve datoteke otvorene od strane hostfs biti otvorene u režimu dodavanja.

Ova traka objaŔnjava osnovne opcije pokretanja. Pokrenimo kernel s minimalnim potrebnim skupom opcija:

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

Gornje linije govore naÅ”em kernelu sljedeće:

  • Pretpostavimo da je korijenski datotečni sustav pseudo-uređaj /dev/root.
  • Odaberi hostfs kao vozač korijenskog datotečnog sustava.
  • Montirajte gostujući datotečni sustav koji smo stvorili u root uređaju.
  • I da, u načinu rada samo za čitanje i pisanje.
  • Koristite samo 64 megabajta radne memorije (možete koristiti mnogo manje, ovisno o tome Å”to planirate raditi, ali 64 MB se čini optimalnom količinom).
  • Jezgra automatski pokreće /bin/sh kao init-proces.

Pokrenite ovu naredbu, i trebali biste dobiti neÅ”to poput sljedećeg:

JoÅ” jedan list

Ograničenja za core dump:
        soft - 0
        hard - NEMA
Provjera može li ptrace promijeniti brojeve sistemskih poziva...UREDNO
Provjera ekipe za emulaciju sistemskih poziva za ptrace...UREDNO
Provjera napredne ekipe za emulaciju sistemskih poziva za ptrace...UREDNO
Provjera varijabli okruženja za tempdir...nijedna nije pronađena
Provjera je li \/dev\/shm na tmpfs...UREDNO
Provjera PROT_EXEC mmap u \/dev\/shm...UREDNO
Dodavanje 32137216 bajtova fizičkoj memoriji da bi se nadoknadila praznina exec-shield
Linux verzija 5.1.16 (cadey@kahless) (gcc verzija 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Ned Jul 7 18:57:19 UTC 2019
Izgrađene su 1 zonalist, mobilnost grupiranja. Ukupno stranica: 23898
Kernel naredbeni redak: root=\/dev\/root rootflags=\/home\/cadey\/dl\/uml\/alpine rootfstype=hostfs rw mem=64M init=\/bin\/sh
Dentry cache hash tablica unosa: 16384 (redoslijed: 5, 131072 bajtova)
Inode-cache hash tablica unosa: 8192 (redoslijed: 4, 65536 bajtova)
Memorija: 59584K\/96920K dostupna (2692K kernel koda, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K rezervirano, 0K cma-rezervirano)
SLUB: HWalign=64, Redoslijed=0-3, MinObjects=0, CPU=1, Čvorovi=1
NR_IRQS: 15
izvor vremena: timer: maska: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Kalibriranje petlje kaŔnjenja... 7479.29 BogoMIPS (lpj=37396480)
pid_max: zadano: 32768 minimalno: 301
Mount-cache hash tablica unosa: 512 (redoslijed: 0, 4096 bajtova)
Mountpoint-cache hash tablica unosa: 512 (redoslijed: 0, 4096 bajtova)
Provjera podržava li host ptys isporuku SIGIO...Da
Provjera podržava li host ptys SIGIO pri zatvaranju...Ne, omogućavanje rjeÅ”enja
devtmpfs: inicijalizirano
random: get_random_bytes pozvano iz setup_net+0x48\/0x1e0 s crng_init=0
Koristeći 2.6 host AIO
izvor vremena: jiffies: maska: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash tablica unosa: 256 (redoslijed: 0, 6144 bajtova)
NET: Registrirana obitelj protokola 16
izvor vremena: Prebačeno na izvor vremena timer
NET: Registrirana obitelj protokola 2
tcp_listen_portaddr_hash hash tablica unosa: 256 (redoslijed: 0, 4096 bajtova)
TCP uspostavljena hash tablica unosa: 1024 (redoslijed: 1, 8192 bajtova)
TCP bind hash tablica unosa: 1024 (redoslijed: 1, 8192 bajtova)
TCP: Hash tablice konfigurirane (uspostavljeno 1024 bind 1024)
UDP hash tablica unosa: 256 (redoslijed: 1, 8192 bajtova)
UDP-Lite hash tablica unosa: 256 (redoslijed: 1, 8192 bajtova)
NET: Registrirana obitelj protokola 1
konzola [stderr0] onemogućena
mconsole (verzija 2) inicijalizirana na \/home\/cadey\/.uml\/tEwIjm\/mconsole
Provjera podrŔke host MADV_REMOVE...UREDNO
workingset: timestamp_bits=62 max_order=14 bucket_order=0
SCSI generički (bsg) vozač verzije 0.4 učitan (glavni 254)
io planer noop registriran (zadano)
io planer bfq registriran
loop: modul učitan
NET: Registrirana obitelj protokola 17
Inicijaliziran stdio konzola vozač
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 1: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 2: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 3: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 4: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 5: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 6: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 7: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 8: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 9: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 10: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 11: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 12: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 13: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 14: Konfiguracija nije uspjela
Koristeći tip kanala koji je konfiguriran izvan UML
setup_one_line neuspjeÅ”an za uređaj 15: Konfiguracija nije uspjela
Konzola inicijalizirana na \/dev\/tty0
konzola [tty0] omogućena
konzola [mc-1] omogućena
Neuspjeh pri inicijalizaciji ubd uređaja 0: Nije moguće odrediti veličinu datoteke uređaja
VFS: Montiran korijen (hostfs datotečni sustav) na uređaju 0:11.
devtmpfs: montirano
Ova arhitektura nema zaŔtitu memorije jezgre.
Pokrenite \/bin\/sh kao init proces
\/bin\/sh: ne mogu pristupiti tty; kontrola posla isključena
random: brzi init zavrŔen
\ # 

Manipulacije iznad će nam dati gostujući sustav s minimalnim postavkama, bez takvih stvari kao Å”to su /proc ili dodijeljeni hostname. Na primjer, pokuÅ”ajte izvrÅ”iti sljedeće naredbe:

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

Da biste izaÅ”li iz gostujućeg sustava, unesite exit ili pritisnite control-d. Ovo će ubiti ljusku s kasnijim kernel panic:

/ # exit
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
fish: ā€œ./linux root=/dev/root rootflagā€¦ā€ terminated by signal SIGABRT (Abort)

Dobili smo ovaj kernel panic zbog toga Å”to Linux kernel smatra da je proces inicijalizacije uvijek pokrenut. Bez njega sustav viÅ”e ne može funkcionirati i gasi se. No poÅ”to je to proces korisničkog moda, rezultat koji se dobije vraća se sam u SIGABRT, Å”to dovodi do izlaska.

Postavljanje gostujuće mreže

A ovdje nam stvari počinju ići naopako. Mreža u User Mode Linuxu - to je mjesto gdje se cijela koncepcija ograničenog ā€žkorisničkog modaā€ počinje raspadati. Naime, obično je na sustavnoj razini mreža ograničena privilegiranim načinima izvrÅ”avanja iz očitih razloga.

Napomena: viŔe o različitim opcijama rada s mrežom u UML-u možete pročitati ovdje.

Putovanje u slirp

No, postoji drevni i praktički nezaÅ”tićen alat pod imenom Slirp, pomoću kojeg User Mode Linux može komunicirati s mrežom. Funkcionira otprilike kao TCP/IP stog na razini korisnika i ne zahtijeva nikakve sustavne dozvole za pokretanje. Ovaj alat je objavljen 1995. godine, a posljednje ažuriranje datira iz 2006. godine. Slirp je veoma star. Tijekom vremena bez podrÅ”ke i ažuriranja, kompajleri su otiÅ”li tako daleko da se sada ovaj alat može opisati samo kao ā€žcode rotā€.

Dakle, idemo instalirati Slirp iz Ubuntu repozitorija i pokuŔati ga pokrenuti:

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

Copyright (c) 1995,1996 Danny Gasparovski i drugi.
Sva prava zadržana.
Ovaj program je autorski zaÅ”tićen, slobodni softver.
Molimo pročitajte datoteku COPYRIGHT koja je doŔla s Slirp
paketom za uvjete i odredbe autorskog prava.

IP adresa Slirp domaćina: 127.0.0.1
IP adresa vaŔeg DNS-a: 1.1.1.1, 10.77.0.7
VaŔa adresa je 10.0.2.15
(ili bilo Ŕto drugo Ŕto želite)

Unesite pet nula (0) za izlaz.

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

SLiRP Spreman ...
fish: ā€œ/usr/bin/slirpā€ prekinut signalom SIGSEGV (GreÅ”ka granice adrese)

Oh, bože. Idemo instalirati debager za Slirp i vidjeti možemo li razumjeti Å”to se tu događa:

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.

GreŔka se javlja u ovoj liniji. Pogledajmo stacktrace, možda nam tamo neŔto pomogne:

(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.

Ovde vidimo da se greŔka javlja prilikom pokretanja glavne petlje, kada slirp pokuŔava da proveri vremenske limite. U tom trenutku sam trebala da odustanem od pokuŔaja debagovanja. No, hajde da vidimo radi li Slirp koji je napravljen iz izvora. Ponovo sam preuzela arhivu direktno sa sajta Sourceforge, jer je teže neŔto preuzeti putem komandne linije:

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

Ovde vidimo upozorenja o neodređenim ugrađenim funkcijama, Å”to znači da nije moguće povezati konačni binarni fajl. Čini se da je između 2006. godine i ovog trenutka gcc prestao da stvara simbole koji se koriste u ugrađenim funkcijama međufazno kompajliranih fajlova. Hajde da pokuÅ”amo zameniti ključnu reč inline sa praznim komentarom i pogledamo rezultat:

vi slirp.h
:6
a

#define inline /**/

:wq
make

Ne. To također ne radi. JoÅ” uvijek ne mogu pronaći simbole ovih funkcija.

U ovoj fazi sam se predala i počela tražiti na Githubu pakete izgradnje Heroku. Moja teorija temeljila se na pretpostavci da će neki paket izgradnje Heroku sadržavati potrebne binarne datoteke. Na kraju su me pretrage dovele ovdje. Preuzela sam i raspakirala uml.tar.gz i pronaÅ”la sljedeće:

total 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*

To je binarna datoteka slirp! A da li radi?

.\/slirp
Slirp v1.0.17 (BETA) FULL_BOLT

Copyright (c) 1995,1996 Danny Gasparovski i drugi.
Sva prava zadržana.
Ovaj program je zaÅ”tićen autorskim pravima, slobodni softver.
Molimo vas da pročitate datoteku COPYRIGHT koja je doŔla s Slirp
paketom za uvjete i odredbe autorskog prava.

IP adresa Slirp hosta: 127.0.0.1
IP adresa vaŔih DNS-ova: 1.1.1.1, 10.77.0.7
VaŔa adresa je 10.0.2.15
(ili bilo Ŕto drugo Ŕto želite)

UpiŔite pet nula (0) za izlaz.

[automatsko otkrivanje SLIP/CSLIP, MTU 1500, MRU 1500]

SLiRP Spremno ...

Ne ruÅ”i se — pa bi to trebalo raditi! Idemo umetnuti ovu binarnu datoteku u ~/bin/slirp:

cp slirp ~/bin/slirp

U slučaju da kreator paketa ukloni, ja napravila sam ogledalo.

PodeŔavanje mreže

Sada idemo konfigurirati mrežu na naÅ”em gostujućem jezgru. Ažurirajmo pokretne parametre:

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

Sada idemo omogućiti mrežu:

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

Prve dvije komande konfiguracije /proc i /sys neophodne su za rad ifconfig, koja postavlja mrežni interfejs za komunikaciju sa Slirp. Komanda route postavlja tablicu rutiranja jezgre kako bi se sav promet usmjerio kroz Slirp tunel. Provjerimo to s DNS upitom:

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:4006:81b::200e lga25s63-in-x0e.1e100.net

Radi!

Napomena: Izgleda da je izvorni post napisan na desktop računalu s žičanom mrežnom karticom, ili nekakvom drugom konfiguracijom koja ne zahtijeva dodatne drajvere. Na prijenosnom računalu s WiFi 8265 od Intela, kada se podiže mreža, pojavljuje se greŔka

/ # 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
/ #

Izgleda da jezgra ne može uspostaviti vezu s drajverom mrežnog sučelja. PokuÅ”aj uključivanja firmvera u jezgru nažalost nije ispravio situaciju. U trenutku objave, na ovoj konfiguraciji rjeÅ”enje se joÅ” nije moglo pronaći. Na jednostavnijim konfiguracijama (npr. u Virtualboxu) interfejs se ispravno podiže.

Automatizirajmo preusmjeravanje pomoću sljedećeg shell skripta:

#!/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

I markirajmo ga kao izvrŔni:

chmod +x init.sh

A zatim ćemo unijeti izmjene u liniju naredbe kernela:

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

I ponovit ćemo:

SLiRP Spreman ...
mrežno povezivanje postavljeno
\/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

Mreža radi stabilno!

Docker datoteka

Da bi vam olakÅ”ala sve ovo provjeriti, sastavila sam Dockerfile, koja automatizira većinu opisanih koraka i trebala bi vam osigurati radnu konfiguraciju. Također imam gotovu konfiguraciju kernela, koja sadrži sve Å”to je navedeno u postu. No, važno je razumjeti da sam ovdje izložila samo minimalnu konfiguraciju.

Nadam se da vam je ova objava pomogla da razumijete kako pokrenuti gostujući kernel. IzaÅ”ao je neki čudoviÅ”te, ali objava je zamiÅ”ljena kao sveobuhvatan vodič o temi izrade, instalacije i konfiguracije User Mode u Linuxu pod modernim verzijama operativnih sustava ove obitelji. Daljnji koraci trebali bi uključivati instalaciju servisa i ostalog softvera unutar gostujućeg sustava. Kako su Docker slike samo raspakirane tar arhive, trebali biste biti u mogućnosti izvući sliku putem docker export, a zatim odrediti put za njen smjeÅ”taj u korijenu datotečnog sustava gostujućeg kernela. Pa, zatim izvrÅ”ite shell skript.

Posebno hvala Rkeeneu s #lobsters na Freenode. Bez njegove pomoći u debuggiranju Slirpa ne bih dogurala tako daleko. Nemam pojma kako njegova Slackware sistem ispravno radi sa slirp, ali moji sustavi Ubuntu i Alpine nisu prihvatili slirp i Rkeeneov mi ponuđeni binarni datotek. No, ja sam zadovoljna i s tim Å”to mi neÅ”to uopće radi.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaÅ”titom, VPS VDS servere šŸ”„ Kupite pouzdan hosting za web stranice s DDoS zaÅ”titom, VPS VDS servere | ProHoster