So starten Sie den Benutzermodus unter Linux

Einführung des Übersetzers: Vor dem Hintergrund des massiven Eintritts verschiedener Arten von Containern in unser Leben kann es sehr interessant und nützlich sein, herauszufinden, mit welchen Technologien alles einmal begonnen hat. Einige von ihnen können bis heute verwendet werden, aber nicht jeder erinnert sich an solche Methoden (oder weiß, ob sie während ihrer schnellen Entwicklung nicht gefunden wurden). Eine solche Technologie ist User Mode Linux. Der Autor des Originals kramte ziemlich herum, fand heraus, was von den alten Entwicklungen noch funktionierte und was nicht sehr viel, und sammelte so etwas wie eine Schritt-für-Schritt-Anleitung, wie ich in 2k19 selbstgebaute UML in 2k19 starten kann. Und ja, wir haben den Autor des ursprünglichen Cadey- Beitrags nach Habr eingeladen. Wenn Sie also Fragen haben, fragen Sie in den Kommentaren auf Englisch.

Bild

Der Linux-Benutzermodus ist in der Tat der Linux-Kernel-Port selbst. In diesem Modus können Sie einen vollwertigen Linux-Kernel als Benutzerprozess ausführen und werden normalerweise von Entwicklern zum Testen von Treibern verwendet. Dieser Modus eignet sich aber auch als Werkzeug für die allgemeine Isolation, deren Prinzip dem Betrieb virtueller Maschinen ähnelt. Dieser Modus bietet mehr Isolation als Docker, jedoch weniger als eine vollwertige virtuelle Maschine wie KVM oder Virtual Box.

Im Allgemeinen mag der Benutzermodus seltsam und schwierig zu verwenden erscheinen, hat aber immer noch seine eigenen Anwendungsbereiche. Immerhin ist dies ein vollwertiger Linux-Kernel, der von einem nicht privilegierten Benutzer aus arbeitet. Mit dieser Funktion können Sie möglicherweise nicht vertrauenswürdigen Code ausführen, ohne den Host-Computer zu gefährden. Und da es sich um einen vollwertigen Kernel handelt, sind seine Prozesse vom Host-Computer isoliert, dh die im Benutzermodus ausgeführten Prozesse sind für den Host nicht sichtbar . Dies ist nicht wie der übliche Docker-Container. In diesem Fall sieht der Host-Computer immer die Prozesse im Repository. Schauen Sie sich dieses Stück pstree von einem meiner Server an:

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

Und vergleichen Sie dies mit dem pstree Linux-Kernel im Benutzermodus:

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

Wenn ich mit Docker-Containern arbeite, kann ich die Namen der Prozesse sehen, die auf dem Gastsystem vom Host ausgeführt werden. Im Linux-Benutzermodus ist dies nicht möglich. Was bedeutet das? Dies bedeutet, dass bei Überwachungstools, die über das Linux-Überwachungssubsystem arbeiten , keine Prozesse auf dem Gastsystem ausgeführt werden. In einigen Situationen kann diese Funktion jedoch zu einem zweischneidigen Schwert werden.

Im Allgemeinen besteht der gesamte nachstehende Beitrag aus einer Reihe von Studien und unhöflichen Versuchen, das gewünschte Ergebnis zu erzielen. Dazu musste ich verschiedene alte Tools verwenden, die Kernelquellen lesen, den Code, der bereits in der Grundschule geschrieben wurde, intensiv debuggen und Heroku-Assemblys mithilfe eines speziellen Binars auf der Suche nach den benötigten Tools durchsuchen. All diese Arbeit hat die Leute in meinem IRC dazu gebracht, mich Magie zu nennen. Ich hoffe, dass dieser Beitrag als zuverlässige Dokumentation für jemanden dient, um alles gleich zu machen, aber mit neueren Kerneln und Betriebssystemversionen.

Anpassung


Das Einrichten des Linux-Benutzermodus umfasst mehrere Schritte:

  • Installieren von Abhängigkeiten auf dem Host;
  • Herunterladen des Linux-Kernels
  • Kernel Assembly Setup;
  • Kernel-Assembly;
  • binäre Installation;
  • Einrichten des Gastdateisystems;
  • Auswahl der Kernel-Startparameter;
  • Gastnetzwerk einrichten;
  • Starten des Gastkerns.

Ich gehe davon aus, dass Sie, wenn Sie sich dazu entschließen, alles selbst anzukurbeln, höchstwahrscheinlich alles tun werden, was in einem Ubuntu- oder Debian-ähnlichen System beschrieben ist. Ich habe versucht, all das in meiner Lieblingsdistribution - Alpine - zu implementieren, aber es kam nichts dabei heraus, anscheinend, weil der Linux-Kernel eine enge Bindung zu Glibc-Ismen für Treiber im Benutzermodus hatte. Ich habe vor, dies dem Upstream zu melden, nachdem ich das Problem endlich herausgefunden habe.

Installieren Sie Abhängigkeiten auf dem Host


Ubuntu benötigt mindestens die folgenden Pakete, um den Linux-Kernel zu erstellen (vorausgesetzt, eine Neuinstallation):

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


Sie können sie mit dem folgenden Befehl installieren (mit Root-Rechten oder mit sudo):

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

Beachten Sie, dass zum AusfĂĽhren des MenĂĽ-Setup-Programms fĂĽr den Linux-Kernel libncurses-dev installiert werden libncurses-dev . Stellen Sie sicher, dass es mit dem folgenden Befehl installiert wird (mit Root-Rechten oder mit sudo):

 apt-get -y install libncurses-dev 

Kernel herunterladen


Bestimmen Sie den Ort fĂĽr das Laden und die anschlieĂźende Montage des Kernels. FĂĽr diesen Vorgang mĂĽssen Sie etwa 1,3 GB Festplattenspeicher zuweisen. Stellen Sie daher sicher, dass Sie ĂĽber einen verfĂĽgen.

Gehen Sie dann zu kernel.org und rufen Sie die URL ab, um die neueste stabile Kernelversion herunterzuladen. Zum Zeitpunkt des Schreibens dieses Beitrags: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Laden Sie diese Datei mit 'wget' herunter:

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

Und extrahieren Sie es mit 'tar' :

 tar xJf linux-5.1.16.tar.xz 

Jetzt geben wir das Verzeichnis ein, das beim Auspacken des Tarballs erstellt wurde:

 cd linux-5.1.16 

Kernel-Build-Konfiguration


Das Kernel-Build-System ist eine Sammlung von Makefiles mit vielen benutzerdefinierten Tools und Skripten zur Automatisierung des Prozesses. Öffnen Sie zunächst das Online-Setup-Programm:

 make ARCH=um menuconfig 

Die Montage wird teilweise abgeschlossen und ein Dialogfeld für Sie angezeigt. Wenn unten im Fenster ' [Select] ' angezeigt wird, können Sie die Konfiguration mit den Leertasten oder der Eingabetaste vornehmen. Navigation im Fenster wie gewohnt mit den Aufwärts- und Abwärtspfeilen der Tastatur und der Auswahl der Elemente - „links“ oder „rechts“.

Ein Ansichtszeiger ---> bedeutet, dass Sie sich in einem UntermenĂĽ befinden, auf das Sie mit der Eingabetaste zugreifen. Der Ausweg fĂĽhrt offensichtlich ĂĽber ' [Exit] '.

FĂĽgen Sie die folgenden Parameter in ' [Select] ' ein und stellen Sie sicher, dass sich neben ihnen ein '[*]' Symbol befindet:

 UML-specific Options: - Host filesystem Networking support (enable this to get the submenu to show up): - Networking options: - TCP/IP Networking UML Network devices: - Virtual network device - SLiRP transport 

Alles aus diesem Fenster kann durch sequentielle Auswahl von ' [Exit] ' beendet werden. Stellen Sie einfach sicher, dass Sie am Ende aufgefordert werden, die Konfiguration zu speichern, und wählen Sie " [Yes] ".

Ich empfehle, dass Sie nach dem Lesen dieses Beitrags mit den Kernel-Build-Optionen herumspielen. Dank dieser Experimente können Sie viel lernen, um die Arbeit der Kernelmechanik auf niedriger Ebene und den Einfluss verschiedener Flags auf ihre Assemblierung zu verstehen.

Kernel-Assembly


Der Linux-Kernel ist ein großartiges Programm, das viele Dinge tut. Selbst bei einer derart minimalen Konfiguration alter Geräte kann die Montage einige Zeit dauern. Erstellen Sie daher den Kernel mit dem folgenden Befehl:

 make ARCH=um -j$(nproc) 

Warum? Dieser Befehl weist unseren Assembler an, alle verfügbaren Kerne und Prozessorthreads während des Erstellungsprozesses zu verwenden. Der $(nproc) am Ende von Build ersetzt die Ausgabe des nproc , der Teil von coreutils im Standard-Ubuntu-Build ist.

Nach einiger Zeit wird unser Kernel in eine ausfĂĽhrbare ./linux kompiliert.

Binäre Installation


Da der Benutzermodus unter Linux eine reguläre Binärdatei erstellt, können Sie diese wie jedes andere Dienstprogramm installieren. So habe ich es gemacht:

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

Es lohnt sich auch zu ĂĽberprĂĽfen, ob ~/bin in Ihrem $PATH :

 export PATH=$PATH:$HOME/bin 

Einrichten des Gastdateisystems


Erstellen Sie ein Verzeichnis fĂĽr das Gastdateisystem:

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

Ă–ffnen Sie alpinelinux.org und finden Sie im Download-Bereich den aktuellen Link zum Herunterladen von MINI ROOT FILESYSTEM . Zum Zeitpunkt dieses Schreibens war es:

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

Laden Sie diesen Tarball mit wget herunter:

 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 

Geben Sie nun das Verzeichnis des Gastdateisystems ein und entpacken Sie das Archiv:

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

Mit den beschriebenen Schritten wird eine kleine Dateisystemvorlage erstellt. Aufgrund der Art des Systems ist die Installation von Paketen über den Alpine Apk Manager äußerst schwierig. Dieser FS wird jedoch ausreichen, um die allgemeine Idee zu bewerten.

Wir benötigen auch das tini- Tool, um den Speicherverbrauch durch die Zombie-Prozesse unseres Gastkerns zu unterdrücken.

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

Erstellen einer Kernel-Befehlszeile


Der Linux-Kernel verfĂĽgt wie die meisten anderen Programme ĂĽber Befehlszeilenargumente, auf die durch Angabe des Schalters --help zugegriffen werden kann.

Sam - Hilfe
 linux --help User Mode Linux v5.1.16 available at http://user-mode-linux.sourceforge.net/ --showconfig Prints the config file that this UML binary was generated from. iomem=<name>,<file> Configure <file> as an IO memory region named <name>. mem=<Amount of desired ram> This controls how much "physical" memory the kernel allocates for the system. The size is specified as a number followed by one of 'k', 'K', 'm', 'M', which have the obvious meanings. This is not related to the amount of memory in the host. It can be more, and the excess, if it's ever used, will just be swapped out. Example: mem=64M --help Prints this message. debug this flag is not needed to run gdb on UML in skas mode root=<file containing the root fs> This is actually used by the generic kernel in exactly the same way as in any other kernel. If you configure a number of block devices and want to boot off something other than ubd0, you would use something like: root=/dev/ubd5 --version Prints the version number of the kernel. umid=<name> This is used to assign a unique identity to this UML machine and is used for naming the pid file and management console socket. con[0-9]*=<channel description> Attach a console or serial line to a host channel. See http://user-mode-linux.sourceforge.net/old/input.html for a complete description of this switch. eth[0-9]+=<transport>,<options> Configure a network device. aio=2.4 This is used to force UML to use 2.4-style AIO even when 2.6 AIO is available. 2.4 AIO is a single thread that handles one request at a time, synchronously. 2.6 AIO is a thread which uses the 2.6 AIO interface to handle an arbitrary number of pending requests. 2.6 AIO is not available in tt mode, on 2.4 hosts, or when UML is built with /usr/include/linux/aio_abi.h not available. Many distributions don't include aio_abi.h, so you will need to copy it from a kernel tree to your /usr/include/linux in order to build an AIO-capable UML nosysemu Turns off syscall emulation patch for ptrace (SYSEMU). SYSEMU is a performance-patch introduced by Laurent Vivier. It changes behaviour of ptrace() and helps reduce host context switch rates. To make it work, you need a kernel patch for your host, too. See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information. uml_dir=<directory> The location to place the pid and umid files. quiet Turns off information messages during boot. hostfs=<root dir>,<flags>,... This is used to set hostfs parameters. The root directory argument is used to confine all hostfs mounts to within the specified directory tree on the host. If this isn't specified, then a user inside UML can mount anything on the host that's accessible to the user that's running it. The only flag currently supported is 'append', which specifies that all files opened by hostfs will be opened in append mode. 


Dieses Banner beleuchtet die Hauptstartoptionen. Lassen Sie uns den Kernel mit den minimal erforderlichen Optionen ausfĂĽhren:

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

Die obigen Zeilen sagen unserem Kern Folgendes:

  • Angenommen, das Root-Dateisystem ist das Pseudogerät /dev/root .
  • Wählen Sie hostfs als Root-Dateisystemtreiber.
  • Hängen Sie das Gastdateisystem ein, das wir auf dem Root-Gerät erstellt haben.
  • Und ja, im Lese- / Schreibmodus.
  • Verwenden Sie nur 64 Megabyte RAM (Sie können viel weniger verwenden, je nachdem, was Sie vorhaben, aber 64 MB scheinen die optimale Größe zu sein).
  • Der Kernel startet /bin/sh automatisch als init Prozess.

FĂĽhren Sie diesen Befehl aus, und Sie sollten Folgendes erhalten:

Noch ein Blatt
 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 / # 


Wenn Sie das oben Gesagte manipulieren, erhalten wir mindestens ein Gastsystem , ohne Dinge wie /proc oder einen zugewiesenen Hostnamen. Versuchen Sie beispielsweise die folgenden Befehle:

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


Geben Sie zum Beenden des Gastsystems exit oder drĂĽcken Sie Strg-d. Dies wird die Shell abschieĂźen, gefolgt von Kernel-Panik:

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

Wir haben diese Kernel-Panik, weil der Linux-Kernel glaubt, dass der Initialisierungsprozess immer läuft. Ohne sie kann das System nicht mehr funktionieren und fährt herunter. Da dies jedoch ein Prozess im Benutzermodus ist, sendet sich das Ergebnis an SIGABRT , was zum Beenden führt.

Gastnetzwerk einrichten


Und hier bei uns läuft alles nicht nach Plan. Im Netzwerk im Benutzermodus Linux beginnt das gesamte Konzept eines eingeschränkten „Benutzermodus“ auseinanderzufallen. Schließlich ist das Netzwerk normalerweise auf Systemebene aus allen von uns eindeutigen Gründen auf privilegierte Ausführungsmodi beschränkt.

Hinweis trans.: Weitere Informationen zu den verschiedenen Optionen fĂĽr die Arbeit mit dem Netzwerk in UML finden Sie hier .

Reise zum Slirp


Es gibt jedoch ein altes und fast nicht unterstütztes Tool namens Slirp , mit dem Linux im Benutzermodus mit dem Netzwerk interagieren kann. Es funktioniert ungefähr wie ein TCP / IP-Stack auf Benutzerebene und erfordert keine Systemberechtigungen, um ausgeführt zu werden. Dieses Tool wurde 1995 veröffentlicht und das neueste Update stammt aus dem Jahr 2006 . Slirp ist sehr alt. Für eine Zeit ohne Support und Updates sind Compiler so weit gegangen, dass dieses Tool nur noch als „Code Rot“ bezeichnet werden kann .

Lassen Sie uns also Slirp aus den Ubuntu-Repositories rollen und versuchen, es auszufĂĽhren:

 sudo apt-get install slirp /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 ... fish: “/usr/bin/slirp” terminated by signal SIGSEGV (Address boundary error) 

Oh Götter. Lassen Sie uns einen Debugger für Slirp installieren und sehen, ob wir herausfinden können, was hier vor sich geht:

 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 <http://gnu.org/licenses/gpl.html> 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: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. 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. 

Der Fehler schlägt in dieser Zeile . Schauen wir uns Stacktrace an, vielleicht hilft uns dort etwas:

 (gdb) bt full #0 ip_slowtimo () at ip_input.c:457 fp = 0x55784a40 #1 0x000055555556a57c in main_loop () at ./main.c:980 so = <optimized out> so_next = <optimized out> timeout = {tv_sec = 0, tv_usec = 0} ret = 0 nfds = 0 ttyp = <optimized out> ttyp2 = <optimized out> best_time = <optimized out> tmp_time = <optimized out> #2 0x000055555555b116 in main (argc=1, argv=0x7fffffffdc58) at ./main.c:95 No locals. 

Hier sehen wir, dass ein Fehler beim Start der Hauptschleife auftritt, wenn slirp versucht, ZeitĂĽberschreitungen zu ĂĽberprĂĽfen. Zu diesem Zeitpunkt musste ich den Versuch des Debuggens aufgeben. Aber mal sehen, ob Slirp, das aus Sortierungen kompiliert wurde, funktioniert. Ich habe das Archiv direkt von der Sourceforge- Website neu geladen, da das Ziehen von dort ĂĽber die Befehlszeile schmerzhaft ist:

 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 

Hier sehen wir Warnungen über undefinierte integrierte Funktionen, dh über die Unmöglichkeit, die resultierende Binärdatei zu verknüpfen. Es scheint, dass gcc zwischen 2006 und diesem Moment aufgehört hat, Zeichen zu erstellen, die in den integrierten Funktionen von kompilierten Zwischendateien verwendet werden. Versuchen wir, das inline durch einen leeren Kommentar zu ersetzen, und sehen wir uns das Ergebnis an:

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

Nein. Dies funktioniert auch nicht. Sie können die Zeichen für diese Funktionen immer noch nicht finden.

Zu diesem Zeitpunkt gab ich auf und suchte nach Heroku-Build-Paketen auf Github. Meine Theorie basierte auf der Tatsache, dass einige Heroku-Build-Pakete die Binärdateien enthalten, die ich benötige. Infolgedessen führte mich die Suche hierher . Ich habe uml.tar.gz heruntergeladen und entpackt und Folgendes gefunden:

 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* 

Dies ist eine binäre Slirp-Datei! Arbeitet er

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

Stürzt nicht ab - also sollte es funktionieren! Lassen Sie uns diese Binärdatei in ~/bin/slirp :

 cp slirp ~/bin/slirp 

FĂĽr den Fall, dass der Ersteller des Pakets es entfernt, habe ich einen Spiegel gemacht .

Netzwerkeinrichtung


Jetzt richten wir das Netzwerk auf unserem Gastkern ein. Startoptionen aktualisieren :

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

Jetzt schalten wir das Netzwerk ein:

 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 

Die ersten beiden Konfigurationsbefehle /proc und /sys benötigt, damit ifconfig funktioniert. Dadurch wird eine Netzwerkschnittstelle für die Kommunikation mit Slirp eingerichtet. Der Befehl route richtet eine Kernel-Routing-Tabelle ein, um den gesamten Datenverkehr durch den Slirp-Tunnel zu erzwingen. Lassen Sie uns dies mit einer DNS-Abfrage überprüfen:

 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 

Es funktioniert!

Hinweis: Anscheinend wurde der ursprüngliche Beitrag mit einer kabelgebundenen Netzwerkkarte oder einer anderen Konfiguration, für die keine zusätzlichen Treiber erforderlich sind, auf dem Desktop geschrieben. Auf einem Laptop mit WiFi 8265 von Intel tritt beim Erhöhen des Netzwerks ein Fehler auf

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

Anscheinend kann der Kernel nicht mit dem Netzwerktreiber kommunizieren. Ein Versuch, Firmware in den Kernel zu kompilieren, konnte die Situation leider nicht beheben. Zum Zeitpunkt der Veröffentlichung war es in dieser speziellen Konfiguration nicht möglich, eine Lösung zu finden. Bei einfacheren Konfigurationen (z. B. in Virtualbox) steigt die Schnittstelle korrekt an.

Lassen Sie uns die Umleitung mithilfe des folgenden Shell-Skripts automatisieren:

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

Und markieren Sie es als ausfĂĽhrbar:

 chmod +x init.sh 

Nehmen Sie dann Änderungen an der Kernel-Befehlszeile vor:

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

Und wiederhole:

 SLiRP Ready ... networking set up /bin/sh: can't access tty; job control turned off nslookup google.com 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 dns.google Name: google.com Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net Address 2: 2607:f8b0:4004:800::200e iad30s09-in-x0e.1e100.net 

Das Netzwerk ist stabil!

Docker-Datei


, Dockerfile , . , , . , .



, , . - , , User Mode Linux . . Docker — tar-, docker export , . , shell-.

Rkeene #lobsters Freenode. Slirp . , Slackware slirp, Ubuntu Alpine slirp Rkeene . , -.

Source: https://habr.com/ru/post/de459558/


All Articles