Como começar a usar o Modo de Usuário no Linux

Introdução do tradutor: No contexto da entrada maciça em nossas vidas de vários tipos de contêineres, pode ser bastante interessante e útil descobrir com quais tecnologias tudo começou uma vez. Alguns deles ainda podem ser usados ​​até hoje, mas nem todos se lembram de tais métodos (ou sabem se eles não foram encontrados durante seu rápido desenvolvimento). Uma dessas tecnologias é o Linux no modo de usuário. O autor do original vasculhou, descobrindo o que os desenvolvimentos antigos ainda funcionavam e o que não era muito, e coletou algo como uma instrução passo a passo sobre como iniciar a UML doméstica em 2k19 para mim. E sim, convidamos o autor do post original do Cadey para Habr . Portanto, se você tiver alguma dúvida, pergunte em inglês nos comentários.

imagem

O Modo de Usuário Linux é, de fato, a própria porta do kernel Linux. Esse modo permite executar um kernel Linux completo como um processo do usuário e geralmente é usado pelos desenvolvedores para testar drivers. Mas esse modo também é útil como uma ferramenta para isolamento geral, cujo princípio é semelhante à operação de máquinas virtuais. Esse modo fornece mais isolamento que o Docker, mas menos que uma máquina virtual completa, como KVM ou Virtual Box.

Em geral, o Modo do Usuário pode parecer estranho e difícil de usar, mas ainda possui suas próprias áreas de aplicação. Afinal, este é um kernel Linux completo, trabalhando com um usuário sem privilégios. Esse recurso permite que você execute código potencialmente não confiável sem ameaças à máquina host. E como é um kernel completo, seus processos são isolados da máquina host, ou seja, os processos em execução no Modo Usuário não serão visíveis para o host . Isso não é como o contêiner Docker usual, nesse caso a máquina host sempre vê os processos dentro do repositório. Dê uma olhada neste pedaço de pstree de um dos meus 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}] 

E compare isso com o kernel do pstree Linux no Modo de Usuário:

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

Ao trabalhar com contêineres do Docker, posso ver os nomes dos processos em execução no sistema convidado a partir do host. Com o Modo de Usuário Linux, isso não é possível. O que isso significa? Isso significa que as ferramentas de monitoramento que funcionam através do subsistema de auditoria do Linux não veem processos em execução no sistema convidado. Mas em algumas situações, esse recurso pode se tornar uma faca de dois gumes.

Em geral, todo o post abaixo é um conjunto de estudos e tentativas grosseiras de alcançar o resultado desejado. Para fazer isso, tive que usar várias ferramentas antigas, ler as fontes do kernel, depurar intensamente o código escrito enquanto eu ainda estava no ensino fundamental e também escolher as assembléias do Heroku usando um binário especial em busca das ferramentas necessárias. Todo esse trabalho levou os caras do meu IRC a me chamarem de mágica. Espero que este post sirva como alguém documentação confiável para pôr tudo em ordem, mas com os kernels e versões mais recentes do sistema operacional.

Personalização


A configuração do Modo de Usuário Linux leva várias etapas:

  • instalar dependências no host;
  • Fazendo Download do Kernel Linux
  • configuração de montagem do kernel;
  • montagem de kernel;
  • instalação binária;
  • configurando o sistema de arquivos convidado;
  • seleção de parâmetros de inicialização do kernel;
  • configuração de rede de convidados;
  • iniciando o kernel convidado.

Presumo que, se você decidir aumentar tudo, provavelmente fará tudo o que está descrito em algum sistema semelhante ao Ubuntu ou Debian. Tentei implementar todas as opções acima na minha distribuição favorita - Alpine, mas nada aconteceu, aparentemente porque o kernel do Linux tinha uma forte ligação no glibc-isms para drivers no Modo Usuário. Eu pretendo relatar isso ao montante depois que eu finalmente descobrir o problema.

Instale dependências no host


O Ubuntu requer pelo menos os seguintes pacotes para construir o kernel do Linux (desde que seja uma instalação limpa):

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


Você pode instalá-los usando o seguinte comando (com privilégios de root ou usando o sudo):

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

Observe que a execução do programa de configuração de menu para o kernel do Linux exigirá a instalação do libncurses-dev . Verifique se ele está instalado usando o seguinte comando (com privilégios de root ou com sudo):

 apt-get -y install libncurses-dev 

Download do kernel


Determine onde carregar e, em seguida, construa o kernel. Para esta operação, você precisará alocar cerca de 1,3 GB de espaço no disco rígido, portanto, verifique se possui um.

Então vá para kernel.org e obtenha o URL para baixar a última versão estável do kernel. No momento da redação deste post: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Faça o download deste arquivo usando 'wget' :

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

E extraia-o com 'tar' :

 tar xJf linux-5.1.16.tar.xz 

Agora entramos no diretório criado ao descompactar o tarball:

 cd linux-5.1.16 

Configuração de compilação do kernel


O sistema de compilação do kernel é uma coleção de Makefiles com muitas ferramentas e scripts personalizados para automatizar o processo. Para começar, abra o programa de instalação online:

 make ARCH=um menuconfig 

Ele completará parcialmente a montagem e exibirá uma caixa de diálogo para você. Quando ' [Select] ' for exibido na parte inferior da janela, você poderá fazer a configuração usando as teclas Espaço ou Enter. Navegação na janela, como sempre, com as setas para cima e para baixo do teclado e a seleção de elementos - “esquerda” ou “direita”.

Um ponteiro de visualização ---> significa que você está em um submenu acessado pela tecla Enter. A saída é obviamente através de ' [Exit] '.

Inclua os seguintes parâmetros em ' [Select] ' e verifique se há um símbolo '[*]' próximo a eles:

 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 

Tudo a partir desta janela pode ser encerrado selecionando sequencialmente ' [Exit] '. Apenas certifique-se de que, no final, você seja solicitado a salvar a configuração e selecione ' [Yes] '.

Eu recomendo que você brinque com as opções de compilação do kernel depois de ler este post. Graças a esses experimentos, você pode aprender muito em termos de compreensão do trabalho da mecânica de núcleo de baixo nível e da influência de vários sinalizadores em sua montagem.

Montagem do Kernel


O kernel do Linux é um ótimo programa que faz muitas coisas. Mesmo com uma configuração mínima em equipamentos antigos, pode demorar um pouco para montá-lo. Portanto, construa o kernel com o seguinte comando:

 make ARCH=um -j$(nproc) 

Porque Este comando instruirá nosso montador a usar todos os núcleos e threads de processador disponíveis durante o processo de compilação. O $(nproc) no final do Build substitui a saída do nproc , que faz parte dos coreutils na compilação padrão do Ubuntu.

Depois de algum tempo, nosso kernel será compilado em um arquivo executável ./linux .

Instalação binária


Como o Modo de Usuário no Linux cria um binário regular, você pode instalá-lo como qualquer outro utilitário. Aqui está como eu fiz isso:

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

Também vale a pena verificar se ~/bin está no seu $PATH :

 export PATH=$PATH:$HOME/bin 

Configurando o Sistema de Arquivos Convidado


Crie um diretório para o sistema de arquivos convidado:

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

Abra o alpinelinux.org e, na seção de downloads, encontre o link atual para baixar o MINI ROOT FILESYSTEM . No momento da redação deste texto, era:

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

Faça o download deste tarball usando o 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 

Agora digite o diretório do sistema de arquivos convidado e descompacte o arquivo morto:

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

As etapas descritas criarão um pequeno modelo de sistema de arquivos. Devido à natureza do sistema, a instalação de pacotes através do gerenciador de aplicativos Alpine será extremamente difícil. Mas esse FS será suficiente para avaliar a ideia geral.

Também precisamos da ferramenta tini para suprimir o consumo de memória pelos processos zumbis de nosso núcleo convidado.

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

Criando uma linha de comando do kernel


O kernel do Linux, como a maioria dos outros programas, possui argumentos de linha de comando que podem ser acessados ​​especificando a opção --help .

Sam --help
 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 as principais opções de inicialização. Vamos executar o kernel com o conjunto mínimo de opções necessário:

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

As linhas acima informam ao nosso núcleo o seguinte:

  • Suponha que o sistema de arquivos raiz seja o pseudo-dispositivo /dev/root .
  • Escolha hostfs como o driver do sistema de arquivos raiz.
  • Monte o sistema de arquivos convidado que criamos no dispositivo raiz.
  • E sim, no modo de leitura e gravação.
  • Use apenas 64 megabytes de RAM (você pode usar muito menos, dependendo do que planeja fazer, mas 64 MB parece ser o tamanho ideal).
  • O kernel inicia automaticamente /bin/sh como um processo init .

Execute este comando e você deverá obter algo como o seguinte:

Outra folha
 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 o que foi dito acima nos dará um sistema de convidados no mínimo , sem coisas como /proc ou um nome de host atribuído. Por exemplo, tente os seguintes comandos:

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


Para sair do sistema convidado, digite exit ou pressione control-d. Isso disparará no shell seguido pelo pânico do kernel:

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

Temos esse pânico no kernel porque o kernel Linux acredita que o processo de inicialização está sempre em execução. Sem ele, o sistema não pode mais funcionar e é desligado. Mas, como esse é um processo no modo de usuário, o resultado se envia para o SIGABRT , o que leva à saída.

Configuração de rede de convidado


E aqui em nós tudo começa a não seguir o plano. A rede no Modo de Usuário Linux é onde todo o conceito de um "modo de usuário" limitado começa a desmoronar. Afinal, geralmente no nível do sistema, a rede é limitada a modos de execução privilegiados por todos nós, razões claras.

Nota trans .: mais sobre as diferentes opções para trabalhar com a rede na UML podem ser lidas aqui .

Viajar para slirp


No entanto, existe uma ferramenta antiga e quase sem suporte chamada Slirp , com a qual o Linux no Modo de Usuário pode interagir com a rede. Funciona mais ou menos como uma pilha TCP / IP no nível do usuário e não requer nenhuma permissão do sistema para ser executada. Esta ferramenta foi lançada em 1995 e a atualização mais recente data de 2006 . Slirp é muito antigo. Por um tempo sem suporte e atualizações, os compiladores foram tão longe que agora essa ferramenta só pode ser descrita como uma "roteirização de código" .

Então, vamos rolar o Slirp dos repositórios do Ubuntu e tentar executá-lo:

 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 deuses. Vamos instalar um depurador para Slirp e ver se conseguimos descobrir o que está acontecendo aqui:

 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. 

O erro está batendo nesta linha . Vejamos o stacktrace, talvez algo nos ajude lá:

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

Aqui vemos que uma falha ocorre durante o início do loop principal, quando o slirp tenta verificar o tempo limite. Nesse ponto, tive que desistir de tentar depurar. Mas vamos ver se o Slirp compilado a partir das sortes funciona. Eu recarreguei o arquivo diretamente do site Sourceforge , porque arrastar algo de lá através da linha de comando é uma dor:

 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 

Aqui vemos alertas sobre funções internas indefinidas, ou seja, sobre a impossibilidade de vincular o arquivo binário resultante. Parece que entre 2006 e esse momento, o gcc parou de criar caracteres usados ​​nas funções internas dos arquivos compilados intermediários. Vamos tentar substituir a inline - inline por um comentário vazio e ver o resultado:

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

Não. Isso também não funciona. Você ainda não consegue encontrar os caracteres para essas funções.

Nesse ponto, desisti e comecei a procurar pacotes de compilação Heroku no Github. Minha teoria foi baseada no fato de que alguns pacotes de compilação do Heroku conterão os binários de que preciso. Como resultado, a pesquisa me levou aqui . Fiz o download e descompactei uml.tar.gz e encontrei o seguinte:

 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 é um arquivo slirp binário! Ele trabalha?

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

Não falha - por isso deve funcionar! Vamos conectar este binário em ~/bin/slirp :

 cp slirp ~/bin/slirp 

Caso o criador do pacote o remova, fiz um espelho .

Configuração de rede


Agora vamos configurar a rede em nosso núcleo de convidados. Atualize as opções de inicialização :

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

Agora vamos ligar a rede:

 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 

Os dois primeiros comandos de configuração /proc e /sys necessários para o funcionamento do ifconfig , que configura uma interface de rede para comunicação com o Slirp. O comando route configura uma tabela de roteamento do kernel para forçar todo o tráfego através do túnel Slirp. Vamos verificar isso com uma 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 

Isso funciona!

Nota: Aparentemente, a postagem original foi gravada na área de trabalho com uma placa de rede com fio ou outra configuração que não requer drivers adicionais. Em um laptop com WiFi 8265 da Intel, quando você cria a rede, ocorre um erro

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

Aparentemente, o kernel não pode se comunicar com o driver de rede. Uma tentativa de compilar o firmware no kernel, infelizmente, não corrigiu a situação. No momento da publicação, não era possível encontrar uma solução nessa configuração específica. Em configurações mais simples (por exemplo, no Virtualbox), a interface aumenta corretamente.

Vamos automatizar o redirecionamento usando o seguinte 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 

E marque-o como executável:

 chmod +x init.sh 

E, em seguida, faça alterações na linha de comando do kernel:

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

E repita:

 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 

A rede está estável!

-


, 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/pt459558/


All Articles