Kuidas alustada User Mode'i kasutamist Linuxis

Tõlkija sissejuhatus: Erinevate konteinerite laialdase kasutuselevõtu taustal võib olla üsna huvitav ja kasulik uurida, millistest tehnoloogiatest see kõik kunagi algas. Mõndasid neist saab kasulikult rakendada ka tänapäeval, aga kõik ei mäleta (või ei tea, kui nad ei olnud tunnistajaks nende kiirele arengule). Üks selline tehnoloogia on User Mode Linux. Originaali autor uuris süvitsi, et mõista, millised vanad arendused veel töötavad ja millised mitte, ning koondas kokku midagi, mis sarnaneb samm-sammult juhendiga, kuidas ise endale koduse UML-i 2k19 käivitada. Ja jah, me kutsusime Habri originaalpostituse autori. Cadey, nii et kui teil on küsimusi, küsige inglise keeles kommentaarides.

Kuidas alustada User Mode'i kasutamist Linuxis

User Mode Linux — see, port of the Linux kernel to itself. This mode allows you to run a full Linux kernel as a user process and is typically used by developers for testing drivers. However, this mode is also helpful as a tool for general isolation, similar to how virtual machines work. This mode provides greater isolation than Docker, but less than a full virtual machine like KVM or Virtual Box.

Overall, User Mode might seem like a strange and complex tool to use, but it still has its applications. After all, it is a fully-fledged Linux kernel running as an unprivileged user. This feature allows you to run potentially untrusted code without any threats to the host machine. And since it's a full kernel, its processes are isolated from the host machine, meaning the processes running inside User Mode will not be visible to the host. This is not like a typical Docker container, where the host machine can always see the processes inside the storage. Look at this piece of pstree from one of my servers:

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

Ja võrrelge seda Linuxi kernel pstree'ga kasutajarežiimis:

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

Docker-konteinerite käitamisel saan hostilt näha protsesside nimesid, mis on käivitatud külgsüsteemis. Linuxi kasutajarežiimis ei ole see võimalik. Mis see tähendab? See tähendab, et jälgimistööristad, mis töötavad Linuxi auditialase alamsüsteemi kaudu, ei näe küljel käivitatavaid protsesse. Kuid mõnes olukorras võib see omadus olla ka kahesuunaline relv.

Kogu allolev postitus on uuringute ja katsete kogum, et saavutada soovitud tulemus. Selleks pidin kasutama erinevaid vanu tööriistu, lugema tuuma lähtekoodi, tegema intensiivset koodi silumist, mis oli kirjutatud ajal, mil ma veel algkoolis käisin, ja kaevama Heroku kogumites erilise binaariga, et leida vajalikud tööriistad. Kõik see töö tõi selleni, et mu IRC sõbrad hakkasid mind nimetama nõiaks (magic). Lo امیدوارж, et see postitus toob kedagi usaldusväärse dokumentatsioonina, et teha kõike sama, kuid uute tuumade ja OS versioonidega.

Seadistamine

Linux User Mode seadistamine toimub mitmes etapis:

  • sõltuvuste installimine hostis;
  • Linuxi tuuma allalaadimine;
  • tuuma kogumise seadistamine;
  • tuuma kokku kogumine;
  • binaari installimine;
  • külaliste failisüsteemi seadistamine;
  • tuuma käivitusparameetrite valimine;
  • külaliste võrgu seadistamine;
  • külaliste tuuma käivitamine.

Arvan, et kui otsustate kõik ise ajada, siis teete tõenäoliselt kõike Ubuntu või Debian-taolises süsteemis. Püüdsin rakendada kõike eespool mainitut oma lemmikjaotuses — Alpine'is, kuid see ei õnnestunud, ilmselt seetõttu, et Linuxi kernalil on tugev sidumine glibc-ims jaoks User Mode'i draiverite jaoks. Plaanin sellest upstream'is teatada, kui olen probleemiga täielikult kursis.

Sõltuvuste installimine hostis

Ubuntu vajab, vähemalt, järgmised paketid Linuxi kerneli ehitamiseks (eeldusel, et tegemist on puhta paigaldamisega):

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

Saate need installida järgmise käsu abil (root'i õigustes või sudo abil):

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

Pange tähele, et Linuxi kerneli menüü seadistamise programmi käivitamine nõuab libncurses-dev. Palun veenduge, et see on installitud järgmise käsu abil (root'i õigustes või sudo abil):

apt-get -y install libncurses-dev

Kerneli allalaadimine

Määrake koht tuvastamiseks ja järgmise sammu jaoks tuumade üleslaadimiseks. Selle protsessi jaoks on teil vaja umbes 1,3 Gt kettaruumi, seega veenduge, et teil on see olemas.

Seejärel minge aadressile kernel.org ja hankige viide viimasest stabiilsest tuumaversioonist. Praeguse seisuga on see: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Laadige see fail alla, kasutades 'wget':

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

Ja ekstraktige see kasutades 'tar':

tar xJf linux-5.1.16.tar.xz

Nüüd siseneme kausta, mis loodi tarball'i lahti pakkimisel:

cd linux-5.1.16

Tuumade ehitamise seadistamine

Tuumade ehitamise süsteem on komplekt Make-failidest koos mugavate kasutajate tööriistadest ja skriptidest, mis automatiseerivad protsessi. Alustamiseks avage interaktiivne seade programme:

make ARCH=um menuconfig

See viib teid osaliselt kaudu ja avab dialoogikasti. Kui akna allosas kuvatakse '[Select]', saate seadistamist teha tühikuklahvi või Enteriga. Akna navigeerimine toimub nagu tavaliselt, kasutades nooleklahve "üles" ja "alla", ning elementide valimine on "vasakule" või "paremale".

Viidatud tüüp —> tähendab, et olete menüü alamosas, kuhu pääseb siseneda sisestusklahviga. Väljumine sealt toimub eitamise kaudu.[Exit]‘.

Aktiveerige järgmised parameetrid ‘[Select]‘ ja veenduge, et nende kõrval on sümbol ‘[*]’:

UML-spetsiifilised valikud:
  - Host-failisüsteem
Võrgu tugi (lülitage see sisse, et menüü alamosa ilmuks):
  - Võrgu valikud:
    - TCP/IP võrgundus
UML võrgu seadmed:
  - Virtuaalne võrgu seade
  - SLiRP transport

Kõik, sellest aknast on võimalik välja minna, valides järjest ‘[Exit]‘. Lihtsalt veenduge, et keegi lõpuks küsib teilt konfiguratsiooni salvestamist ja valite ‘[Jah]‘.

Soovitan teil pärast selle postituse lugemist proovida mängida kerneli ehitamise parameetridega. Nende katsetega saate palju õppida, mõistes madalama taseme kernelimehhanisme ja erinevate lipu mõju selle ehitusele.

Kerneli ehitamine

Linuxi kerneli on suur programm, mis tegeleb paljude asjadega. Isegi minimaalsete seadistuste korral vanal riistvaral võib selle ehitamine võtta piisavalt kaua aega. Seetõttu ehitage kerneli järgnevate käskude abil:

make ARCH=um -j$(nproc)

Miks? See käsk ütleb meie koostajale kasutada kõiki saadaolevaid protsessori südamike ja lõimede kombinatsioone koostamisprotsessi ajal. Käsk $(nproc) Build lõpus kasutatakse käsu nprocväljastust, mis on osa coreutils standardse Ubuntu versiooni koostamisest.

Mõne aja pärast on meie tuum loodud käivitatavaks failiks ./linux.

Binaari installimine

Kuna Linuxi kasutajarežiim loob tavalise binaari, saate seda installida nagu igasugust muud utiliiti. Näitan, kuidas mina seda tegin:

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

Samuti on oluline veenduda, et ~/bin on teie $PATH:

export PATH=$PATH:$HOME/bin

Külalissüsteemi failisüsteemi seadistamine

Looge külalissüsteemi failisüsteemile kaust:

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

Avage alpinelinux.org ja allalaadimise sektsioonis leidke aktuaalne link allalaadimiseks MINI ROOT FILESYSTEM. Publikatsiooni kirjutamise hetkel oli see järgmine:

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

Laadige see tarball alla, kasutades 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

Nüüd minge külalissüsteemi failisüsteemi kausta ja pakkige arhiiv lahti:

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

Kirjeldatud toimingud loovad väikese failisüsteemi malli. Süsteemi töö põhimõtete tõttu on Alpine'i pakettide installimine läbi apk haldurit äärmiselt keeruline. Kuid see failisüsteem on piisav, et mõista üldist ideed.

Samuti on meil vaja tööriista tini mälu tarbimise vältimiseks zombi-protsesside meie külaliskerneli.

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

Kerneli käsurea loomine

Linuxi kernels, nagu enamikes teistes programmides, on käsurea argumendid, millega tutvuda saab, kasutades võtit --help.

ise —help

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

--showconfig
    Prindib konfiguratsioonifaili, mille põhjal see UML binaar loodi.

iomem=,
    Konfigureeri  IO mälu piirkonnana nimega .

mem=
    See kontrollib, kui palju "füüsilist" mälu tuum jagab
    süsteemile. Suuruse määramine toimub numbri ja järgneva
    ühe 'k', 'K', 'm', 'M' abil, millel on ilmne tähendus.
    See ei ole seotud hosti mäluhulgaga. See võib olla rohkem,
    ja ülejääk, kui seda kunagi kasutatakse, vahetatakse lihtsalt välja.
        Näide: mem=64M

--help
    Prindib selle sõnumi.

debug
    seda lippu ei ole vaja UML-i skas režiimis gdb käitamiseks

root=
    Seda kasutatakse tegelikult universaalse tuuma jaoks täpselt samamoodi
    nagu igas teises tuumas. Kui konfigureerite mitmeid blokeeringu
    seadmeid ja soovite käivitada midagi muud kui ubd0, peaksite
    kasutama midagi sellist:
        root=/dev/ubd5

--version
    Prindib tuuma versiooninumbri.

umid=
    Seda kasutatakse, et määrata sellele UML masinale ainulaadne identiteet ja
    seda kasutatakse pid faili ja halduskonsooli side nimeks.

con[0-9]*=
    Kinnita konsool või seeria rida hostikanalile.  Vaata
    http://user-mode-linux.sourceforge.net/old/input.html, et saada täielikku
    kirjeldust selle lüliti kohta.

eth[0-9]+=,
    Konfigureeri võrgu seade.
    
aio=2.4
    Seda kasutatakse UML-i sundimiseks kasutama 2.4-stiilis AIO, isegi siis
    kui 2.6 AIO on saadaval. 2.4 AIO on ühe teema, mis käsitleb
    ühe päringu korraga, süstemaatiliselt.  2.6 AIO on teema, mis kasutab
    2.6 AIO liidest, et käsitleda suvalist arvu ootel olevaid päringuid.
    2.6 AIO ei ole saadaval tt režiimis, 2.4 hostides või kui UML
    on loodud ilma /usr/include/linux/aio_abi.h. Paljud distributsioonid
    ei sisalda aio_abi.h, seega peate selle kopeerima
    tuumapuu alt oma /usr/include/linux tuumaklastri ehitamiseks, mis toetab AIO

nosysemu
    Keerab syscall emulatsiooni patch'i välja ptrace'i (SYSEMU) jaoks.
    SYSEMU on jõudluse parandus, mille tutvustas Laurent Vivier. See muudab
    ptrace() käitumist ja aitab vähendada hosti konteksti vahetuse kiirus.
    Selle toimimiseks vajate ka hosti tuuma plaastrit.
    Vaata http://perso.wanadoo.fr/laurent.vivier/UML/ edasise
    teabe saamiseks.

uml_dir=
    Asukoht pid ja umid failide paigutamiseks.

quiet
    Keerab välja teabe sõnumid käivitamise ajal.

hostfs=,,...
    Seda kasutatakse hostfs parameetrite seadmiseks. Juurkatalooge argument
    kasutatakse kõigi hostfs mahtude piiramiseks määratud katalooge
    puusse. Kui seda ei ole määratud, siis võib UML siseneja
    monteerida midagi hostil, mis on ligipääsetav kasutajale, kes selle
    käivitab.
    Praegu toetatud ainus lipp on 'append', mis määrab, et kõik
    hostfs-i avatud failid avatakse lisamise režiimis.

See lipp on valgustab käivitamise põhiseaded. Käivitame tuuma minimaalse vajaliku valikute kogumiga:

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

Ülaltoodud read ütlevad meie tuumale järgmist:

  • Oletame, et juurefailisüsteem on pseudoseade /dev/root.
  • Vali hostfs juurefailisüsteemi draiveriks.
  • Mount the guest file system we created in the root device.
  • Ja jah, lugemise-kirjutamise režiimis.
  • Kasutage ainult 64 megabaiti RAM-i (saate kasutada palju vähem, sõltuvalt sellest, mida kavatsete teha, kuid 64 MB tundub optimaalse mahuna).
  • Tuum käivitab automaatselt /bin/sh kuidas init-protsessi.

Käivitage see käsk ja peaksite saama midagi sellist nagu:

Veel üks leht

Core dump limits :
        soft - 0
        hard - NONE
Checking that ptrace can change system call numbers...OK
Checking syscall emulation patch for ptrace...OK
Checking advanced syscall emulation patch for ptrace...OK
Checking environment variables for a tempdir...none found
Checking if /dev/shm is on tmpfs...OK
Checking PROT_EXEC mmap in /dev/shm...OK
Adding 32137216 bytes to physical memory to account for exec-shield gap
Linux version 5.1.16 (cadey@kahless) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Sun Jul 7 18:57:19 UTC 2019
Built 1 zonelists, mobility grouping on.  Total pages: 23898
Kernel command line: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh
Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
Inode-cache hash table entries: 8192 (order: 4, 65536 bytes)
Memory: 59584K/96920K available (2692K kernel code, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS: 15
clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Calibrating delay loop... 7479.29 BogoMIPS (lpj=37396480)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
Checking that host ptys support output SIGIO...Yes
Checking that host ptys support SIGIO on close...No, enabling workaround
devtmpfs: initialized
random: get_random_bytes called from setup_net+0x48/0x1e0 with crng_init=0
Using 2.6 host AIO
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 256 (order: 0, 6144 bytes)
NET: Registered protocol family 16
clocksource: Switched to clocksource timer
NET: Registered protocol family 2
tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 1, 8192 bytes)
UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
NET: Registered protocol family 1
console [stderr0] disabled
mconsole (version 2) initialized on /home/cadey/.uml/tEwIjm/mconsole
Checking host MADV_REMOVE support...OK
workingset: timestamp_bits=62 max_order=14 bucket_order=0
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered (default)
io scheduler bfq registered
loop: module loaded
NET: Registered protocol family 17
Initialized stdio console driver
Using a channel type which is configured out of UML
setup_one_line failed for device 1 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 2 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 3 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 4 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 5 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 6 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 7 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 8 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 9 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 10 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 11 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 12 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 13 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 14 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 15 : Configuration failed
Console initialized on /dev/tty0
console [tty0] enabled
console [mc-1] enabled
Failed to initialize ubd device 0 :Couldn't determine size of device's file
VFS: Mounted root (hostfs filesystem) on device 0:11.
devtmpfs: mounted
This architecture does not have kernel memory protection.
Run /bin/sh as init process
/bin/sh: can't access tty; job control turned off
random: fast init done
/ # 

Ülaltoodud manipulatsioonid annavad meile külalisrežiimis miinimumversiooni, ilma selliste asjadeta nagu /proc või määratud hostinimi. Näiteks proovige järgmisi käske:

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

Külalisrežiimist väljumiseks sisestage exit või vajutage control-d. See tapab shelli ja põhjustab järgmist kernel panic:

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

Me saime selle kernel panic'i, kuna Linuxi südamik arvab, et initsialiseerimisprotsess on alati käimas. Ilma selleta ei saa süsteem enam funktsioneerida ja lõpetab töö. Kuid kuna see on kasutaja režiimi protsess, saadab saadud tulemus enda sisse SIGABRT, mis viib lahkumiseni.

Külgvõrgu seadistamine

Aga siit hakkavad asjad mitte nii nagu planeeritud minema. Võrk User Mode Linuxis on koht, kus kogu piiratud „kasutaja režiimi” kontseptsioon hakkab murenema. Tavalises süsteemi tasemel on võrk piiratud privileegitud täitmisrežiimide tõttu, mille põhjustel me kõik teame.

Märkusena: rohkem erinevate UMLi võrgu töötlemise variantide kohta saab lugeda siit.

Reis slirpi

Siiski on olemas iidne ja praktiliselt mitte toetatud tööriist nimega Slirp, mille, millega User Mode Linux suudab võrku suhelda. See töötab umbes nagu TCP/IP protokollipakk kasutaja tasemel ja ei vaja käivitamiseks süsteemilubasid. See tööriist oli välja antud 1995. aastal, viimase uuendusega kuupäeva 2006. aastal. Slirp on väga vana. Toetuse ja uuenduste puudumise tõttu on kompilaatorid jõudnud nii kaugele, et nüüd saab seda tööriista iseloomustada ainult kui «koodide lagunemine».

Nii et laseme Slirpi Ubuntu hoidlatest ja proovime seda käivitada:

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

Autoriõigus (c) 1995,1996 Danny Gasparovski ja teised.
Kõik õigused kaitstud.
See programm on autoriõiguse alusel tasuta tarkvara.
Palun lugege Slirpi
paketiga kaasas olnud faili COPYRIGHT autorite õiguste tingimuste kohta.

Slirpi hosti IP-aadress: 127.0.0.1
Teie DNS-i (de) IP-aadress(id): 1.1.1.1, 10.77.0.7
Teie aadress on 10.0.2.15
(või mis tahes muu, mida soovite)

Viie nulli (0) tippimine lõpetab.

[autodetekteeri SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baudi]

SLiRP Valmis ...
fisher: “/usr/bin/slirp” katkestatud signaali SIGSEGV (aadressiriba viga) tõttu

Oh, jumal püha. Laseme Slirpi jaoks debuggeri ja vaatame, kas suudame aru saada, mis siin toimub:

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.

Tõrge esines selles reas. Vaatame stacktrace'i, ehk leidub sealt midagi kasulikku:

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

Siin näeme, et rike toimub põhitsükli käivitamise ajal, kui slirp püüab kontrollida ajaülesandeid. Sel hetkel oleksin pidanud loobuma tõrkeotsingust. Kuid vaatame, kas Slirp töötab, kui see on allalaaditud allikatest. Tõin arhiivi otse veebisaidilt tagasi Sourceforge, sest seal midagi käsurealt alla tõmmata – see on piin:

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

Siin näeme teateid määratlemata sisseehitatud funktsioonide kohta, s.t. võimetus lingitud failis sümboleid genereerida. Tundub, et aastate vahel 2006 ja praeguse hetkeni on gcc lõpetanud looma sümboleid, mida kasutatakse sisseehitatud funktsioonide jaoks vahepeal compileeritud failides. Proovime asendada märksõna inline tühja kommentaariga ja vaatame, mis juhtub:

vi slirp.h
:6
a
<enter>
#define inline /**/
<escape>
:wq
make

Не-а. Это тоже не работает. По-прежнему не удается найти символы этих функций.

На этом этапе я сдалась и начала искать на Github пакеты сборки Heroku. Моя теория базировалась на том, что в каком-нибудь сборочном пакете Heroku будут содержаться необходимые мне двоичные файлы. В итоге поиски привели меня вот сюда. Я скачала и распаковала uml.tar.gz и нашла следующее:

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*

Это бинарный файл slirp! А он работает?

./slirp
Slirp v1.0.17 (BETA) FULL_BOLT

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]

SLiRP Ready ...

Не падает — так что должно сработать! Давайте подсадим этот бинарник в ~/bin/slirp:

cp slirp ~/bin/slirp

На случай, если создатель пакета удалит его, я сделала зеркало.

Võrgu seadistamine

Nüüd seadistame võrgu meie külaliskernelil. Uuendame käivitamisparameetreid:

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

Nüüd lülitame võrgu sisse:

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

Esimesed kaks seadistamise käsku /proc ja /sys on vajalikud tööks ifconfig, mis seadistab võrguliidese suhtlemiseks Slirpiga. Käsk mars seab kernelile marsruutimistabeleid, et sundida kogu liiklust Slirpi tunnelisse. Kontrollime seda DNS-päringu abil:

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

Nimi:      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

Töötas!

Märkus: Tundub, et algne post kirjutati lauaarvutis, millel oli juhtmeta võrkaart või mõni muu konfiguratsioon, mis ei nõua täiendavaid draivereid. Sülearvutis, millel on Intel WiFi 8265, tekib võrgu tõstmisel viga.

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

Tundub, et tuum ei saa ühendust võrgu draiveriga. Kahjuks ei parandanud firmware'i tuumasse kompileerimine olukorda. Avaldamise hetkel pole sellises konfiguratsioonis lahendust leitud. Lihtsamatel konfiguratsioonidel (näiteks Virtualboxis) tõuseb liides korrektselt.

Automatiseerime suunamise järgmise shell-skripti abil:

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

Ja teeme selle täidetavaks:

chmod +x init.sh

Ja siis teeme muudatused tuuma käsureale:

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

Ja kordame:

SLiRP Valmis ...
ettevõtte ühendus seadistatud
/bin/sh: ei pääse tty-le; töö juhtimine on välja lülitatud

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

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

Võrk töötab stabiilselt!

Docker-fail

Teie mugavuseks olen kokku pannud Dockerfile, mis automatiseerib enamik kirjeldatud samme ja peaks tagama teile töötava konfiguratsiooni. Mul on ka valmis tuumakonfiguratsioon, mis sisaldab kõike, mis postituses on mainitud. Kuid oluline on mõista, et siin olen kirjeldanud ainult minimaalset seadistust.

Loodan, et see postitus aitas teil mõista, kuidas luua külalisjaotust. Tuli välja mingisugune monster, kuid publikatsioon mõeldi kui kõikehõlmavat juhendit User Mode'i ülesehitamise, installimise ja seadistamise kohta Linuxis, kaasaegsete operatsioonisüsteemide versioonide jaoks. Järgmised sammud peaksid hõlmama teenuste ja muu tarkvara installimist juba külalissüsteemi sees. Kuna Docker'i konteineripildid on lihtsalt komprimeeritud tar-arhiivid, peate olema võimeline pilti välja tõmbama läbi docker export, ja seejärel määrake selle paigaldamise tee külalisjaotuse failisüsteemi juures. Siis käivitage shell-skripti.

Eriline tänu Rkeene'ile #lobsters kanalil Freenodes. Ilma tema abita Slirp'i tõrkeotsingul ei oleks ma nii kaugele jõudnud. Mul pole aimugi, kuidas tema Slackware'i süsteem slirpiga korrektselt toimib, kuid minu Ubuntu ja Alpine süsteemid ei aktsepteerinud slirp'i ja Rkeene'i pakutud binaarfaili. Kuid mulle piisab sellest, et mul on töötav lahendus.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster