Cara mulai menggunakan Mode Pengguna di Linux

Pendahuluan dari penerjemah: Dengan latar belakang masuknya besar-besaran ke dalam kehidupan kita dari berbagai jenis wadah, bisa sangat menarik dan berguna untuk mengetahui dengan teknologi mana semuanya dimulai sekali. Beberapa dari mereka masih dapat digunakan sampai hari ini, tetapi tidak semua orang ingat metode seperti itu (atau tahu jika mereka tidak ditemukan selama perkembangan cepat mereka). Salah satu teknologi tersebut adalah User Mode Linux. Penulis asli cukup mencari-cari, mencari tahu apa perkembangan lama masih bekerja, dan apa yang tidak terlalu banyak, dan mengumpulkan sesuatu seperti instruksi langkah-demi-langkah tentang cara memulai UML rumahan dalam 2k19 untuk saya sendiri. Dan ya, kami mengundang penulis posting Cadey asli ke Habr , jadi jika Anda memiliki pertanyaan, tanyakan dalam bahasa Inggris di komentar.

gambar

Mode Pengguna Linux sebenarnya adalah port kernel Linux itu sendiri. Mode ini memungkinkan Anda untuk menjalankan kernel Linux lengkap sebagai proses pengguna dan biasanya digunakan oleh pengembang untuk menguji driver. Tetapi mode ini juga berguna sebagai alat untuk isolasi umum, yang prinsipnya mirip dengan pengoperasian mesin virtual. Mode ini memberikan lebih banyak isolasi daripada Docker, tetapi kurang dari mesin virtual lengkap seperti KVM atau Virtual Box.

Secara umum, Mode Pengguna mungkin tampak aneh dan sulit digunakan, tetapi masih memiliki area aplikasi sendiri. Bagaimanapun, ini adalah kernel Linux lengkap, bekerja dari pengguna yang tidak memiliki hak. Fitur ini memungkinkan Anda untuk menjalankan kode yang berpotensi tidak dipercaya tanpa ancaman ke mesin host. Dan karena itu adalah kernel penuh, prosesnya diisolasi dari mesin host, yaitu, proses yang berjalan di dalam Mode Pengguna tidak akan terlihat oleh host . Ini tidak seperti wadah Docker biasa, dalam hal ini mesin host selalu melihat proses di dalam repositori. Lihatlah sepotong pstree ini dari salah satu server saya:

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

Dan bandingkan ini dengan kernel pstree Linux dalam Mode Pengguna:

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

Ketika bekerja dengan wadah Docker, saya bisa melihat nama-nama proses yang berjalan pada sistem tamu dari tuan rumah. Dengan Mode Pengguna Linux, ini tidak mungkin. Apa artinya ini? Ini berarti bahwa alat pemantauan yang bekerja melalui subsistem audit Linux tidak melihat proses berjalan pada sistem tamu. Namun dalam beberapa situasi, fitur ini bisa menjadi pedang bermata dua.

Secara umum, seluruh posting di bawah ini adalah serangkaian studi dan upaya kasar untuk mencapai hasil yang diinginkan. Untuk melakukan ini, saya harus menggunakan berbagai alat kuno, membaca sumber kernel, secara intensif men-debug kode yang ditulis ketika saya masih di sekolah dasar, dan juga memilih majelis Heroku menggunakan binar khusus untuk mencari alat yang saya butuhkan. Semua pekerjaan ini telah membuat orang-orang di IRC saya memanggil saya sihir. Saya berharap postingan ini akan berfungsi sebagai dokumentasi yang dapat diandalkan seseorang untuk melakukan engkol semuanya sama, tetapi dengan kernel yang lebih baru dan versi OS.

Kustomisasi


Mengatur Mode Pengguna Linux membutuhkan beberapa langkah:

  • menginstal dependensi pada host;
  • Mengunduh kernel Linux
  • pengaturan perakitan kernel;
  • perakitan kernel;
  • instalasi biner;
  • mengatur sistem file tamu;
  • pemilihan parameter peluncuran kernel;
  • pengaturan jaringan tamu;
  • memulai kernel tamu.

Saya berasumsi bahwa jika Anda memutuskan untuk membuat semuanya sendiri, kemungkinan besar Anda akan melakukan semua yang dijelaskan dalam beberapa sistem seperti Ubuntu atau Debian. Saya mencoba menerapkan semua hal di atas dalam distribusi favorit saya - Alpine, tetapi tidak ada yang muncul darinya, tampaknya karena kernel Linux memiliki ikatan yang kuat pada glibc-isme untuk driver dalam Mode Pengguna. Saya berencana untuk melaporkan ini ke hulu setelah saya akhirnya menemukan masalah.

Instal dependensi pada host


Ubuntu membutuhkan setidaknya paket berikut untuk membangun kernel Linux (menyediakan instalasi yang bersih):

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


Anda dapat menginstalnya menggunakan perintah berikut (dengan hak akses root atau menggunakan sudo):

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

Perhatikan bahwa menjalankan program pengaturan menu untuk kernel Linux akan memerlukan instalasi libncurses-dev . Pastikan itu diinstal menggunakan perintah berikut (dengan hak akses root atau dengan sudo):

 apt-get -y install libncurses-dev 

Pengunduhan kernel


Tentukan tempat untuk memuat dan kemudian membangun kernel. Untuk operasi ini, Anda harus mengalokasikan sekitar 1,3 GB ruang hard disk, jadi pastikan Anda memilikinya.

Lalu pergi ke kernel.org dan dapatkan URL untuk mengunduh versi kernel stabil terbaru. Pada saat menulis posting ini: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Unduh file ini menggunakan 'wget' :

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

Dan ekstrak dengan 'tar' :

 tar xJf linux-5.1.16.tar.xz 

Sekarang kita masuk ke direktori yang dibuat saat membongkar tarball:

 cd linux-5.1.16 

Konfigurasi Pembuatan Kernel


Sistem kernel build adalah kumpulan Makefiles dengan banyak alat khusus dan skrip untuk mengotomatiskan proses. Untuk memulai, buka program pengaturan online:

 make ARCH=um menuconfig 

Ini akan menyelesaikan sebagian perakitan dan menampilkan kotak dialog untuk Anda. Ketika ' [Select] ' ditampilkan di bagian bawah jendela, Anda dapat melakukan konfigurasi menggunakan tombol Space atau Enter. Navigasi di jendela, seperti biasa, dengan panah atas dan bawah keyboard, dan pemilihan elemen - "kiri" atau "kanan".

Penunjuk tampilan ---> berarti bahwa Anda berada dalam submenu yang diakses oleh tombol Enter. Jalan keluarnya jelas melalui ' [Exit] '.

Sertakan parameter berikut di ' [Select] ' dan pastikan ada simbol '[*]' di sebelahnya:

 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 

Semuanya dari jendela ini dapat keluar dengan memilih secara berurutan ' [Exit] '. Pastikan bahwa pada akhirnya Anda diminta untuk menyimpan konfigurasi dan pilih ' [Yes] '.

Saya sarankan Anda bermain-main dengan opsi kernel build setelah membaca posting ini. Berkat eksperimen ini, Anda dapat belajar banyak dalam hal memahami pekerjaan mekanika kernel tingkat rendah dan pengaruh berbagai flag pada rakitannya.

Perakitan kernel


Kernel Linux adalah program hebat yang melakukan banyak hal. Bahkan dengan konfigurasi minimal pada peralatan lama, dibutuhkan waktu cukup lama untuk merakitnya. Karena itu, bangun kernel dengan perintah berikut:

 make ARCH=um -j$(nproc) 

Mengapa Perintah ini akan memberi tahu assembler kami untuk menggunakan semua core dan utas prosesor yang tersedia selama proses pembangunan. Perintah $(nproc) di akhir Build menggantikan output dari nproc , yang merupakan bagian dari coreutils di build standar Ubuntu.

Setelah beberapa waktu, kernel kami akan dikompilasi menjadi file ./linux dapat dieksekusi.

Instalasi biner


Karena Mode Pengguna di Linux membuat biner biasa, Anda dapat menginstalnya seperti utilitas lainnya. Begini cara saya melakukannya:

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

Anda juga perlu memeriksa bahwa ~/bin di $PATH :

 export PATH=$PATH:$HOME/bin 

Menyiapkan sistem file tamu


Buat direktori untuk sistem file tamu:

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

Buka alpinelinux.org dan di bagian unduhan temukan tautan saat ini untuk mengunduh MINI ROOT FILESYSTEM . Pada saat penulisan ini, itu adalah:

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

Unduh tarbal ini menggunakan 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 

Sekarang masukkan direktori sistem file tamu dan unzip arsip:

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

Langkah-langkah yang dijelaskan akan membuat templat sistem file kecil. Karena sifat sistem, menginstal paket melalui manajer Alpine apk akan sangat sulit. Tetapi FS ini akan cukup untuk mengevaluasi ide umum.

Kami juga membutuhkan alat kecil untuk menekan konsumsi memori oleh proses zombie dari inti tamu kami.

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

Membuat baris perintah kernel


Kernel Linux, seperti kebanyakan program lain, memiliki argumen baris perintah yang dapat diakses dengan menentukan saklar --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. 


Spanduk ini menerangi opsi peluncuran utama. Mari kita jalankan kernel dengan set opsi minimum yang diperlukan:

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

Baris di atas memberi tahu inti kami hal berikut:

  • Misalkan sistem file root adalah perangkat semu /dev/root .
  • Pilih hostfs sebagai driver sistem file root.
  • Pasang sistem file tamu yang kami buat di perangkat root.
  • Dan ya, dalam mode baca-tulis.
  • Gunakan hanya 64 megabita RAM (Anda dapat menggunakan lebih sedikit, tergantung pada apa yang Anda rencanakan, tetapi 64 MB tampaknya merupakan ukuran optimal).
  • Kernel secara otomatis memulai /bin/sh sebagai proses init .

Jalankan perintah ini dan Anda harus mendapatkan sesuatu seperti berikut:

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


Memanipulasi di atas akan memberi kita sistem tamu minimal , tanpa hal-hal seperti /proc atau nama host yang ditugaskan. Misalnya, coba perintah berikut:

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


Untuk keluar dari sistem tamu, ketik exit atau tekan control-d. Ini akan menembakkan shell diikuti oleh kernel panik:

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

Kami mendapatkan kepanikan kernel ini karena kernel Linux percaya bahwa proses inisialisasi selalu berjalan. Tanpanya, sistem tidak dapat lagi berfungsi dan dimatikan. Tetapi karena ini adalah proses mode pengguna, hasilnya mengirimkan dirinya ke SIGABRT , yang mengarah ke pintu keluar.

Pengaturan Jaringan Tamu


Dan di sini kita mulai semuanya tidak berjalan sesuai rencana. Jaringan dalam Mode Pengguna Linux adalah tempat seluruh konsep "mode pengguna" terbatas mulai berantakan. Lagi pula, biasanya pada tingkat sistem jaringan terbatas pada mode eksekusi istimewa untuk kita semua alasan yang jelas.

Catatan trans .: lebih lanjut tentang berbagai opsi untuk bekerja dengan jaringan di UML dapat dibaca di sini .

Bepergian ke slirp


Namun, ada alat kuno dan hampir tidak didukung yang disebut Slirp , yang dengannya Mode Pengguna Linux dapat berinteraksi dengan jaringan. Ini bekerja kira-kira seperti tumpukan TCP / IP di tingkat pengguna dan tidak memerlukan izin sistem untuk dijalankan. Alat ini dirilis pada tahun 1995 , dan pembaruan terakhir kembali ke tahun 2006 . Slirp sudah sangat tua. Untuk waktu tanpa dukungan dan pembaruan, kompiler telah melangkah sejauh ini sehingga sekarang alat ini hanya dapat digambarkan sebagai "kode busuk" .

Jadi, mari kita roll Slirp dari repositori Ubuntu dan mencoba menjalankannya:

 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) 

Ya tuhan. Mari kita instal sebuah debugger untuk Slirp dan lihat apakah kita dapat mengetahui apa yang sedang terjadi di sini:

 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. 

Kesalahan terjadi pada baris ini . Mari kita lihat stacktrace, mungkin sesuatu akan membantu kita di sana:

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

Di sini kita melihat bahwa kegagalan terjadi selama permulaan loop utama, ketika slirp mencoba memeriksa timeout. Pada titik ini, saya harus berhenti berusaha untuk debug. Tapi mari kita lihat apakah Slirp dikompilasi dari berbagai karya. Saya memuat ulang arsip langsung dari situs web Sourceforge , karena menyeret sesuatu dari sana melalui baris perintah sangat menyebalkan:

 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 

Di sini kita melihat peringatan tentang fungsi bawaan yang tidak ditentukan, yaitu tentang ketidakmungkinan menghubungkan file biner yang dihasilkan. Tampaknya antara tahun 2006 dan saat ini, gcc berhenti membuat karakter yang digunakan dalam fungsi bawaan file kompilasi menengah. Mari kita coba ganti inline dengan komentar kosong dan lihat hasilnya:

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

Tidak. Ini juga tidak berhasil. Anda masih tidak dapat menemukan karakter untuk fungsi-fungsi ini.

Pada titik ini, saya menyerah dan mulai mencari paket pembuatan Heroku di Github. Teori saya didasarkan pada kenyataan bahwa beberapa paket build Heroku akan berisi binari yang saya butuhkan. Akibatnya, pencarian membawa saya ke sini . Saya mengunduh dan membongkar uml.tar.gz dan menemukan yang berikut:

 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* 

Ini adalah file slirp biner! Apakah dia bekerja?

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

Tidak macet - jadi itu harus bekerja! Mari kita kaitkan biner ini ke ~/bin/slirp :

 cp slirp ~/bin/slirp 

Jika pembuat paket menghapusnya, saya membuat cermin .

Pengaturan jaringan


Sekarang mari kita mengatur jaringan pada inti tamu kami. Perbarui opsi peluncuran :

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

Sekarang mari kita hidupkan jaringan:

 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 

Dua perintah konfigurasi pertama /proc dan /sys diperlukan agar ifconfig berfungsi, yang mengatur antarmuka jaringan untuk berkomunikasi dengan Slirp. Perintah route mengatur tabel routing kernel untuk memaksa semua lalu lintas melalui terowongan Slirp. Mari kita verifikasi ini dengan permintaan 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 

Itu berhasil!

Catatan: Rupanya, posting asli ditulis di desktop dengan kartu jaringan kabel, atau konfigurasi lain yang tidak memerlukan driver tambahan. Pada laptop dengan WiFi 8265 dari Intel, ketika Anda meningkatkan jaringan, kesalahan terjadi

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

Tampaknya, kernel tidak dapat berkomunikasi dengan driver jaringan. Upaya untuk mengkompilasi firmware ke dalam kernel, sayangnya, tidak memperbaiki situasi. Pada saat publikasi, tidak mungkin untuk menemukan solusi dalam konfigurasi khusus ini. Pada konfigurasi yang lebih sederhana (misalnya, di Virtualbox) antarmuka naik dengan benar.

Mari kita otomatiskan pengalihan menggunakan skrip shell berikut:

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

Dan tandai itu dapat dieksekusi:

 chmod +x init.sh 

Dan kemudian lakukan perubahan pada baris perintah kernel:

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

Dan ulangi:

 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 

Jaringannya stabil!

-


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


All Articles