Introducción del traductor: en el contexto de la entrada masiva en nuestras vidas de varios tipos de contenedores, puede ser bastante interesante y útil descubrir con qué tecnologías comenzó todo una vez. Algunos de ellos pueden usarse hasta el día de hoy, pero no todos recuerdan tales métodos (o saben si no fueron encontrados durante su rápido desarrollo). Una de esas tecnologías es User Mode Linux. El autor del original revolvió bastante, averiguando qué de los desarrollos antiguos todavía funcionaba, y qué no era mucho, y recopiló algo como una instrucción paso a paso sobre cómo iniciar UML local en 2k19 para mí. Y sí, invitamos al autor de la publicación original de Cadey a Habr , así que si tiene preguntas, pregunte en inglés en los comentarios.
El modo de usuario de Linux es, de hecho, el puerto del kernel de Linux. Este modo le permite ejecutar un kernel de Linux completo como un proceso de usuario y generalmente lo usan los desarrolladores para probar los controladores. Pero este modo también es útil como herramienta para el aislamiento general, cuyo principio es similar al funcionamiento de las máquinas virtuales. Este modo proporciona más aislamiento que Docker, pero menos que una máquina virtual completa como KVM o Virtual Box.
En general, el modo de usuario puede parecer extraño y difícil de usar, pero aún tiene sus propias áreas de aplicación. Después de todo, este es un núcleo Linux completo, que trabaja desde un usuario sin privilegios. Esta característica le permite ejecutar código potencialmente no confiable sin ninguna amenaza para la máquina host. Y dado que es un kernel completo, sus procesos están aislados de la máquina host, es decir, los
procesos que se ejecutan dentro del Modo de usuario no serán visibles para el host . Esto no es como el contenedor Docker habitual, en cuyo caso la máquina host siempre ve los procesos dentro del repositorio. Echa un vistazo a esta pieza de pstree desde uno de mis servidores:
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}]
Y compare esto con el kernel pstree Linux en modo de usuario:
linux─┬─5*[linux] └─slirp
Cuando trabajo con contenedores Docker, puedo ver los nombres de los procesos que se ejecutan en el sistema invitado desde el host. Con el modo de usuario de Linux, esto no es posible. ¿Qué significa esto? Esto significa que las herramientas de monitoreo que funcionan a través del subsistema de auditoría de Linux
no ven los procesos que se ejecutan en el sistema invitado. Pero en algunas situaciones, esta característica puede convertirse en una espada de doble filo.
En general, toda la publicación a continuación es un conjunto de estudios e intentos groseros para lograr el resultado deseado. Para hacer esto, tuve que usar varias herramientas antiguas, leer las fuentes del núcleo, depurar intensamente el código escrito mientras aún estaba en la escuela primaria, y también elegir los ensamblados de Heroku usando un binario especial en busca de las herramientas que necesitaba. Todo este trabajo ha llevado a los chicos de mi IRC a llamarme mágico. Espero que esta publicación sirva como una documentación confiable para que todo funcione de la misma manera, pero con kernels y versiones de sistema operativo más recientes.
Personalización
La configuración del modo de usuario de Linux tiene varios pasos:
- instalar dependencias en el host;
- Descargar el kernel de Linux
- configuración del ensamblaje del núcleo;
- ensamblaje del grano;
- instalación binaria;
- configurar el sistema de archivos de invitado;
- selección de parámetros de lanzamiento del kernel;
- configuración de la red de invitados;
- comenzando el kernel invitado.
Supongo que si decides subirlo todo por ti mismo, lo más probable es que hagas todo lo descrito en algún sistema similar a Ubuntu o Debian. Traté de implementar todo lo anterior en mi distribución favorita: Alpine, pero no salió nada de eso, aparentemente porque el kernel de Linux tenía un estricto enlace en glibc-isms para los controladores en modo de usuario. Tengo la intención de informar de esto a la corriente arriba después de que finalmente descubra el problema.
Instalar dependencias en el host
Ubuntu requiere al menos los siguientes paquetes para construir el kernel de Linux (siempre que haya una instalación limpia):
- 'build-essential'
- 'flex'
- 'bison'
- 'xz-utils'
- 'wget'
- 'ca-certificates'
- 'bc'
- 'linux-headers'
Puede instalarlos usando el siguiente comando (con privilegios de root o usando sudo):
apt-get -y install build-essential flex bison xz-utils wget ca-certificates bc \ linux-headers-$(uname -r)
Tenga en cuenta que ejecutar el programa de configuración del menú para el kernel de Linux requerirá la instalación de
libncurses-dev
. Asegúrese de que esté instalado con el siguiente comando (con privilegios de root o con sudo):
apt-get -y install libncurses-dev
Descarga del kernel
Determine la ubicación para la carga y el posterior ensamblaje del núcleo. Para esta operación, deberá asignar aproximadamente 1.3 GB de espacio en el disco duro, así que asegúrese de tener uno.
Luego vaya a
kernel.org y obtenga la URL para descargar la última versión estable del kernel. Al momento de escribir esta publicación:
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xzDescargue este archivo usando
'wget'
:
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz
Y extraerlo con
'tar'
:
tar xJf linux-5.1.16.tar.xz
Ahora ingresamos al directorio creado al desempacar el tarball:
cd linux-5.1.16
Configuración de compilación del núcleo
El sistema de compilación del núcleo es una colección de
Makefiles con
muchas herramientas y scripts personalizados para automatizar el proceso. Para comenzar, abra el programa de configuración en línea:
make ARCH=um menuconfig
Completará parcialmente el ensamblaje y mostrará un cuadro de diálogo para usted. Cuando se muestra '
[Select]
' en la parte inferior de la ventana, puede hacer la configuración con las teclas Espacio o Entrar. Navegación en la ventana, como de costumbre, con las flechas hacia arriba y hacia abajo del teclado, y la selección de elementos es izquierda o derecha.
Un puntero de vista ---> significa que está en un submenú al que se accede mediante la tecla Intro. La salida es obviamente a través de '
[Exit]
'.
Incluya los siguientes parámetros en '
[Select]
' y asegúrese de que haya un símbolo '[*]' junto a ellos:
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
Todo desde esta ventana se puede salir seleccionando secuencialmente '
[Exit]
'. Solo asegúrese de que al final se le solicite que guarde la configuración y seleccione '
[Yes]
'.
Te recomiendo que juegues con las opciones de compilación del núcleo después de leer esta publicación. Gracias a estos experimentos, puede aprender mucho en términos de comprender el trabajo de la mecánica de kernel de bajo nivel y la influencia de varios indicadores en su ensamblaje.
Ensamblaje de granos
El kernel de Linux es un gran programa que hace muchas cosas. Incluso con una configuración tan mínima en equipos antiguos, puede llevar bastante tiempo ensamblarlo. Por lo tanto, construya el núcleo con el siguiente comando:
make ARCH=um -j$(nproc)
Por qué Este comando le indicará a nuestro ensamblador que use todos los núcleos y subprocesos de procesador disponibles durante el proceso de compilación. El
$(nproc)
al final de Build sustituye la salida del
nproc
, que es parte de
coreutils
en la compilación estándar de Ubuntu.
Después de un tiempo, nuestro núcleo se compilará en un archivo ejecutable
./linux
.
Instalación binaria
Como User Mode en Linux crea un binario regular, puede instalarlo como cualquier otra utilidad. Así es como lo hice:
mkdir -p ~/bin cp linux ~/bin/linux
También vale la pena verificar que
~/bin
está en su
$PATH
:
export PATH=$PATH:$HOME/bin
Configurar el sistema de archivos invitado
Cree un directorio para el sistema de archivos invitado:
mkdir -p $HOME/prefix/uml-demo cd $HOME/prefix
Abra alpinelinux.org y en
la sección de descargas encuentre el enlace actual para descargar
MINI ROOT FILESYSTEM
. En el momento de escribir esto, era:
http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz
Descargue este tarball usando 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
Ahora ingrese el directorio del sistema de archivos invitado y descomprima el archivo:
cd uml-demo tar xf ../alpine-rootfs.tgz
Los pasos descritos crearán una pequeña plantilla de sistema de archivos. Debido a la naturaleza del sistema, la instalación de paquetes a través del administrador Alpine apk será extremadamente difícil. Pero este FS será suficiente para evaluar la idea general.
También necesitamos la herramienta
tini para suprimir el consumo de memoria por los
procesos zombies de nuestro núcleo invitado.
wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static chmod +x tini
Crear una línea de comando del núcleo
El núcleo de Linux, como la mayoría de los otros programas, tiene argumentos de línea de comandos a los que se puede acceder especificando el
--help
.
Sam - ayuda 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.
Este banner ilumina las principales opciones de lanzamiento. Ejecutemos el kernel con el conjunto mínimo de opciones requeridas:
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ init=/bin/sh
Las líneas anteriores le dicen a nuestro núcleo lo siguiente:
- Supongamos que el sistema de archivos raíz es el pseudo dispositivo
/dev/root
. - Elija hostfs como el controlador del sistema de archivos raíz.
- Monte el sistema de archivos invitado que creamos en el dispositivo raíz.
- Y sí, en modo lectura-escritura.
- Use solo 64 megabytes de RAM (puede usar mucho menos, dependiendo de lo que planee hacer, pero 64 MB parece ser el tamaño óptimo).
- El kernel se inicia automáticamente
/bin/sh
como un proceso de init
.
Ejecute este comando y debería obtener algo como lo siguiente:
Otra hoja 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 / #
Manipular lo anterior nos dará un
sistema de invitado como mínimo , sin elementos como
/proc
o un nombre de host asignado. Por ejemplo, pruebe los siguientes comandos:
- uname -av
- cat /proc/self/pid
- hostname
Para salir del sistema invitado, escriba
exit
o presione control-d. Esto disparará el shell seguido de kernel panic:
/ # exit Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 fish: “./linux root=/dev/root rootflag…” terminated by signal SIGABRT (Abort)
Tenemos este kernel panic porque el kernel de Linux cree que el proceso de inicialización siempre se está ejecutando. Sin él, el sistema ya no puede funcionar y se apaga. Pero dado que este es un proceso en modo de usuario, el resultado se envía a
SIGABRT
, que conduce a la salida.
Configuración de red de invitado
Y aquí, en nosotros, todo comienza a ir no según el plan. La red en modo de usuario Linux es donde todo el concepto de un "modo de usuario" limitado comienza a desmoronarse. Después de todo, generalmente a nivel del sistema, la red se limita a modos de ejecución
privilegiados por razones claras.
Nota trans .: puede leer más sobre las diferentes opciones para trabajar con la red en UML aquí .Viaja a slirp
Sin embargo, existe una herramienta antigua y casi
incompatible llamada
Slirp , con la cual el Modo de usuario Linux puede interactuar con la red. Funciona más o menos como una pila TCP / IP a nivel de usuario y no requiere ningún permiso del sistema para ejecutarse. Esta herramienta fue
lanzada en 1995 , y la última actualización data de
2006 . Slirp es muy viejo. Durante un tiempo sin soporte ni actualizaciones, los compiladores han llegado tan lejos que ahora esta herramienta solo puede describirse como una
"descomposición de código" .
Entonces, pasemos Slirp desde los repositorios de Ubuntu e intentemos ejecutarlo:
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 dioses Instalemos un depurador para Slirp y veamos si podemos descubrir qué está pasando aquí:
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.
El error late en
esta línea . Echemos un vistazo a stacktrace, tal vez algo nos ayudará allí:
(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.
Aquí vemos que ocurre una falla durante el inicio del bucle principal, cuando slirp intenta verificar los tiempos de espera. En este punto, tuve que renunciar a tratar de depurar. Pero veamos si Slirp compilado de algún tipo funciona. Recargué el archivo directamente desde el sitio web de
Sourceforge , porque arrastrar algo desde allí a través de la línea de comando es un dolor:
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
Aquí vemos alertas sobre funciones incorporadas indefinidas, es decir, sobre la imposibilidad de vincular el archivo binario resultante. Parece que entre 2006 y este momento, gcc dejó de crear caracteres utilizados en las funciones integradas de archivos compilados intermedios. Intentemos reemplazar la
inline
con un comentario vacío y veamos el resultado:
vi slirp.h :6 a <enter> #define inline /**/ <escape> :wq make
No Esto tampoco funciona. Aún no puede encontrar los caracteres para estas funciones.
En este punto, me di por vencido y comencé a buscar
paquetes de compilación de Heroku en Github. Mi teoría se basó en el hecho de que algunos paquetes de compilación de Heroku contendrán los archivos binarios que necesito. Como resultado, la búsqueda me llevó
aquí . Descargué y desempaqué
uml.tar.gz
y encontré lo siguiente:
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*
Este es un archivo slirp binario! ¿El trabaja?
./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 ...
No se bloquea, ¡así que debería funcionar! Enganchemos este binario a
~/bin/slirp
:
cp slirp ~/bin/slirp
En caso de que el creador del paquete lo elimine, hice
un espejo .
Configuración de red
Ahora configuremos la red en nuestro núcleo de invitados.
Actualizar opciones de inicio :
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ eth0=slirp,,$HOME/bin/slirp \ init=/bin/sh
Ahora encienda la red:
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
Los dos primeros comandos de configuración
/proc
y
/sys
necesarios para que
ifconfig
funcione, lo que configura una interfaz de red para comunicarse con Slirp. El comando de
route
configura una tabla de enrutamiento del núcleo para forzar todo el tráfico a través del túnel Slirp. Verifiquemos esto con una consulta DNS:
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
Funciona!
Nota: Aparentemente, la publicación original se escribió en el escritorio con una tarjeta de red con cable o alguna otra configuración que no requiera controladores adicionales. En una computadora portátil con WiFi 8265 de Intel, cuando eleva la red, se produce un error /
Aparentemente, el núcleo no puede comunicarse con el controlador de red. Lamentablemente, un intento de compilar firmware en el kernel no solucionó la situación. En el momento de la publicación, no era posible encontrar una solución en esta configuración particular. En configuraciones más simples (por ejemplo, en Virtualbox) la interfaz se eleva correctamente.Automaticemos la redirección utilizando el siguiente script de shell:
#!/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
Y márquelo como ejecutable:
chmod +x init.sh
Y luego realice cambios en la línea de comando del kernel:
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ eth0=slirp,,$HOME/bin/slirp \ init=/init.sh
Y repito:
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
¡La red es estable!
-
,
Dockerfile , .
, , . , .
, , . - , , User Mode Linux . . Docker — tar-,
docker export
, . , shell-.
Rkeene #lobsters Freenode. Slirp . , Slackware slirp, Ubuntu Alpine slirp Rkeene . , -.