Hur man börjar anvÀnda User Mode i Linux

Inledning frĂ„n översĂ€ttaren: Mot bakgrund av det massiva intrĂ„nget av olika typer av containrar i vĂ„ra liv kan det vara intressant och anvĂ€ndbart att veta vilka teknologier detta en gĂ„ng började med. Vissa av dem kan fortfarande anvĂ€ndas med fördel idag, men inte alla kommer folk ihĂ„g (eller kĂ€nner till, om de inte upplevde tiden för deras hastiga utveckling). En av dessa teknologier Ă€r User Mode Linux. Författaren av originalet har grĂ€vt djupt för att ta reda pĂ„ vad av de gamla lösningarna som fortfarande fungerar och vad som inte gör det, och har samlat nĂ„got som liknar en steg-för-steg-instruktion om hur man sjĂ€lv kan sĂ€tta upp en hemgjord UML 2019. Och ja, vi har bjudit in författaren av det ursprungliga inlĂ€gget till Habr. Cadey, sĂ„ om ni har frĂ„gor — stĂ€ll dem pĂ„ engelska i kommentarerna.

Hur man börjar anvÀnda User Mode i Linux

User Mode i Linux Àr i praktiken en portering av Linux-kÀrnan pÄ sig sjÀlv. Det hÀr lÀget gör det möjligt att köra en fullstÀndig Linux-kÀrna som en anvÀndarprocess och anvÀnds vanligtvis av utvecklare för att testa drivrutiner. Men detta lÀge Àr ocksÄ anvÀndbart som ett verktyg för allmÀn isolering, vars princip liknar att anvÀnda virtuella maskiner. Detta lÀge ger större isolering Àn Docker, men mindre Àn en fullstÀndig virtuell maskin som KVM eller Virtual Box.

Överlag kan User Mode verka som ett konstigt och svĂ„rt verktyg att anvĂ€nda, men det har Ă€ndĂ„ sina tillĂ€mpningsomrĂ„den. Det Ă€r trots allt en fullstĂ€ndig Linux-kĂ€rna som körs av en icke-privilegerad anvĂ€ndare. Denna egenskap gör det möjligt att köra potentiellt osĂ€kert kod utan nĂ„gra hot mot vĂ€rdmaskinen. Och eftersom det Ă€r en fullstĂ€ndig kĂ€rna, Ă€r dess processer avskilda frĂ„n vĂ€rdmaskinen, vilket innebĂ€r att processer som körs inom User Mode inte kommer att vara synliga för vĂ€rden.Detta liknar inte en vanlig Docker-container, dĂ€r vĂ€rdmaskinen alltid kan se processerna inne i lagringsutrymmet. Titta pĂ„ detta stycke pstree frĂ„n en av mina servrar:

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

Och jÀmför detta med pstree i Linux-kÀrnan i anvÀndarlÀge:

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

NÀr jag arbetar med Docker-containrar kan jag se processnamnen som körs i gÀstsystemet frÄn vÀrden. Med Linux anvÀndarlÀge Àr detta inte möjligt. Vad betyder detta? Det betyder att övervakningsverktyg som arbetar genom Linuxs revisionssystem inte ser processer som körs i gÀstsystemet. Men i vissa situationer kan denna funktion bli en tveeggat svÀrd.

Hela inlÀgget nedan Àr en uppsÀttning av forskningar och grova försök att Ästadkomma önskat resultat. För detta har jag tvingats anvÀnda olika gamla verktyg, lÀsa kÀllkoden till kÀrnan, Àgna mig Ät intensiv felsökning av kod som skrivits under en tid nÀr jag fortfarande gick i grundskolan, samt grÀva i Heroku-uppsÀttningar med hjÀlp av ett speciellt binÀrprogram för att hitta de verktyg jag behövde. allt detta arbete ledde till att killarna i min IRC började kalla mig för magikern. Jag hoppas att detta inlÀgg kan fungera som en tillförlitlig dokumentation för nÄgon som vill göra exakt samma sak, men med nyare kÀrnor och versioner av operativsystem.

InstÀllning

InstÀllning av Linux anvÀndarlÀge sker i flera steg:

  • installation av beroenden pĂ„ vĂ€rden;
  • nedladdning av Linux-kĂ€rnan;
  • konfigurera kĂ€rnbygget;
  • bygga kĂ€rnan;
  • installera binĂ€rfilen;
  • konfigurera gĂ€stfilsystemet;
  • vĂ€lja startparametrar för kĂ€rnan;
  • konfigurera gĂ€stnĂ€tverket;
  • starta gĂ€stkĂ€rnan.

Jag antar att om du beslutar dig för att göra allt detta sjĂ€lv, sĂ„ kommer du högst troligt att göra det i nĂ„got Ubuntu- eller Debian-liknande system. Jag försökte implementera allt ovan i min favoritdistribution – Alpine, men det blev inget av, uppenbarligen pĂ„ grund av att Linux-kĂ€rnan har en strikt koppling till glibc-isms för drivrutiner i anvĂ€ndarlĂ€ge. Jag planerar att rapportera detta till upstream efter att jag har förstĂ„tt problemet helt.

Installation av beroenden pÄ vÀrden

Ubuntu krÀver minst följande paket för att bygga Linux-kÀrnan (förutsatt en ren installation):

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

Du kan installera dem med följande kommando (med root-rÀttigheter eller med sudo):

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

Observera att körningen av instÀllningsprogrammet för Linux-kÀrnan kommer att krÀva installation av libncurses-dev. VÀnligen se till att det Àr installerat med följande kommando (med root-rÀttigheter eller med sudo):

apt-get -y install libncurses-dev

Nedladdning av kÀrnan

BestÀm en plats för nedladdning och efterföljande byggnation av kÀrnan. För denna operation behöver du avsÀtta cirka 1,3 GB utrymme pÄ hÄrddisken, sÄ se till att du har det.

Efter det, gÄ till kernel.org och erhÄll URL:en för att ladda ner den senaste stabila versionen av kÀrnan. Vid tidpunkten för skrivandet av detta inlÀgg, Àr det: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Ladda ner denna fil med 'wget':

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

Och extrahera den med 'tar':

tar xJf linux-5.1.16.tar.xz

Nu gÄr vi in i katalogen som skapades vid uppackningen av tarball:

cd linux-5.1.16

Konfigurering av kÀrnbyggnation

Byggsystemet för kÀrnan Àr en uppsÀttning Make-filer med med mÄnga anvÀndarverktyg och skript för att automatisera processen. Börja med att öppna det interaktiva konfigurationsprogrammet:

make ARCH=um menuconfig

Det kommer delvis att genomföra byggprocessen och visa dig en dialogruta. NĂ€r det i botten av fönstret visas ‘[Select]‘, kan du börja konfigurera med hjĂ€lp av mellanslagstangent eller Enter. Navigering i fönstret görs som vanligt med piltangenterna ‘upp’ och ‘ner’, och val av element med ‘vĂ€nster’ eller ‘höger’.

En indikator av typen –> innebĂ€r att du Ă€r i en undermeny, som du gĂ„r in i med Enter-tangenten. UtgĂ„ng frĂ„n den, uppenbarligen, genom ‘[Exit]‘.

Aktivera följande alternativ i ‘[Select]‘ och se till att det finns en symbol ‘[*]’ bredvid dem:

UML-specifika alternativ:
  - VĂ€rdfilssystem
NÀtverksstöd (aktivera detta för att fÄ undermenyn att visas):
  - NĂ€tverksalternativ:
    - TCP/IP-nÀtverk
UML-nÀtverksenheter:
  - Virtuell nÀtverksenhet
  - SLiRP-transport

Allt, detta fönster kan lĂ€mnas genom att vĂ€lja ‘[Exit]‘. Se bara till att du erbjuds att spara konfigurationen i slutet och vĂ€ljer ‘[Ja]‘.

Jag rekommenderar att du leker med kÀrnkonfigurationsalternativen efter att ha lÀst detta inlÀgg. Genom dessa experiment kan du lÀra dig mycket om hur lÄgnivÄmekanikerna i kÀrnan fungerar och hur olika flaggor pÄverkar dess kompilering.

Kompilering av kÀrna

Linux-kĂ€rnan Ă€r ett stort program som sysslar med mĂ„nga saker. Även med en sĂ„ minimal konfiguration kan kompileringen ta ganska lĂ„ng tid pĂ„ gammal utrustning. SĂ„ hĂ€r kompilera du kĂ€rnan med följande kommando:

make ARCH=um -j$(nproc)

Varför? Detta kommando sÀger till vÄr kompilator att anvÀnda alla tillgÀngliga kÀrnor och trÄdar i processen. Kommandot $(nproc) i slutet av Byggd sÀtter in utdata frÄn kommandot nproc, som Àr en del av coreutils i den standardmÀssiga Ubuntu-konfigurationen.

Efter en stund kommer vÄr kÀrna att kompilera till en körbar fil ./linux.

Installation av binÀrfilen

Eftersom User Mode i Linux skapar en vanlig binÀrfil kan du installera den som vilken annan verktyg som helst. SÄ hÀr gjorde jag:

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

Det Àr ocksÄ vÀrt att se till att ~/bin finns i din $PATH:

export PATH=$PATH:$HOME/bin

Konfigurera gÀstfilssystemet

Skapa en katalog för gÀstfilssystemet:

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

Öppna alpinelinux.org och i nedladdningsavsnittet hitta den aktuella nedladdningslĂ€nken MINI ROOT FILESYSTEM. Vid tidpunkten för detta inlĂ€gg var det:

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

Ladda ner denna tarball med 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Ä nu in i gÀstfilssystemets katalog och packa upp arkivet:

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

De beskrivna ÄtgÀrderna kommer att skapa en liten mall av filsystemet. PÄ grund av systemets egenskaper kan det vara mycket svÄrt att installera paket via apks hanterare. Men detta filsystem kommer att vara tillrÀckligt för att förstÄ den övergripande idén.

Vi kommer ocksÄ att behöva verktyget tini för att förhindra minnesanvÀndning av zombieprocesser i vÄrt gÀstkÀrna.

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

Skapa kÀrnkommandoraden

I Linux-kÀrnan, liksom i de flesta andra program, finns det kommandoradsargument som kan ses genom att ange nyckeln --help.

SjĂ€lv —help

linux --help
User Mode Linux v5.1.16
        finns tillgÀnglig pÄ http://user-mode-linux.sourceforge.net/

--showconfig
    Skriver ut konfigurationsfilen som denna UML-binÀr skapades frÄn.

iomem=,
    Konfigurera  som en IO-minnesregion namngiven .

mem=
    Detta kontrollerar hur mycket "fysisk" minne kÀrnan allokerar
    för systemet. Storleken anges som ett nummer följt av
    en av 'k', 'K', 'm', 'M', som har de uppenbara betydelserna.
    Detta Àr inte relaterat till mÀngden minne i vÀrden. Det kan
    vara mer, och överskotten, om de nÄgonsin anvÀnds, kommer bara att bli swapade.
        Exempel: mem=64M

--help
    Skriver ut detta meddelande.

debug
    denna flagga behövs inte för att köra gdb pÄ UML i skas-lÀge

root=
    Detta anvÀnds faktiskt av den generiska kÀrnan pÄ exakt samma
    sÀtt som i nÄgon annan kÀrna. Om du konfigurerar ett antal block
    enheter och vill starta frÄn nÄgot annat Àn ubd0, skulle du
    anvÀnda nÄgot som:
        root=/dev/ubd5

--version
    Skriver ut versionsnumret av kÀrnan.

umid=
    Detta anvÀnds för att tilldela en unik identitet till denna UML-maskin och
    anvÀnds för att namnge pid-filen och hanteringskonsolens socket.

con[0-9]*=
    Koppla en konsol eller seriell linje till en vÀrdkanal. Se
    http://user-mode-linux.sourceforge.net/old/input.html för en fullstÀndig
    beskrivning av denna switch.

eth[0-9]+=,
    Konfigurera en nÀtverksenhet.
    
aio=2.4
    Detta anvÀnds för att tvinga UML att anvÀnda 2.4-stil AIO Àven nÀr 2.6 AIO Àr
    tillgÀnglig. 2.4 AIO Àr en enda trÄd som hanterar en förfrÄgan i
    taget, synkront. 2.6 AIO Àr en trÄd som anvÀnder 2.6 AIO
    grÀnssnittet för att hantera ett godtyckligt antal utestÄende förfrÄgningar. 2.6 AIO
    Àr inte tillgÀnglig i tt-lÀge, pÄ 2.4-vÀrdar eller nÀr UML Àr byggd med
    /usr/include/linux/aio_abi.h inte tillgÀnglig. MÄnga distributioner inkluderar inte
    aio_abi.h, sÄ du behöver kopiera den frÄn en kÀrntrÀ till
    din /usr/include/linux för att bygga en AIO-kapabel UML.

nosysemu
    StÀnger av syscall-emuleringspatchen för ptrace (SYSEMU).
    SYSEMU Àr en prestandapatch som introducerades av Laurent Vivier. Den Àndrar
    beteendet hos ptrace() och hjÀlper till att minska vÀrdkontextvÀxlingshastigheter.
    För att fÄ det att fungera behöver du ocksÄ en kÀrnpatch för din vÀrd.
    Se http://perso.wanadoo.fr/laurent.vivier/UML/ för mer information.

uml_dir=
    Platsen för att placera pid- och umid-filerna.

quiet
    StÀnger av informationsmeddelanden under uppstart.

hostfs=,,...
    Detta anvÀnds för att stÀlla in hostfs-parametrar. Rotkatalogargumentet
    anvÀnds för att begrÀnsa alla hostfs-mounts till den specificerade katalog
    trÀdet pÄ vÀrden. Om detta inte anges, kan en anvÀndare inuti UML
    montera vad som helst pÄ vÀrden som Àr Ätkomligt för anvÀndaren som kör
    den. Den enda flagga som för nÀrvarande stöds Àr 'append', vilket anger att alla
    filer som öppnas av hostfs kommer att öppnas i append-lÀge.

Detta banner belyser de grundlÀggande startparametrarna. LÄt oss starta kÀrnan med den minimi nödvÀndiga uppsÀttningen av alternativ:

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

Raderna ovan anger för vÄr kÀrna följande:

  • Anta att rotfilsystemet Ă€r en pseudoadapter. /dev/root.
  • VĂ€lj hostfs som en drivrutin för rotfilssystemet.
  • Montera gĂ€stfilssystemet som vi skapade pĂ„ rot-enheten.
  • Och ja, i lĂ€s-och-skriv-lĂ€ge.
  • AnvĂ€nd endast 64 megabyte RAM (du kan anvĂ€nda mycket mindre, beroende pĂ„ vad du planerar att göra, men 64 MB verkar vara en optimal mĂ€ngd).
  • KĂ€rnan startar automatiskt /bin/sh som init-process.

Kör detta kommando, och du bör fÄ nÄgot i stil med följande:

En till strÀcka

KÀrnedumpgrÀnser :
        mjuk - 0
        hÄrd - INGEN
Kontrollerar att ptrace kan Àndra systemanropsnummer...OK
Kontrollerar systemanropsemuleringspatch för ptrace...OK
Kontrollerar avancerad systemanropsemuleringspatch för ptrace...OK
Kontrollerar miljövariabler för en tempdir...inga funna
Kontrollerar om /dev/shm Àr pÄ tmpfs...OK
Kontrollerar PROT_EXEC mmap i /dev/shm...OK
LÀgger till 32137216 byte till fysisk minne för att ta hÀnsyn till exec-shield-gap
Linux-version 5.1.16 (cadey@kahless) (gcc-version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Sön 7 Jul 18:57:19 UTC 2019
Byggde 1 zonlistor, mobilitetsgruppering pÄ.  Totalt sidor: 23898
KĂ€rnkommandorad: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh
Dentry-cache hash-tabellposter: 16384 (ordning: 5, 131072 byte)
Inode-cache hash-tabellposter: 8192 (ordning: 4, 65536 byte)
Minnes: 59584K/96920K tillgÀngligt (2692K kÀrnkod, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reserverat, 0K cma-reserverat)
SLUB: HWalign=64, Ordning=0-3, MinObjects=0, CPUer=1, Noder=1
NR_IRQS: 15
klockkÀlla: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Kalibrerar fördröjningsloop... 7479.29 BogoMIPS (lpj=37396480)
pid_max: standard: 32768 minimum: 301
Monteringscache hash-tabellposter: 512 (ordning: 0, 4096 byte)
Montagepunkt-cache hash-tabellposter: 512 (ordning: 0, 4096 byte)
Kontrollerar att vÀrdena för vÀrdena ptys stödjer utdata SIGIO...Ja
Kontrollerar att vÀrdena för vÀrdena ptys stödjer SIGIO vid stÀngning...Nej, aktiverar workaround
devtmpfs: initierad
slumrande: get_random_bytes anropades frÄn setup_net+0x48/0x1e0 med crng_init=0
AnvÀnder 2.6 vÀrd AIO
klockkÀlla: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash-tabellposter: 256 (ordning: 0, 6144 byte)
NET: Registrerade protokollfamilj 16
klockkÀlla: VÀxlat till klockkÀlla timer
NET: Registrerade protokollfamilj 2
tcp_listen_portaddr_hash hash-tabellposter: 256 (ordning: 0, 4096 byte)
TCP etablerad hash-tabellposter: 1024 (ordning: 1, 8192 byte)
TCP bind hash-tabellposter: 1024 (ordning: 1, 8192 byte)
TCP: Hash-tabeller konfigurerade (etablerad 1024 bind 1024)
UDP hash-tabellposter: 256 (ordning: 1, 8192 byte)
UDP-Lite hash-tabellposter: 256 (ordning: 1, 8192 byte)
NET: Registrerade protokollfamilj 1
konsol [stderr0] inaktiverad
mconsole (version 2) initierad pÄ /home/cadey/.uml/tEwIjm/mconsole
Kontrollerar stöd för host MADV_REMOVE...OK
workingset: timestamp_bits=62 max_order=14 bucket_order=0
Blocklager SCSI generell (bsg) drivrutin version 0.4 laddad (major 254)
io schemalÀggare noop registrerad (standard)
io schemalÀggare bfq registrerad
loop: modul laddad
NET: Registrerade protokollfamilj 17
Initierad stdio konsol drivrutin
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 1 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 2 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 3 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 4 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 5 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 6 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 7 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 8 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 9 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 10 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 11 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 12 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 13 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 14 : Konfiguration misslyckades
AnvÀnder en kanaltyp som Àr konfigurerad utanför UML
setup_one_line misslyckades för enhet 15 : Konfiguration misslyckades
Konsolen initierad pÄ /dev/tty0
konsol [tty0] aktiverad
konsol [mc-1] aktiverad
Misslyckades med att initiera ubd-enhet 0 : Kunde inte bestÀmma storleken pÄ enhetens fil
VFS: Monterade rot (hostfs-filsystem) pÄ enhet 0:11.
devtmpfs: monterad
Denna arkitektur har ingen kÀrnminnesskydd.
Kör /bin/sh som init-process
/bin/sh: kan inte komma Ät tty; jobbkontroll avstÀngd
slumrande: snabb init klart
/ # 

Manipulationerna ovan ger oss ett minimalt gÀstsystem, utan sÄdana saker som /proc eller tilldelat vÀrdnamn. Som exempel, prova att köra följande kommandon:

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

För att lÀmna gÀstsystemet, skriv exit eller tryck control-d. Detta kommer att avsluta skalet med en följande 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 fick denna kernel panic eftersom Linux-kÀrnan anser att initieringsprocessen alltid körs. Utan den kan systemet inte fungera lÀngre och stÀnger ner. Men eftersom detta Àr en process i anvÀndarlÀge, skickar den erhÄllna resultaten tillbaka till SIGABRT, vilket resulterar i utgÄng.

Konfigurera gÀstnÀtverket

Det Àr hÀr saker börjar gÄ snett. NÀtverket i User Mode Linux Àr den plats dÀr hela konceptet av det begrÀnsade 'anvÀndarlÀget' börjar falla isÀr. Vanligtvis Àr nÀtverket pÄ systemnivÄ begrÀnsat av privilegierade exekveringslÀgen av alla kÀnda skÀl.

Not. anm.: mer om olika sÀtt att arbeta med nÀtverket i UML gÄr att lÀsa hÀr.

En resa in i slirp

Det finns dock ett gammalt och praktiskt taget ounderstödd verktyg som kallas Slirp, med vilket User Mode Linux kan interagera med nĂ€tverket. Det fungerar ungefĂ€r som ett TCP/IP-stack pĂ„ anvĂ€ndarnivĂ„ och krĂ€ver inga systembehörigheter för att köra. Det hĂ€r verktyget slĂ€pptes 1995, och den senaste uppdateringen Ă€r frĂ„n 2006.Slirp Ă€r vĂ€ldigt gammal. Under tiden utan stöd och uppdateringar har kompilatorer kommit sĂ„ lĂ„ngt att detta verktyg nu bara kan karaktĂ€riseras som ‘code rot’.

SÄ lÄt oss installera Slirp frÄn Ubuntu-repositorierna och försöka köra det:

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

Copyright (c) 1995, 1996 Danny Gasparovski och andra.
Alla rÀttigheter förbehÄllna.
Detta program Àr copyrightat, fri programvara.
VÀnligen lÀs filen COPYRIGHT som medföljde Slirp
paketet för villkoren och förutsÀttningarna för upphovsrÀtten.

IP-adress för Slirp-vÀrden: 127.0.0.1
IP-adressen för dina DNS:er: 1.1.1.1, 10.77.0.7
Din adress Àr 10.0.2.15
(eller vad som helst annat du vill)

Skriv fem nollor (0) för att avsluta.

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

SLiRP Ready ...
fisk: “/usr/bin/slirp” avslutat av signal SIGSEGV (AdressgrĂ€nsfel)

Åh, herregud. LĂ„t oss installera en debugger för Slirp och se om vi kan förstĂ„ vad som hĂ€nder:

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.

Felet finns i den hÀr raden. LÄt oss titta pÄ stacktrace, kanske kan det hjÀlpa 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.

HÀr ser vi att felet intrÀffar nÀr den huvudsakliga loopen startas, nÀr slirp försöker kontrollera timeouts. Vid den punkten borde jag ha gett upp med felsökningen. Men lÄt oss se om Slirp, som byggdes frÄn kÀllkoden, fungerar. Jag laddade ner arkivet direkt frÄn webbplatsen Sourceforge, eftersom det Àr besvÀrligt att hÀmta nÄgot dÀrifrÄn via kommandoraden:

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

HÀr ser vi varningar om odefinierade inbyggda funktioner, vilket betyder att det inte gÄr att lÀnka den resulterande binÀra filen. Det verkar som om gcc slutade generera symboler som anvÀnds i inbyggda funktioner för mellan-kompilerade filer mellan 2006 och nu. LÄt oss försöka byta ut nyckelordet inline mot en tom kommentar och se resultatet:

vi slirp.h
:6
a

#define inline /**/

:wq
make

Nej. Det fungerar inte heller. Jag kan fortfarande inte hitta tecknen för dessa funktioner.

Vid det hÀr laget gav jag upp och började söka pÄ Github. byggpaket för Heroku.. Min teori var att det skulle finnas nödvÀndiga binÀrfiler i nÄgot byggpaket för Heroku. Till slut ledde sökandet mig hit.. Jag laddade ner och packade upp uml.tar.gz. och hittade följande:

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*

Detta Àr binÀrfilen slirp! Men fungerar den?

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

Copyright (c) 1995,1996 Danny Gasparovski och andra.
Alla rÀttigheter förbehÄllna.
Detta program Àr upphovsrÀttsskyddat, gratis programvara.
VÀnligen lÀs filen COPYRIGHT som följde med Slirp
paketet för villkor och bestÀmmelser för upphovsrÀtten.

IP-adress för Slirp-vÀrden: 127.0.0.1
IP-adress för dina DNS: 1.1.1.1, 10.77.0.7
Din adress Àr 10.0.2.15
(eller nÄgot annat du vill)

Skriv fem nollor (0) för att avsluta.

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

SLiRP Klar ...

Den kraschar inte — sĂ„ det borde fungera! LĂ„t oss lĂ€gga in denna binĂ€r i ~\/bin\/slirp.:

cp slirp ~\/bin\/slirp.

För att skydda mig om paketets skapare tar bort det, har jag gjort en spegel..

NÀtverksinstÀllning.

Nu ska vi konfigurera nÀtverket pÄ vÄr gÀstkÀrna. Vi uppdaterar startparametrarna.:

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

Nu lÄt oss aktivera nÀtverket:

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.

De första tvÄ konfigurationskommandona /proc och /sys Àr nödvÀndiga för att fungera. ifconfig, vilket upprÀttar nÀtverksgrÀnssnittet för kommunikation med Slirp. Kommandot route upprÀttar kÀrnans routingtabell för att dirigera all trafik genom tunneln Slirp. LÄt oss testa detta med en DNS-förfrÄgan:

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

Det fungerar!

Obs. Enligt vad som verkar ha skrivits, den ursprungliga posten, pÄ en stationÀr dator med en trÄdbunden nÀtverksadapter, eller nÄgon annan konfiguration som inte krÀver extra drivrutiner. En bÀrbar dator med WiFi 8265 frÄn Intel ger dock ett fel nÀr nÀtverket aktiveras.

/ # 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 verkar som om kÀrnan inte kan ansluta till nÀtverksdrivrutinen. TyvÀrr rÀttade ett försök att kompilera firmware till kÀrnan inte situationen. Vid tidpunkten för publiceringen har en lösning Ànnu inte kunnat hittas i denna konfiguration. I enklare konfigurationer (t.ex. i Virtualbox) startar grÀnssnittet korrekt.

LÄt oss automatisera omdirigeringen med hjÀlp av följande shell-skript:

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

Och lÄt oss markera det som exekverbart:

chmod +x init.sh

Och sedan gör vi Àndringar i kommandoraden för kÀrnan:

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

Och vi upprepar:

SLiRP Ready ...
nÀtverket Àr upprÀttat
\/bin\/sh: kan inte fÄ Ätkomst till tty; jobbkontroll avstÀngd

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

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

NĂ€tverket fungerar stabilt!

Docker-fil

För att göra det lÀttare för dig att kontrollera allt detta har jag samlat Dockerfile, som automatiserar de flesta av de beskrivna stegen och bör ge dig en fungerande konfiguration. Jag har Àven en fÀrdig kÀrnkonfiguration, som innehÄller allt som beskrivs i inlÀgget. Men det Àr viktigt att förstÄ att jag hÀr har redogjort för endast den minimiella instÀllningen.

Jag hoppas att detta inlÀgg har hjÀlpt dig att förstÄ hur man startar en gÀstkÀrna. Det blev nÄgon slags monster, men syftet med publiceringen var att fungera som en omfattande guide om byggande, installation och konfiguration av User Mode i Linux för moderna versioner av operativsystem i denna familj. Efterföljande ÄtgÀrder bör inkludera installation av tjÀnster och annan programvara redan inuti gÀstsystmet. Eftersom Docker-containerbilder bara Àr extraherade tar-arkiv, borde du kunna extrahera bilden genom docker export, och sedan ange installationsvÀgen i rotkatalogen för gÀstkÀrnan. SÄ, utför shell-skriptet.

Ett stort tack till Rkeene med #lobsters pÄ Freenode. Utan hans hjÀlp med att felsöka Slirp skulle jag inte ha kommit sÄ hÀr lÄngt. Jag har ingen aning om hur hans Slackware-system fungerar korrekt med slirp, men mina Ubuntu- och Alpine-system accepterade inte slirp och den Rkeene-binary som föreslogs för mig. Men det Àr tillrÀckligt för mig att nÄgot fungerar.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster