Indledning fra oversætteren: I takt med den massive indtræden af forskellige containere i vores liv kan det være interessant og nyttigt at kende de teknologier, som dette hele engang startede med. Nogle af dem kan stadig med fordel anvendes den dag i dag, men ikke alle husker (eller ved, hvis de ikke oplevede dem under deres hastige udvikling) sådanne metoder. En af disse teknologier er User Mode Linux. Forfatteren af originalen har gravet dybt for at finde ud af, hvilke af de gamle idéer der stadig fungerer, og hvad der ikke gør, og har samlet noget, der ligner en trin-for-trin guide til, hvordan man selv kan få en hjemmelavet UML i 2k19. Og ja, vi har inviteret forfatteren af det originale indlæg til Habr. , så hvis der er spørgsmål - så spørg på engelsk i kommentarerne.

User Mode i Linux er i virkeligheden en port af Linux-kernen til sig selv. Denne tilstand gør det muligt at køre en fuld fungerende Linux-kerne som en brugerproces og bruges normalt af udviklere til at teste drivere. Men denne tilstand er også nyttig som et generelt isoleringsværktøj, hvis princip er sammenligneligt med, hvordan virtuelle maskiner fungerer. Denne tilstand giver større isolation end Docker, men mindre end en fuld virtuel maskine såsom KVM eller Virtual Box.
Generelt kan User Mode virke som et mærkeligt og komplekst værktøj at bruge, men det har alligevel sine anvendelsesområder. For det er en fuld Linux-kerne, der kører under en ikke-privilegeret bruger. Denne funktion giver mulighed for at køre potentielt usikre koder uden nogen trussel mod værtmaskinen. Og da det er en fuld kerne, er dens processer isoleret fra værtmaskinen, det vil sige processerne, der kører inden for User Mode, vil ikke være synlige for værten. Det ligner ikke den velkendte Docker-container, hvor værtmaskinen altid kan se processerne inden for containeren. Se på dette stykke pstree fra en af mine servere:
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 sammenlign dette med pstree i Linux-kernen i brugerens tilstand:
linux─┬─5*[linux]
└─slirpNår jeg arbejder med Docker-containere, kan jeg se procesnavnene, der kører i gæstesystemet fra værten. Dette er ikke muligt med Linux User Mode. Hvad betyder det? Det betyder, at overvågningsværktøjer, der arbejder gennem Linux’s auditing subsystem, ikke ser de processer, der udføres i gæstesystemet. Men i nogle situationer kan denne egenskab blive en tosidet sværd.
Hele indlægget herunder er en samling af undersøgelser og grove forsøg på at opnå det ønskede resultat. Til dette har jeg været nødt til at bruge forskellige gamle værktøjer, læse kildekoden til kernen, foretage intensiv debugging af kode skrevet i en tid, hvor jeg stadig gik i folkeskole, samt nørde rundt i Heroku-builds med et specielt binær i jagten på de værktøjer, jeg havde brug for. Alt dette arbejde har fået drengene i min IRC til at kalde mig en troldkvinde (magic). Jeg håber, at dette indlæg kan tjene som pålidelig dokumentation for nogen, der ønsker at gøre det samme, men allerede med nyere kerner og OS-versioner.
Indstillinger
Opsætning af Linux User Mode sker i flere trin:
- installation af afhængigheder på værten;
- download af Linux-kernen;
- opsætning af kernebuild;
- kompilering af kernen;
- installation af binærfilen;
- opsætning af gæstefilssystemet;
- justering af kernelstartparametre;
- opsætning af gæstenetværket;
- start af gæstekernen.
Jeg antager, at hvis du vælger at klare dette selv, vil du sandsynligvis gøre alt det beskrevne i et eller andet Ubuntu- eller Debian-lignende system. Jeg har forsøgt at implementere alt det ovenfor beskrevne i min yndlingsdistribution — Alpine, men det gik ikke, angiveligt fordi kernel Linux har en rigid binding til glibc-ism'er for drivere i brugerklassen. Jeg planlægger at rapportere dette til upstream, når jeg har helt forstået problemet.
Installation af afhængigheder på værten
Ubuntu kræver mindst følgende pakker for at kompilere kernen i Linux (under forudsætning af en ren installation):
- 'build-essential'
- 'flex'
- 'bison'
- 'xz-utils'
- 'wget'
- 'ca-certificates'
- 'bc'
- 'linux-headers'
Du kan installere dem med følgende kommando (som root eller ved hjælp af sudo):
apt-get -y install build-essential flex bison xz-utils wget ca-certificates bc
linux-headers-$(uname -r) Bemærk, at kørsel af konfigurationsprogrammet til Linux-kernen kræver installation af libncurses-dev. Venligst sikr dig, at det er installeret med følgende kommando (som root eller ved hjælp af sudo):
apt-get -y install libncurses-devDownload af kernen
Bestem, hvor du vil downloade og senere kompilere kernen. Du skal afsætte omkring 1,3 GB plads på harddisken til denne operation, så sørg for, at du har det.
Derefter skal du gå til og få URL'en til at downloade den seneste stabile version af kernen. På tidspunktet for denne skrivning er det:
Download denne fil ved hjælp af 'wget':
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz Og udpak den med 'tar':
tar xJf linux-5.1.16.tar.xzNu går vi ind i den mappe, der blev oprettet ved udpakkingen af tarballen:
cd linux-5.1.16Konfiguration af kernen
Kernens bygge-system er et sæt med mange brugerdefinerede værktøjer og scripts til at automatisere processen. For at starte skal du åbne det interaktive konfigurationsprogram:
make ARCH=um menuconfig Det vil delvist gennemføre kompileringen og vise dig et dialogvindue. Når '[Select]' vises nederst i vinduet, kan du begynde at konfigurere med tasterne mellemrum eller Enter. Navigering i vinduet gøres som sædvanlig med pilene 'op' og 'ned', og markeringen af elementer med 'venstre' eller 'højre'.
En indikator som —> betyder, at du er i en undermenu, som du går ind i ved at trykke på Enter. Udad fra den går du tydeligvis ved at vælge '[Exit]'Aktivér følgende indstillinger i '[Select]' og sørg for, at der er et symbol '[*]' ved siden af dem:‘.
Aktivér følgende indstillinger i ‘[Select]‘ og sørg for, at der er et symbol ‘[*]’ ved siden af dem:
UML-specifikke indstillinger:
- Værtsfilsystem
Netværksunderstøttelse (aktiver dette for at få under-menuen til at vises):
- Netværksindstillinger:
- TCP/IP-netværk
UML-netværksenheder:
- Virtuel netværksenhed
- SLiRP-transport Du kan forlade dette vindue ved at vælge ‘Aktivér følgende indstillinger i '[Select]' og sørg for, at der er et symbol '[*]' ved siden af dem:‘. Bare sørg for, at du til sidst bliver tilbudt at gemme konfigurationen og vælg ‘[Ja]‘.
Jeg anbefaler, at du eksperimenterer med kernelbyggeindstillingerne efter at have læst dette indlæg. Gennem disse eksperimenter kan du lære meget om, hvordan lavniveau mekanismer fungerer i kernen og hvordan forskellige flag påvirker dens bygning.
Kernelbygning
Linux-kernen er et stort program, der håndterer mange ting. Selv med en minimal konfiguration på gammelt hardware kan opbygningen tage betydelig tid. Derfor kan du bygge kernen ved hjælp af følgende kommando:
make ARCH=um -j$(nproc) Hvorfor? Denne kommando fortæller vores byggeprogram at bruge alle tilgængelige kerner og tråde under byggingen. Kommandoen $(nproc) indsætter output fra kommandoen nproc, som er en del af coreutils i den standardinstallation af Ubuntu.
Efter noget tid vil vores kernel blive bygget til en eksekverbar fil ./linux.
Installation af binæren
Da User Mode i Linux opretter en almindelig binær, kan du installere den som enhver anden tjeneste. Her er, hvad jeg gjorde:
mkdir -p ~/bin
cp linux ~/bin/linux Du bør også sikre dig, at ~\/bin er i din $PATH:
export PATH=$PATH:$HOME/binOpsætning af gæste-filsystemet
Opret en mappe til gæste-filsystemet:
mkdir -p $HOME/prefix/uml-demo
cd $HOME/prefix
Gå til alpinelinux.org og i find den aktuelle downloadlink til MINI ROOT FILESYSTEM. På tidspunktet for publiceringen var dette:
http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gzDownload denne tarball ved hjælp af 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.gzNu skal du gå ind i mappen for gæste-filsystemet og udpakke arkivet:
cd uml-demo
tar xf ../alpine-rootfs.tgzDe beskrevne skridt vil oprette et lille skabelon-filsystem. På grund af systemets karakter vil det være ret vanskeligt at installere pakker via apk-pakkestyringssystemet fra Alpine. Men dette filsystem vil være tilstrækkeligt til at vurdere den overordnede idé.
Vi vil også få brug for værktøjet for at stoppe hukommelsesforbruget i vores gæstekernel.
wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static
chmod +x tiniOprettelse af kernelens kommandolinje
I Linux-kernen, ligesom i de fleste andre programmer, er der kommandolinjeargumenter, som kan fås ved at angive nøglen --help.
Selv —help
linux --help
User Mode Linux v5.1.16
tilgængelig på http://user-mode-linux.sourceforge.net/
--showconfig
Udskriver konfigurationsfilen, som denne UML-binærfil blev genereret fra.
iomem=,
Konfigurer som et IO-hukommelsesområde navngivet .
mem=
Dette styrer, hvor meget "fysisk" hukommelse kerne allokerer til systemet. Størrelsen angives som et tal efterfulgt af en af 'k', 'K', 'm', 'M', som har de indlysende betydninger. Dette er ikke relateret til mængden af hukommelse i værten. Det kan være mere, og overskuddet, hvis det nogensinde bruges, vil blot blive byttet ud.
Eksempel: mem=64M
--help
Udskriver denne meddelelse.
debug
dette flag er ikke nødvendigt for at køre gdb på UML i skas-tilstand
root=
Dette bruges faktisk af den generiske kerne på præcis samme måde, som i enhver anden kerne. Hvis du konfigurerer et antal blok-enheder og ønsker at boote fra noget andet end ubd0, ville du bruge noget som:
root=/dev/ubd5
--version
Udskriver versionnummeret på kernen.
umid=
Dette bruges til at tildele en unik identitet til denne UML-maskine og bruges til at navngive pid-filen og administrationskonsolens socket.
con[0-9]*=
Tilslut en konsol eller seriel linje til en værtkanal. Se
http://user-mode-linux.sourceforge.net/old/input.html for en komplet beskrivelse af denne switch.
eth[0-9]+=,
Konfigurer en netværksenhed.
aio=2.4
Dette bruges til at tvinge UML til at bruge 2.4-stil AIO, selv når 2.6 AIO er tilgængelig. 2.4 AIO er en enkelt tråd, der håndterer en anmodning ad gangen, synkront. 2.6 AIO er en tråd, der bruger 2.6 AIO-grænsefladen til at håndtere et vilkårligt antal ventende anmodninger. 2.6 AIO er ikke tilgængelig i tt-tilstand, på 2.4 værter eller når UML er bygget med /usr/include/linux/aio_abi.h ikke tilgængelig. Mange distributioner inkluderer ikke aio_abi.h, så du bliver nødt til at kopiere det fra et kerne-træ til din /usr/include/linux for at bygge en AIO-kapabel UML
nosysemu
Slår syscall-emuleringspatch for ptrace (SYSEMU) fra. SYSEMU er en ydelsespatch, der blev introduceret af Laurent Vivier. Den ændrer adfærden af ptrace() og hjælper med at reducere værts kontekstskiftfrekvens. For at få det til at fungere skal du også have en kerne-patch til din vært. Se http://perso.wanadoo.fr/laurent.vivier/UML/ for yderligere information.
uml_dir=
Placeringen af pid- og umid-filerne.
quiet
Slår informationsmeddelelser fra under boot.
hostfs=,,...
Dette bruges til at sætte hostfs-parametre. Argumentet for rodmappen bruges til at begrænse alle hostfs-mounts til inden for det angivne mappetræ på værten. Hvis dette ikke er angivet, kan en bruger inde i UML montere alt på værten, der er tilgængeligt for den bruger, der kører det.
Den eneste flag, der i øjeblikket understøttes, er 'append', som angiver, at alle filer åbnet af hostfs vil blive åbnet i append-tilstand.Dette dokument belyser de grundlæggende opstartsparametre. Lad os starte kernen med det mindste nødvendige sæt af indstillinger:
linux
root=/dev/root
rootfstype=hostfs
rootflags=$HOME/prefix/uml-demo
rw
mem=64M
init=/bin/shLinjerne ovenfor siger til vores kerne:
- Lad os antage, at rodfilsystemet er en pseudo-enhed
/dev/root. - Vælg som en driver for rodfilsystemet.
- Monter gæstefilsystemet, som vi har oprettet, i root-enheden.
- Og ja, i læsning-skrivning-tilstand.
- Brug kun 64 megabyte RAM (du kan bruge meget mindre, afhængigt af hvad du planlægger at gøre, men 64 MB virker optimalt).
- Kernen starter automatisk
/bin/shhvordaninit-processen.
Kør denne kommando, og du skal få noget som følgende:
En anden blok
Kernekdump begrænsninger :
blød - 0
hård - INGEN
Tjekker om ptrace kan ændre systemopkaldsnumre...OK
Tjekker syscall-emulation patch til ptrace...OK
Tjekker avanceret syscall-emulation patch til ptrace...OK
Tjekker miljøvariabler for en tempdir...ingen fundet
Tjekker om /dev/shm er på tmpfs...OK
Tjekker PROT_EXEC mmap i /dev/shm...OK
Tilføjer 32137216 bytes til fysisk hukommelse for at dække 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øndag den 7. jul 2019 18:57:19 UTC
Bygget 1 zonelister, mobilitetsgruppering aktiveret. Samlet antal sider: 23898
Kernel kommando linje: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh
Dentry cache hash tabel posteringer: 16384 (orden: 5, 131072 bytes)
Inode-cache hash tabel posteringer: 8192 (orden: 4, 65536 bytes)
Hukommelse: 59584K/96920K tilgængelig (2692K kernel kode, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reserveret, 0K cma-reserveret)
SLUB: HWalign=64, Orden=0-3, MinObjects=0, CPUs=1, Noder=1
NR_IRQS: 15
clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Kalibrering af forsinkelse loop... 7479.29 BogoMIPS (lpj=37396480)
pid_max: standard: 32768 minimum: 301
Mount-cache hash tabel posteringer: 512 (orden: 0, 4096 bytes)
Mountpoint-cache hash tabel posteringer: 512 (orden: 0, 4096 bytes)
Tjekker at host ptys understøtter output SIGIO...Ja
Tjekker at host ptys understøtter SIGIO ved lukning...Nej, aktiverer workaround
devtmpfs: initialiseret
random: get_random_bytes kaldt fra setup_net+0x48/0x1e0 med crng_init=0
Brug af 2.6 host AIO
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash tabel posteringer: 256 (orden: 0, 6144 bytes)
NET: Registreret protokol familie 16
clocksource: Skiftet til clocksource timer
NET: Registreret protokol familie 2
tcp_listen_portaddr_hash hash tabel posteringer: 256 (orden: 0, 4096 bytes)
TCP etablerede hash tabel posteringer: 1024 (orden: 1, 8192 bytes)
TCP bind hash tabel posteringer: 1024 (orden: 1, 8192 bytes)
TCP: Hash tabeller konfigureret (etablerede 1024 bind 1024)
UDP hash tabel posteringer: 256 (orden: 1, 8192 bytes)
UDP-Lite hash tabel posteringer: 256 (orden: 1, 8192 bytes)
NET: Registreret protokol familie 1
console [stderr0] deaktiveret
mconsole (version 2) initialiseret på /home/cadey/.uml/tEwIjm/mconsole
Tjekker host MADV_REMOVE support...OK
workingset: timestamp_bits=62 max_order=14 bucket_order=0
Block layer SCSI generisk (bsg) driver version 0.4 indlæst (major 254)
io scheduler noop registreret (standard)
io scheduler bfq registreret
loop: modul indlæst
NET: Registreret protokol familie 17
Initialiseret stdio console driver
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 1 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 2 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 3 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 4 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 5 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 6 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 7 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 8 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 9 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 10 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 11 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 12 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 13 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 14 : Konfiguration mislykkedes
Bruger en kanaltype, der er konfigureret uden for UML
setup_one_line mislykkedes for enhed 15 : Konfiguration mislykkedes
Console initialiseret på /dev/tty0
console [tty0] aktiveret
console [mc-1] aktiveret
Kunne ikke initialisere ubd enhed 0 :Kunne ikke bestemme størrelse af enhedens fil
VFS: Monteret rod (hostfs filsystem) på enhed 0:11.
devtmpfs: monteret
Denne arkitektur har ikke beskyttelse af kernens hukommelse.
Kør /bin/sh som init proces
/bin/sh: kan ikke få adgang til tty; jobkontrol er slået fra
random: hurtig init udført
/ # Manipulationerne ovenfor vil give os et gæstesystem med minimal funktionalitet, uden sådanne ting som /proc eller tildelt værtsnavn. For eksempel, prøv at køre følgende kommandoer:
- uname -av
- cat /proc/self/pid
- hostname
For at afslutte gæstesystemet, indtast sigreturn eller tryk på control-d. Dette vil afslutte shell'en med efterfø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 fik denne kernel panic, fordi Linux-kernen mener, at initialiseringsprocessen altid er aktiv. Uden den kan systemet ikke længere fungere og afslutter driften. Men da dette er en brugergrænseflade-proces, sender det resulterende output sig selv til SIGABRT, hvilket fører til afslutningen.
Konfiguration af gæstenetværk
Men her begynder tingene at gå galt. Netværket i User Mode Linux er det sted, hvor hele konceptet om begrænset 'brugermode' begynder at bryde sammen. Normalt er netværket på systemniveau begrænset af privilegerede kørselsmode af åbenlyse grunde.
Bemærk: mere om forskellige måder at arbejde med netværk i UML kan findes .
Rejsen til slirp
Der findes dog et gammelt og stort set ikke-understøttet værktøj kaldet , ved hjælp af hvilket User Mode Linux kan interagere med netværket. Det fungerer omtrent som et TCP/IP-stak på brugerniveau og kræver ikke nogen systemtilladelser for at køre. Dette værktøj blev udgivet i 1995, og den seneste opdatering var i 2006.Slirp er meget gammelt. I en periode uden understøttelse og opdateringer er compilere gået så langt, at dette værktøj nu kun kan beskrives som .
Så lad os installere Slirp fra Ubuntu-repositories og forsøge at køre det:
sudo apt-get install slirp
/usr/bin/slirp
Slirp v1.0.17 (BETA)
Copyright (c) 1995,1996 Danny Gasparovski med flere.
Alle rettigheder forbeholdes.
Dette program er ophavsretligt beskyttet, gratis software.
Læs venligst filen COPYRIGHT, der følger med Slirp
pakken for betingelserne for ophavsretten.
IP-adresse for Slirp-værten: 127.0.0.1
IP-adresse for dine DNS(e): 1.1.1.1, 10.77.0.7
Din adresse er 10.0.2.15
(eller hvad som helst andet, du ønsker)
Skriv fem nuller (0) for at afslutte.
[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]
SLiRP Klar ...
fisk: "/usr/bin/slirp" afsluttet af signal SIGSEGV (Adressegrænsefejl)Åh, hvad siger du. Lad os installere en debugger til Slirp og se, om vi kan finde ud af, hvad der sker:
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.Fejlen opstår i . Lad os se på stacktrace, måske kan det hjælpe os:
(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 fejlen opstår i starten af hovedløkken, når slirp prøver at kontrollere tidsudløb. Det var i dette øjeblik, jeg burde have opgivet at debugge. Men lad os se, om Slirp, bygget fra kilden, fungerer. Jeg har genaflæst arkivet direkte fra hjemmesiden , fordi det er besværligt at hente noget 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 advarsler om ubekræftede indbyggede funktioner, hvilket betyder, at det resulterende binære fil ikke kan linker. Det ser ud til, at mellem 2006 og nu har gcc holdt op med at oprette symboler, der bruges i indbyggede funktioner for mellemkompilerede filer. Lad os prøve at erstatte nøgleordet inline med en tom kommentar og se hvad resultatet bliver:
vi slirp.h
:6
a
#define inline /**/
:wq
makeNej, det virker stadig ikke. Jeg kan stadig ikke finde tegn på disse funktioner.
På dette tidspunkt gav jeg op og begyndte at lede efter det på Github . Min teori var, at der i et eller andet Heroku build pack ville være de nødvendige binære filer. Til sidst førte mine søgninger mig . Jeg downloadede og udpakkede uml.tar.gz og fandt 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*Det er den binære fil slirp! Men fungerer den?
./slirp
Slirp v1.0.17 (BETA) FULL_BOLT
Copyright (c) 1995,1996 Danny Gasparovski og andre.
Alle rettigheder forbeholdes.
Dette program er copyrightbeskyttet, gratis software.
Læs venligst filen COPYRIGHT, der følger med Slirp
pakken for vilkårene og betingelserne for copyright.
IP-adresse på Slirp-værten: 127.0.0.1
IP-adresse på din(e) DNS: 1.1.1.1, 10.77.0.7
Din adresse er 10.0.2.15
(eller hvad som helst andet, du ønsker)
Indtast fem nuller (0) for at exit.
[autodetect SLIP/CSLIP, MTU 1500, MRU 1500]
SLiRP Klar ...
Den crasher ikke — så det bør virke! Lad os flytte denne binærfil til ~/bin/slirp:
cp slirp ~/bin/slirpI tilfælde af at skaberen af pakken fjerner den, har jeg .
Netværksopsætning
Lad os nu konfigurere netværket på vores gæste-kerne. :
linux
root=/dev/root
rootfstype=hostfs
rootflags=$HOME/prefix/uml-demo
rw
mem=64M
eth0=slirp,,$HOME/bin/slirp
init=/bin/shLad os nu aktivere netværket:
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ørste to konfigurationskommandoer /proc og /sys er nødvendige for at etablere ifconfignetværksgrænsefladen til kommunikation med Slirp. Kommandoen rute opsætter kernerutingen til at tvinge al trafik gennem Slirp-tunnelen. Lad os teste dette med en DNS-forespørgsel:
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.netDet virker!
Obs: Det ser ud til, at det oprindelige indlæg blev skrevet på en desktop med et kablet netværkskort, eller en anden konfiguration, der ikke kræver ekstra drivere. På en bærbar computer med WiFi 8265 fra Intel opstår der dog en fejl ved netværksoprettelsen.
/ # 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 ud til, at kernen ikke kan oprette forbindelse til netværksdriveren. Desværre løste forsøget på at kompilere firmwaren ind i kernen ikke situationen. På tidspunktet for offentliggørelsen har der endnu ikke været fundet en løsning i denne konfiguration. I mere enkle konfigurationer (f.eks. i VirtualBox) aktiveres grænsefladen korrekt.
Lad os automatisere omdirigeringen ved hjælp af 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/shOg lad os gøre det eksekverbart:
chmod +x init.shOg så vil vi foretage ændringer i kernekommandolinjen:
linux
root=\/dev\/root
rootfstype=hostfs
rootflags=$HOME\/prefix\/uml-demo
rw
mem=64M
eth0=slirp,,$HOME\/bin\/slirp
init=\/init.sh
Og vi gentager:
SLiRP Klar ...
netværk opsat
\/bin\/sh: kan ikke få adgang til tty; jobkontrol slået fra
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.netNetværket fungerer stabilt!
Docker-fil
For at gøre det lettere for dig at tjekke det hele, har jeg samlet , som automatiserer de fleste af de beskrevne trin og bør give dig en fungerende konfiguration. Jeg har også en , som indeholder alt, hvad der er beskrevet i indlægget. Men det er vigtigt at forstå, at jeg kun har præsenteret den minimale opsætning her.
Jeg håber, at dette indlæg har hjulpet dig med at forstå, hvordan man opsætter et gæste-kern. Det blev en slags monster, men publikationen var tænkt som en omfattende guide til emnet samling, installation og opsætning af User Mode i Linux under moderne versioner af dette families operativsystemer. De efterfølgende trin bør omfatte installation af tjenester og anden software inden i gæstesystemet. Da Docker-containerbilleder blot er pakket tar-arkiver, skal du være i stand til at udtrække billedet via docker export, og derefter bestemme banen for dens installation i rodmappen for gæstebitkernel. Og derefter køre shell-scriptet.
En særlig tak til Rkeene fra #lobsters på Freenode. Uden hans hjælp til fejlfinding af Slirp ville jeg ikke være kommet så langt. Jeg har ingen idé om, hvordan hans Slackware-system fungerer korrekt med slirp, men mine Ubuntu- og Alpine-systemer accepterede ikke slirp og den Rkeene-binærfil, jeg blev tilbudt. Men jeg er tilfreds med, at jeg har noget, der fungerer.
Kilde: habr.com
