Hvordan komme i gang med User Mode i Linux

Introduksjon fra oversetteren: Med den masseinnfĂžringen av forskjellige typer containere i livet vĂ„rt, kan det vĂŠre bĂ„de interessant og nyttig Ă„ lĂŠre om hvilke teknologier dette startet med en gang. Noen av dem kan fortsatt brukes, men ikke alle husker (eller vet om) slike metoder, hvis de ikke opplevde den hektiske utviklingen. En av disse teknologiene er User Mode Linux. Forfatteren av originalen har gravd en del, sett pĂ„ hva av gamle lĂžsninger som fortsatt fungerer, og hva som ikke gjĂžr det, og samlet noe som ligner pĂ„ en trinnvis instruksjon om hvordan man selv setter opp en hjemmeprodusert UML i 2k19. Og ja, vi har invitert forfatteren av det originale innlegget til Habr. Cadey, sĂ„ hvis du har spĂžrsmĂ„l — still dem pĂ„ engelsk i kommentarene.

Hvordan komme i gang med User Mode i Linux

User Mode i Linux er faktisk en port av Linux-kjernen til seg selv. Denne modusen lar deg kjÞre en fullverdig Linux-kjerne som en brukers prosess, og brukes vanligvis av utviklere for Ä teste drivere. Men denne modusen er ogsÄ nyttig som et verktÞy for generell isolasjon, prinsippet er likt som i virtuelle maskiner. Denne modusen gir stÞrre isolasjon enn Docker, men mindre enn en fullverdig virtuell maskin som KVM eller Virtual Box.

Generelt kan User Mode virke som et merkelig og komplisert verktÞy Ä bruke, men det har likevel sine bruksomrÄder. Det er en fullverdig Linux-kjerne som kjÞrer fra en ikke-privilegert bruker. Dette gjÞr det mulig Ä kjÞre potensielt usikker kode uten trusler mot vertsmaskinen. Og siden det er en fullverdig kjerne, er prosessene isolert fra vertsmaskinen, det vil si prosesser som kjÞrer inne i User Mode, vil ikke vÊre synlige for verten. Dette er ikke likt et vanlig Docker-container, der verts­maskinen alltid ser prosessene inne i lageret. Se pÄ dette utsnittet av pstree fra én av serverne mine:

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

Og sammenligne dette med pstree fra Linux-kjernen i brukermodus:

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

NÄr jeg jobber med Docker-containere, kan jeg se prosessnavn fra vertssystemet som kjÞrer i gjestemiljÞet. Dette er ikke mulig med Linux brukermodus. Hva betyr dette? Det betyr at overvÄkningsverktÞy som jobber gjennom Linuxs revisjonssubsystem ikke ser prosessene som kjÞrer i gjestemiljÞet. Men i enkelte situasjoner kan denne funksjonen bli en tveegget sverd.

Generelt sett er hele innlegget nedenfor en samling av undersÞkelser og harde forsÞk pÄ Ä oppnÄ Þnsket resultat. For dette har jeg mÄttet bruke forskjellige gamle verktÞy, lese kildekoden til kjernen, engasjere meg i intensiv kodingdebugging av kode skrevet pÄ en tid da jeg fortsatt gikk pÄ barneskolen, samt grave i Heroku-bygninger med hjelp av et spesialbygd binÊrverktÞy pÄ jakt etter verktÞyene jeg trengte. Alt dette arbeidet fÞrte til at gutta i IRCen min begynte Ä kalle meg en magiker (magic). Jeg hÄper at dette innlegget vil vÊre en pÄlitelig dokumentasjon for noen, slik at de kan gjÞre det samme, men med nyere kjerner og versjoner av OS.

Konfigurasjon

Konfigurering av Linux brukermodus skjer i flere trinn:

  • installasjon av avhengigheter pĂ„ verten;
  • nedlasting av Linux-kjernen;
  • konfigurering av kjernens bygning;
  • bygging av kjernen;
  • installering av binĂŠret;
  • konfigurering av gjestefilssystemet;
  • feste oppstartparametere for kjernen;
  • konfigurering av gjestenettverket;
  • oppstart av gjestekjernen.

Jeg antar at hvis du velger Ă„ hĂ„ndtere alt dette selv, vil du mest sannsynlig gjĂžre alt beskrevet i et Ubuntu- eller Debian-lignende system. Jeg har prĂžvd Ă„ implementere alt ovenfor i min favorittdistribusjon – Alpine, men det fungerte ikke, tilsynelatende fordi Linux-kjernen har stramme bindinger til glibc-isms for drivere i brukermodus. Jeg planlegger Ă„ rapportere dette upstream etter at jeg har fĂ„tt full forstĂ„else av problemet.

Installerer avhengigheter pÄ verten

Ubuntu krever minst fĂžlgende pakker for Ă„ bygge Linux-kjernen (forutsatt en ren installasjon):

- 'byggje-nĂždvendig'
- 'fleks'
- 'bison'
- 'xz-nyttige'
- 'wget'
- 'ca-sertifikat'
- 'bc'
- 'linux-hovudar'

Du kan installere dem med fĂžlgende kommando (med root-rettigheter eller ved hjelp av sudo):

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

Vennligst merk at kjĂžringen av konfigurasjonsprogrammet for meny for Linux-kjernen vil kreve installasjon av libncurses-dev. Vennligst sĂžrg for at det er installert med fĂžlgende kommando (med root-rettigheter eller ved hjelp av sudo):

apt-get -y install libncurses-dev

Nedlasting av kjernen

Bestem stedet for nedlasting og pÄfÞlgende bygging av kjernen. For denne operasjonen trenger du omtrent 1,3 GB plass pÄ harddisken, sÄ vÊr sikker pÄ at du har det.

Deretter gÄr du til kernel.org og fÄr URL-en for Ä laste ned den nyeste stabile versjonen av kjernen. PÄ tidspunktet for skrivingen er dette: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Last ned denne filen med 'wget':

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

Og pakk den ut med 'tar':

tar xJf linux-5.1.16.tar.xz

NÄ gÄr vi inn i katalogen som ble opprettet ved pakkingen av tarballen:

cd linux-5.1.16

Konfigurering av byggingen av kjernen

Kjernekonstruksjonssystemet er et sett med Make-filer med med mange brukerverktÞy og skript for Ä automatisere prosessen. For Ä starte, Äpne det interaktive konfigurasjonsprogrammet:

make ARCH=um menuconfig

Det vil delvis gjennomfÞre bygget og vise deg et dialogvindu. NÄr '[Select]' vises nederst i vinduet, kan du begynne konfigurasjonen ved hjelp av mellomromstasten eller Enter. Navigering i vinduet er som vanlig med piltastene «opp» og «ned», og markering av elementer er «venstre» eller «hÞyre».

En pekersymbol som —> indikerer at du er i en undermeny, tilgang til den gjĂžres med Enter. Utgangen er Ă„penbart gjennom'[Exit]‘.

Aktiver fĂžlgende alternativer i '[Select]' og sĂžrg for at det er et symbol '[*]' ved siden av dem:

UML-spesifikke alternativer:
  - Vert filsystem
NettverksstÞtte (aktiver dette for Ä fÄ frem undermenyen):
  - Nettverksalternativer:
    - TCP/IP-nettverk
UML-nettverksenheter:
  - Virtuell nettverksenhet
  - SLiRP-transport

Alt dette vinduet kan du avslutte ved gradvis Ă„ velge ‘[Exit]‘. Bare vĂŠr sikker pĂ„ at du blir bedt om Ă„ lagre konfigurasjonen til slutt og velger ‘[Ja]‘.

Jeg anbefaler at du leker med kjernens byggeparametere etter Ä ha lest dette innlegget. Gjennom disse eksperimentene vil du kunne lÊre mye om hvordan lavnivÄkjernemekanismer fungerer og hvordan ulike flagg pÄvirker byggingen.

Bygge kjerne

Linux-kjernen er et stort program som tar seg av mange oppgaver. Selv med en sÄ minimal konfigurasjon pÄ gammelt utstyr kan byggingen ta en stund. SÄ kjÞr fÞlgende kommando for Ä bygge kjernen:

make ARCH=um -j$(nproc)

Hvorfor? Denne kommandoen ber byggeren vÄr om Ä bruke alle tilgjengelige kjerner og prosessortrÄder under byggeprosessen. Kommandoen $(nproc) for enden av Build setter inn output av kommandoen nproc, som er en del av coreutils i standardbyggingen av Ubuntu.

Etter en viss tid vil kjernen vÄr bli bygget i en kjÞrbar fil ./linux.

Installasjon av binĂŠrfil

Siden User Mode i Linux lager en vanlig binĂŠrfil, kan du installere den som enhver annen verktĂžy. Slik har jeg gjort det:

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

Det er ogsÄ viktig at ~/bin finnes i din $PATH:

export PATH=$PATH:$HOME/bin

Konfigurering av gjeste-filsystemet

Lag en mappe for gjeste-filsystemet:

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

Åpne alpinelinux.org og i nedlastingsseksjonen finn den aktuelle lenken for nedlasting MINI ROOT FILESYSTEM. PĂ„ tidspunktet for skriving av publikasjonen var dette:

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

Last ned denne tarballen ved hjelp av 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

GÄ nÄ inn i mappen for gjeste-filsystemet og pakk ut arkivet:

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

De beskrevne handlingene vil lage en liten mal for filsystemet. PĂ„ grunn av systemets natur vil det vĂŠre svĂŠrt vanskelig Ă„ installere pakker via Alpine-pakkebehandleren apk. Men dette filsystemet vil vĂŠre tilstrekkelig for Ă„ vurdere den generelle ideen.

Vi vil ogsÄ trenge et verktÞy tini for Ä hindre minneforbruk av zombie-prosesser i vÄr gjestekjerne.

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

Opprettelse av kommandolinje for kjernen

I kjernen av Linux, som i de fleste andre programmer, finnes det kommandolinjeargumenter som du kan enkelt se ved Ă„ bruke nĂžkkelen --help.

Selv —help

linux --help
User Mode Linux v5.1.16
        tilgjengelig pÄ http://user-mode-linux.sourceforge.net/

--showconfig
    Skriver ut konfigurasjonsfilen som denne UML-binaryen ble generert fra.

iomem=,
    Konfigurer  som et IO-minneomrÄde med navnet .

mem=
    Dette kontrollerer hvor mye "fysisk" minne kjernen tildeler
    for systemet. StĂžrrelsen spesifiseres som et tall etterfulgt av
    en av 'k', 'K', 'm', 'M', som har Äpenbare betydninger.
    Dette er ikke relatert til mengden minne i vertsmaskinen. Den kan
    vĂŠre stĂžrre, og overskuddet, hvis det noen gang brukes, vil bare bli byttet ut.
        Eksempel: mem=64M

--help
    Skriver ut denne meldingen.

debug
    dette flagget er ikke nÞdvendig for Ä kjÞre gdb pÄ UML i skas-modus

root=
    Dette brukes faktisk av den generiske kjernen pÄ nÞyaktig samme
    mÄte som i enhver annen kjerne. Hvis du konfigurerer et antall blokk
    enheter og Þnsker Ä starte fra noe annet enn ubd0, mÄ du bruke noe som:
        root=/dev/ubd5

--version
    Skriver ut versjonsnummeret til kjernen.

umid=
    Dette brukes til Ă„ tilordne en unik identitet til denne UML-maskinen og
    brukes til Ă„ navngi pid-filen og administrasjonskonsoll-socket.

con[0-9]*=
    Koble en konsoll eller seriell linje til en vertskanal. Se
    http://user-mode-linux.sourceforge.net/old/input.html for en komplett
    beskrivelse av denne bryteren.

eth[0-9]+=,
    Konfigurer et nettverksenhet.
    
aio=2.4
    Dette brukes for Ä tvinge UML til Ä bruke 2.4-stil AIO selv nÄr 2.6 AIO er
    tilgjengelig. 2.4 AIO er en enkelt trÄd som hÄndterer én forespÞrsel om gangen,
    synkront. 2.6 AIO er en trÄd som bruker 2.6 AIO
    grensesnittet for Ä hÄndtere et vilkÄrlig antall ventende forespÞrsel. 2.6 AIO
    er ikke tilgjengelig i tt-modus, pÄ 2.4 verter, eller nÄr UML er bygget med
    /usr/include/linux/aio_abi.h ikke tilgjengelig. Mange distribusjoner inkluderer ikke
    aio_abi.h, sÄ du mÄ kopiere den fra et kjernetre til
    ditt /usr/include/linux for Ă„ bygge en AIO-kapabel UML

nosysemu
    SlÄr av syskall-emuleringspatch for ptrace (SYSEMU).
    SYSEMU er en ytelsespakt introdusert av Laurent Vivier. Den endrer
    atferden til ptrace() og hjelper med Ă„ redusere vertens kontektsbytte.
    For Ä fÄ det til Ä fungere, trenger du ogsÄ en kjernemodifikasjon for verten din.
    Se http://perso.wanadoo.fr/laurent.vivier/UML/ for mer
    informasjon.

uml_dir=
    Plasseringen for Ă„ plassere pid- og umid-filer.

quiet
    SlÄr av informasjonsmeldinger under oppstart.

hostfs=,,...
    Dette brukes til Ă„ sette hostfs-parametere. Rotkatalogargumentet
    brukes til Ă„ begrense alle hostfs-mounts innenfor det spesifiserte katalogtreet
    pÄ verten. Hvis dette ikke spesifiseres, kan en bruker inne i UML
    montere hva som helst pÄ verten som er tilgjengelig for brukeren som kjÞrer
    det.
    Det eneste flagget som for Ăžyeblikket stĂžttes er 'append', som angir at alle
    filer Äpnet av hostfs vil bli Äpnet i append-modus.

Dette banneret belyser de viktigste oppstartparametrene. La oss starte kjernen med det minimum nĂždvendige settet av alternativer:

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

Linjene ovenfor sier til kjernen vÄr fÞlgende:

  • La oss anta at rotfilen er en pseudo-enhet /dev/root.
  • Velg hostfs som som driver for rotfilssystemet.
  • Monter gjestefilssystemet vi opprettet i rot-enheten.
  • Og ja, i lese-skrive-modus.
  • Bruk kun 64 megabyte med RAM (du kan bruke mye mindre, avhengig av hva du planlegger Ă„ gjĂžre, men 64 MB virker Ă„ vĂŠre et optimalt belĂžp).
  • Kjernen starter automatisk /bin/sh som init-prosessen.

KjÞr denne kommandoen, og du bÞr fÄ noe som ligner pÄ det fÞlgende:

En annen ark

Kjernesvaktgrensene :
        myk - 0
        hard - INGEN
Sjekker at ptrace kan endre systemkallnumre...OK
Sjekker syscall-emulasjonspatch for ptrace...OK
Sjekker avansert syscall-emulasjonspatch for ptrace...OK
Sjekker miljĂžvariabler for en midlertidig mappe...ingen funnet
Sjekker om /dev/shm er pÄ tmpfs...OK
Sjekker PROT_EXEC mmap i /dev/shm...OK
Legger til 32137216 byte til fysisk minne for Ă„ ta hensyn til exec-shield-gap
Linux-versjon 5.1.16 (cadey@kahless) (gcc versjon 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 SĂžndag 7. juli 2019 kl. 18:57:19 UTC
Bygget 1 zonelister, mobilitetsgruppering pÄ.  Totalt sider: 23898
Kjernens kommandolinje: rot=/dev/root rotflag=/home/cadey/dl/uml/alpine rotfstyper=hostfs rw mem=64M init=/bin/sh
Dentry cache hash-tabelloppfĂžringer: 16384 (rekkefĂžlge: 5, 131072 byte)
Inode-cache hash-tabelloppfĂžringer: 8192 (rekkefĂžlge: 4, 65536 byte)
Minne: 59584K/96920K tilgjengelig (2692K kjernkode, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reservert, 0K cma-reservert)
SLUB: HWalign=64, RekkefĂžlge=0-3, MinObjects=0, CPUer=1, Noder=1
NR_IRQS: 15
klokke kilde: timer: maske: 0xffffffffffffffff maks_sykluser: 0x1cd42e205, maks_inaktiv_ns: 881590404426 ns
Kalibrerer forsinkelsesslĂžyfe... 7479.29 BogoMIPS (lpj=37396480)
pid_max: standard: 32768 minimum: 301
Monter-cache hash-tabelloppfĂžringer: 512 (rekkefĂžlge: 0, 4096 byte)
Monteringspunkt-cache hash-tabelloppfĂžringer: 512 (rekkefĂžlge: 0, 4096 byte)
Sjekker at vertens ptys stĂžtter utdata SIGIO...Ja
Sjekker at vertens ptys stĂžtter SIGIO ved lukking...Nei, aktiverer workaround
devtmpfs: initialisert
random: get_random_bytes kalt fra setup_net+0x48/0x1e0 med crng_init=0
Bruker 2.6 vert AIO
klokke kilde: jiffies: maske: 0xffffffff maks_sykluser: 0xffffffff, maks_inaktiv_ns: 19112604462750000 ns
futex hash-tabelloppfĂžringer: 256 (rekkefĂžlge: 0, 6144 byte)
NET: Registrert protokollfamilie 16
klokke kilde: Byttet til klokke kilde timer
NET: Registrert protokollfamilie 2
tcp_listen_portaddr_hash hash-tabelloppfĂžringer: 256 (rekkefĂžlge: 0, 4096 byte)
TCP etablerte hash-tabelloppfĂžringer: 1024 (rekkefĂžlge: 1, 8192 byte)
TCP binde hash-tabelloppfĂžringer: 1024 (rekkefĂžlge: 1, 8192 byte)
TCP: Hash-tabeller konfigurert (etablert 1024 bind 1024)
UDP hash-tabelloppfĂžringer: 256 (rekkefĂžlge: 1, 8192 byte)
UDP-Lite hash-tabelloppfĂžringer: 256 (rekkefĂžlge: 1, 8192 byte)
NET: Registrert protokollfamilie 1
konsoll [stderr0] deaktivert
mconsole (versjon 2) initialisert pÄ /home/cadey/.uml/tEwIjm/mconsole
Sjekker vert MADV_REMOVE stĂžtte...OK
arbeidssett: timestamp_bits=62 max_order=14 bucket_order=0
Blokklags SCSI generisk (bsg) driver versjon 0.4 lastet (stĂžrrelse 254)
io-scheduler noop registrert (standard)
io-scheduler bfq registrert
loop: modul lastet
NET: Registrert protokollfamilie 17
Initialisert stdio konsoldriver
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 1 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 2 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 3 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 4 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 5 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 6 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 7 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 8 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 9 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 10 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 11 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 12 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 13 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 14 : Konfigurasjon feilet
Bruker en kanals type som er konfigurert utenfor UML
setup_one_line feilet for enhet 15 : Konfigurasjon feilet
Konsoll initialisert pÄ /dev/tty0
konsoll [tty0] aktivert
konsoll [mc-1] aktivert
Mislyktes Ä initialisere ubd-enhet 0 : Kunne ikke bestemme stÞrrelsen pÄ enhetens fil
VFS: Montert rot (hostfs filsystem) pÄ enhet 0:11.
devtmpfs: montert
Denne arkitekturen har ikke kjerneminnesikring.
KjĂžr /bin/sh som init-prosess
/bin/sh: klarer ikke fÄ tilgang til tty; jobkontroll slÄtt av
random: rask init fullfĂžrt
/ # 

Manipulasjonene over vil gi oss et minimum av gjestesystemet, uten slike ting som /proc eller tildelt vertsnavn. For eksempel, prĂžv Ă„ kjĂžre fĂžlgende kommandoer:

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

For Ä forlate gjestesystemet, skriv inn exit eller trykk control-d. Dette vil avslutte skallet med pÄfÞlgende kernel panic:

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

Vi fikk denne kernel panikken fordi Linux-kjernen mener at initialiseringsprosessen alltid kjĂžrer. Uten dette kan ikke systemet fungere og avslutter. Men siden dette er et brukermodusprosjekt, sender det resulterende resultatet seg selv til SIGABRT, noe som fĂžrer til utgangen.

Innstilling av gjestenettverk

Her begynner vi Ä avvike fra planen. Nettverket i User Mode Linux er stedet hvor hele konseptet med begrenset "bruksmodus" begynner Ä bryte sammen. Vanligvis er nettverket pÄ systemnivÄ begrenset privilegerte kjÞringsmoduser av alle kjente grunner.

Merk: mer om ulike metoder for nettverksarbeid i UML kan leses her.

Reisen til slirp

Imidlertid finnes det et gammelt og praktisk talt utdatert verktÞy kalt Slirp, som lar User Mode Linux kommunisere med nettverket. Det fungerer omtrent som et TCP/IP-stakk pÄ brukernivÄ og krever ingen systemtillatelser for Ä kjÞre. Dette verktÞyet ble utgitt i 1995, og den siste oppdateringen er datert 2006. Slirp er veldig gammelt. PÄ grunn av lang tid uten stÞtte og oppdateringer har kompilatorene utviklet seg sÄ mye at dette verktÞyet nÄ kan beskrives som "code rot".

SĂ„ la oss installere Slirp fra Ubuntu-repositoriene og prĂžve Ă„ starte det:

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

Kopirett (c) 1995,1996 Danny Gasparovski og andre.
Alle rettigheter forbeholdt.
Dette programmet er opphavsrettsbeskyttet, gratis programvare.
Vennligst les filen COPYRIGHT som fĂžlger med Slirp
pakken for vilkÄrene og betingelsene for opphavsretten.

IP-adresse til Slirp-vert: 127.0.0.1
IP-adresse(r) til dine DNS: 1.1.1.1, 10.77.0.7
Din adresse er 10.0.2.15
(eller hva som helst annet du Ăžnsker)

Skriv fem nuller (0) for Ă„ avslutte.

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

SLiRP Klar ...
fisk: "/usr/bin/slirp" avsluttet av signal SIGSEGV (Adressegrensefeil)

Åh, kjére. La oss installere en debugger for Slirp og se om vi kan finne ut hva som skjer:

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.

Feil skjer i denne linjen. La oss se pÄ stacktrace, kanskje det kan hjelpe oss:

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

Her ser vi at feilen oppstÄr under oppstart av hovedlÞkken, nÄr slirp forsÞker Ä sjekke tidsavbrudd. PÄ dette tidspunktet burde jeg ha gitt opp feilsÞkingen. Men la oss se om Slirp fungerer, bygget fra kildefiler. Jeg lastet ned arkivet direkte fra nettstedet Sourceforge, fordi det er en smerte Ä dra noe derfra via kommandolinjen:

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

Her ser vi varsler om udefinerte innebygde funksjoner, det vil si at det er umulig Ä linke den resulterende binÊrfilen. Det ser ut til at i perioden mellom 2006 og dette tidspunktet har gcc sluttet Ä generere symboler som brukes i innebygde funksjoner fra mellomliggende kompileringer. La oss prÞve Ä erstatte nÞkkelordet inline med en tom kommentar og se pÄ resultatet:

vi slirp.h
:6
a

#define inline /**/

:wq
make

Nei. Dette fungerer heller ikke. Kan fortsatt ikke finne tegnene til disse funksjonene.

PÄ dette stadiet ga jeg opp og begynte Ä sÞke pÄ Github Heroku samlingspakker. Min teori var basert pÄ at det i en eller annen samlingspakke fra Heroku ville vÊre nÞdvendige binÊrfiler. Til slutt fÞrte sÞket meg hit. Jeg lastet ned og pakket ut uml.tar.gz og fant fÞlgende:

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*

Dette er binĂŠrfilen slirp! Fungerer den?

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

Copyright (c) 1995,1996 Danny Gasparovski og andre.
Alle rettigheter forbeholdt.
Dette programmet er opphavsrettsbeskyttet, gratis programvare.
Vennligst les filen COPYRIGHT som fulgte med Slirp
pakken for vilkÄr og betingelser for opphavsrett.

IP-adressen til Slirp-verten: 127.0.0.1
IP-adresser til dine DNS-er: 1.1.1.1, 10.77.0.7
Din adresse er 10.0.2.15
(eller hva annet du vil)

Skriv fem nuller (0) for Ă„ avslutte.

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

SLiRP Klar ...

Det krasjer ikke — sĂ„ det burde fungere! La oss legge inn denne binĂŠrfilen i ~\/bin\/slirp:

cp slirp ~\/bin\/slirp

I tilfelle pakkeskaperen fjerner den, har jeg laget et speil.

Innstilling av nettverk

NÄ la oss sette opp nettverket pÄ vÄrt gjeste-kjerne. Oppdater oppstartsparameterne:

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

NĂ„ la oss aktivere nettverket:

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

De fÞrste to konfigurasjonskommandoene /proc og /sys er nÞdvendige for Ä fungere ifconfig, som setter opp nettverksgrensesnittet for kommunikasjon med Slirp. Kommandoen rute setter opp kjernens rutetabell for Ä tvinge alt trafikk gjennom Slirp-tunnelen. La oss sjekke dette med et DNS-spÞrsmÄl:

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

Navn:      google.com
Adresse 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Adresse 2: 2607:f8b0:4006:81b::200e lga25s63-in-x0e.1e100.net

Det fungerer!

Merk: Det ser ut som det opprinnelige innlegget ble skrevet pÄ en stasjonÊr datamaskin med en kabelnettverkskort, eller en annen konfigurasjon som ikke krever ekstra drivere. PÄ en bÊrbar PC med WiFi 8265 fra Intel oppstÄr det derimot en feil nÄr nettverket aktiveres.

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

Det ser ut til at kjernen ikke kan kommunisere med nettverksdriveren. ForsÞk pÄ Ä kompilere firmware inn i kjernen lÞste dessverre ikke problemet. PÄ tidspunktet for publisering har vi ikke funnet en lÞsning for akkurat denne konfigurasjonen. PÄ enklere konfigurasjoner (som for eksempel i Virtualbox) aktiveres grensesnittet riktig.

La oss automatisere omdirigeringen med fĂžlgende shell-script:

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

Og la oss gjĂžre det kjĂžrbart:

chmod +x init.sh

Og sÄ gjÞr vi endringer i kjernebootlinjen:

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

Og gjentar:

SLiRP Klar ...
nettverket er satt opp
\/bin\/sh: kan ikke fÄ tilgang til tty; jobbkontroll er slÄtt av

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

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

Nettverket fungerer stabilt!

Docker-fil

For Ä gjÞre det lettere for deg Ä sjekke alt dette, har jeg samlet Dockerfile, som automatiserer de fleste beskrivne trinnene og bÞr gi deg en fungerende konfigurasjon. Jeg har ogsÄ en ferdig kjernekonfigurasjon, som har alt som er beskrevet i innlegget. Men det er viktig Ä forstÄ at jeg bare har laget den minimale konfigurasjonen.

Jeg hÄper dette innlegget har hjulpet deg Ä forstÄ hvordan du setter opp gjestekjernen. Det ble en slags monstert, men innlegget var ment som en omfattende guide til bygging, installasjon og konfigurasjon av User Mode i Linux for moderne versjoner av operativsystemene i denne familien. Videre trinn bÞr inkludere installasjon av tjenester og annen programvare inne i gjestesystemet. Siden Docker-bilder bare er lagrede tar-arkiver, bÞr du vÊre i stand til Ä trekke bildet gjennom docker export, og deretter angi stien for installasjonen i rotmappen av gjestekjernen. SÄ kjÞr shell-scriptet.

En spesiell takk til Rkeene med #lobsters pÄ Freenode. Uten hans hjelp med feilsÞking av Slirp ville jeg ikke ha kommet sÄ langt. Jeg har ingen anelse om hvordan systemet hans Slackware fungerer riktig med slirp, men mine Ubuntu- og Alpine-systemer aksepterte ikke slirp og den Rkeene-binaryen som ble foreslÄtt til meg. Men jeg er glad for at jeg har fÄtt noe til Ä fungere.

Kilde: habr.com

KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere đŸ”„ KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster