Linuxda foydalanuvchi rejimidan qanday foydalanishni boshlash kerak

Tarjimondan muqaddima: Hayotimizga turli xil idishlarning ommaviy ravishda kirib borishi fonida, bularning barchasi bir marta qanday texnologiyalar bilan boshlanganini bilish juda qiziqarli va foydali bo'lishi mumkin. Ulardan ba'zilari bugungi kunga qadar foydali bo'lishi mumkin, ammo hamma ham bunday usullarni eslay olmaydi (yoki ularning tez rivojlanishi paytida qo'lga olinmaganligini biladi). Shunday texnologiyalardan biri User Mode Linux hisoblanadi. Asl nusxaning muallifi ko'p qazish ishlarini olib bordi, eski ishlanmalarning qaysi biri hali ham ishlayotganini va qaysi biri ishlamayotganini aniqladi va 2k19-da o'zingizga homebrew UML-ni qanday olish bo'yicha bosqichma-bosqich ko'rsatmani birlashtirdi. Ha, biz asl xabar muallifini Xabrga taklif qildik Cadey, shuning uchun sizda biron bir savol bo'lsa - izohlarda ingliz tilida so'rang.

Linuxda foydalanuvchi rejimidan qanday foydalanishni boshlash kerak

Linux-da foydalanuvchi rejimi, aslida, Linux yadrosining o'zi uchun portidir. Ushbu rejim foydalanuvchi jarayoni sifatida to'liq Linux yadrosini ishga tushirish imkonini beradi va odatda ishlab chiquvchilar tomonidan drayverlarni sinab ko'rish uchun ishlatiladi. Ammo bu rejim umumiy izolyatsiya vositasi sifatida ham foydalidir, uning printsipi virtual mashinalarning ishlashiga o'xshaydi. Ushbu rejim Docker-ga qaraganda ko'proq izolyatsiyani ta'minlaydi, ammo KVM yoki Virtual Box kabi to'liq huquqli virtual mashinadan kamroq.

Umuman olganda, User Mode foydalanish uchun g'alati va qiyin vosita bo'lib tuyulishi mumkin, ammo u hali ham o'z maqsadlariga ega. Axir, bu imtiyozsiz foydalanuvchidan ishlaydigan to'liq huquqli Linux yadrosi. Bu xususiyat potentsial ishonchsiz kodni xost-mashina uchun hech qanday tahdidsiz ishlashga imkon beradi. Va bu to'laqonli yadro bo'lgani uchun uning jarayonlari xost mashinasidan ajratilgan, ya'ni Foydalanuvchi rejimida ishlaydigan jarayonlar xostga ko'rinmaydi. Bu odatiy Docker konteyneriga o'xshamaydi, bu holda xost mashinasi har doim ombor ichidagi jarayonlarni ko'radi. Mening serverlarimdan birining ushbu qismiga qarang:

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

Va buni foydalanuvchi rejimida Linux yadrosining pstree bilan solishtiring:

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

Docker konteynerlari bilan ishlashda men xostdan mehmonda ishlayotgan jarayonlarning nomlarini ko'rishim mumkin. Linux foydalanuvchi rejimi bilan bu mumkin emas. Bu nima degani? Bu shuni anglatadiki, Linux audit quyi tizimi orqali ishlaydigan monitoring vositalari ko'rmayapman mehmon tizimida ishlaydigan jarayonlar. Ammo ba'zi hollarda bu xususiyat ikki qirrali qilichga aylanishi mumkin.

Umuman olganda, quyida keltirilgan barcha post tadqiqot va kerakli natijaga erishish uchun qo'pol urinishlar to'plamidir. Buning uchun men turli xil qadimiy vositalardan foydalanishim, yadro manbalarini o'qishim, hali boshlang'ich maktabda bo'lgan paytlarimda yozilgan kodni intensiv disk raskadrovka qilishim, shuningdek, menga kerak bo'lgan vositalarni topish uchun maxsus binar yordamida Heroku tuzilmalari bilan shug'ullanishim kerak edi. . Bu ishlarning barchasi mening ARMdagi yigitlarni meni sehr deb atashlariga olib keldi. Umid qilamanki, ushbu maqola yangi yadrolar va OS versiyalari bilan bir xil narsani sinab ko'rish uchun ishonchli hujjat bo'lib xizmat qiladi.

moslashish

Linux foydalanuvchi rejimini sozlash bir necha bosqichda amalga oshiriladi:

  • xostga bog'liqliklarni o'rnatish;
  • Linux yadrosini yuklab olish;
  • yadro qurish konfiguratsiyasi;
  • yadro yig'ilishi;
  • ikkilik o'rnatish;
  • mehmon fayl tizimini sozlash;
  • yadroni ishga tushirish parametrlarini tanlash;
  • mehmon tarmog'ini o'rnatish;
  • mehmon yadrosini ishga tushirish.

O'ylaymanki, agar siz buni o'zingiz qilishga qaror qilsangiz, Ubuntu yoki Debian-ga o'xshash tizimda tasvirlangan hamma narsani qilishingiz mumkin. Men yuqorida aytilganlarning barchasini o'zimning sevimli distributorim - Alp tog'larida amalga oshirishga harakat qildim, lekin Linux yadrosida foydalanuvchi rejimidagi drayverlar uchun qattiq bog'langan glibc-ismlarga ega bo'lganligi sababli hech narsa chiqmadi. Muammoni nihoyat tushunganimdan so'ng, men bu haqda yuqori oqimga xabar berishni rejalashtirmoqdaman.

Xostga bog'liqliklarni o'rnatish

Ubuntu Linux yadrosini yaratish uchun kamida quyidagi paketlarni talab qiladi (toza o'rnatishda):

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

Siz ularni quyidagi buyruq bilan o'rnatishingiz mumkin (root yoki sudo bilan):

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

E'tibor bering, Linux yadro menyusini o'rnatish dasturini ishga tushirish uchun o'rnatish kerak bo'ladi libncurses-dev. Iltimos, u quyidagi buyruq bilan o'rnatilganligiga ishonch hosil qiling (root yoki sudo bilan):

apt-get -y install libncurses-dev

Yadro yuklab olish

Qaerdan yuklab olishni va yadroni qurishni hal qiling. Ushbu operatsiyani bajarish uchun siz qattiq diskda taxminan 1,3 Gb bo'sh joy ajratishingiz kerak, shuning uchun sizda borligiga ishonch hosil qiling.

O'tgandan keyin kernel.org va oxirgi barqaror yadroni yuklab olish uchun URL manzilini oling. Yozish paytida bu: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

yordamida ushbu faylni yuklab oling 'wget':

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

Va uni chiqarib oling 'tar':

tar xJf linux-5.1.16.tar.xz

Endi biz tarballni ochishda yaratilgan katalogga kiramiz:

cd linux-5.1.16

Yadro qurishni sozlash

Yadro qurish tizimi to'plamdir Makefayllar с ko'p jarayonni avtomatlashtirish uchun maxsus vositalar va skriptlar. Birinchidan, interaktiv sozlash dasturini oching:

make ARCH=um menuconfig

U siz uchun dialog oynasini qisman quradi va ko'rsatadi. Qachon '[Select]', siz Bo'sh joy yoki Enter tugmalari yordamida sozlashingiz mumkin. Odatdagidek, "yuqoriga" va "pastga" klaviatura strelkalari bilan oynada harakatlaning va elementlarni tanlang - "chap" yoki "o'ng".

Ko'rish ko'rsatkichi —> siz Enter tugmasi orqali kiradigan pastki menyuda ekanligingizni bildiradi. Undan chiqish yo'li aniq "[Exit]'.

'ga quyidagi variantlarni kiriting[Select]' va ularning yonida '[*]' borligiga ishonch hosil qiling:

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

Hammasi shunday, ketma-ket ' ni tanlash orqali bu oynadan chiqishingiz mumkin.[Exit]'. Oxirida sizdan konfiguratsiyani saqlash so'ralganiga ishonch hosil qiling va "ni tanlang"[Yes]'.

Men ushbu postni o'qib chiqqandan so'ng yadro yaratish imkoniyatlari bilan o'ynashni tavsiya qilaman. Ushbu tajribalar orqali siz past darajadagi yadro mexanikasi ishini va uni yig'ishda turli bayroqlarning ta'sirini tushunish nuqtai nazaridan ko'p narsalarni o'rganishingiz mumkin.

Yadro qurish

Linux yadrosi ko'p narsalarni bajaradigan katta dasturdir. Qadimgi uskunada bunday minimal konfiguratsiya bo'lsa ham, uni qurish ancha vaqt talab qilishi mumkin. Shunday qilib, yadroni quyidagi buyruq bilan yarating:

make ARCH=um -j$(nproc)

Nima uchun? Ushbu buyruq bizning quruvchimizga barcha mavjud protsessor yadrolari va ish zarralarini qurish jarayonida foydalanishni aytadi. Jamoa $(nproc) Build oxirida buyruqning natijasini almashtiradi nproc, qismi bo'lgan coreutils standart Ubuntu tuzilishida.

Biroz vaqt o'tgach, bizning yadromiz bajariladigan faylga kompilyatsiya qilinadi ./linux.

Binarni o'rnatish

Linuxda User Mode oddiy ikkilik faylni yaratganligi sababli, uni boshqa har qanday yordamchi dastur kabi o'rnatishingiz mumkin. Buni qanday qildim:

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

Bunga ham ishonch hosil qilishga arziydi ~/bin sizning ichingizda $PATH:

export PATH=$PATH:$HOME/bin

Mehmon fayl tizimini sozlash

Mehmon fayl tizimi uchun katalog yarating:

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

alpinelinux.org va saytni oching yuklab olish bo'limi haqiqiy yuklab olish havolasini toping MINI ROOT FILESYSTEM. Yozish paytida bu:

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

Wget yordamida ushbu tarballni yuklab oling:

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

Endi mehmon fayl tizimining katalogini kiriting va arxivni chiqarib oling:

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

Ta'riflangan harakatlar kichik fayl tizimi shablonini yaratadi. Tizimning tabiatiga ko'ra, Alpine apk menejeri orqali paketlarni o'rnatish juda qiyin bo'ladi. Ammo bu FS umumiy fikrni baholash uchun etarli bo'ladi.

Bizga ham vosita kerak kalay xotira sarfini cheklash uchun zombi jarayonlari bizning mehmon yadrosi.

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

Yadro buyruq qatorini yaratish

Linux yadrosi, boshqa dasturlar kabi, buyruq qatori argumentlariga ega, ularga kalitni ko'rsatish orqali kirish mumkin. --help.

O'zi - yordam

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.

Ushbu panel ishga tushirishning asosiy parametrlarini ta'kidlaydi. Yadroni minimal talab qilinadigan variantlar to'plami bilan ishga tushiramiz:

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

Yuqoridagi satrlar yadromizga quyidagilarni aytadi:

  • Ildiz fayl tizimi psevdo qurilma deb faraz qiling /dev/root.
  • Tanlang hostfs ildiz fayl tizimi drayveri sifatida.
  • Biz yaratgan mehmon fayl tizimini ildiz qurilmasiga o'rnating.
  • Va ha, o'qish-yozish rejimida.
  • Faqat 64 MB operativ xotiradan foydalaning (siz nima qilishni rejalashtirganingizga qarab kamroq foydalanishingiz mumkin, lekin 64 MB optimal miqdor kabi ko'rinadi).
  • Yadro avtomatik ravishda ishga tushadi /bin/sh qanday init-jarayon.

Ushbu buyruqni ishga tushiring va siz quyidagi kabi narsalarni olishingiz kerak:

Yana bitta varaq

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

Yuqoridagi manipulyatsiyalar bizga beradi kamida mehmon tizimi, kabi narsalarsiz /proc yoki tayinlangan xost nomi. Masalan, quyidagi buyruqlarni sinab ko'ring:

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

Mehmondan chiqish uchun yozing exit yoki control-d tugmasini bosing. Bu qobiqni o'ldiradi, undan keyin yadro vahima paydo bo'ladi:

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

Bizda yadro vahima paydo bo'ldi, chunki Linux yadrosi ishga tushirish jarayoni doimo ishlayotgan deb o'ylaydi. Busiz tizim endi ishlay olmaydi va ishdan chiqadi. Lekin bu foydalanuvchi rejimidagi jarayon bo'lgani uchun, natijada olingan natija o'zini o'zi yuboradi SIGABRT, bu esa chiqishga olib keladi.

Mehmon tarmog'ini sozlash

Va bu erda narsalar noto'g'ri keta boshlaydi. Linux foydalanuvchi rejimida tarmoq bu erda cheklangan "foydalanuvchi rejimi" tushunchasi parchalana boshlaydi. Axir, odatda tizim darajasida tarmoq cheklangan imtiyozli barchamiz uchun tushunarli sabablarga ko'ra ijro rejimlari.

Eslatma. boshiga: UML-da tarmoq bilan ishlashning turli xil variantlari haqida ko'proq o'qishingiz mumkin shu yerda.

Slirpga sayohat

Biroq, deb nomlangan qadimiy va deyarli qo'llab-quvvatlanmaydigan vosita mavjud Slirp, uning yordamida Linux foydalanuvchi rejimi tarmoq bilan o'zaro aloqada bo'lishi mumkin. U foydalanuvchi darajasidagi TCP/IP stekiga o'xshab ishlaydi va ishlash uchun tizim ruxsatini talab qilmaydi. Bu vosita edi 1995 yilda chiqarilgan, va oxirgi yangilanish sanasi 2006 yil. Slirp juda eski. Qo'llab-quvvatlash va yangilanishlarsiz vaqt davomida kompilyatorlar shu qadar uzoqqa borishdiki, endi bu vositani faqat shunday ta'riflash mumkin kod chirishi.

Keling, Slirpni Ubuntu omborlaridan yuklab olib, uni ishga tushirishga harakat qilaylik:

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)

Ey xudolar. Keling, Slirpning tuzatuvchisini o'rnatamiz va bu erda nima sodir bo'layotganini bilib olamizmi:

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.

Xato bizning ichimizda bu qator. Keling, stacktrace-ni ko'rib chiqaylik, ehtimol u erda bizga biror narsa yordam beradi:

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

Bu erda biz slirp taym-autlarni tekshirishga harakat qilganda, asosiy tsiklning boshlanishi paytida nosozlik sodir bo'lishini ko'ramiz. Shu nuqtada, men disk raskadrovka qilishdan voz kechishim kerak edi. Ammo keling, sortlardan qurilgan Slirp ishlaydimi yoki yo'qligini bilib olaylik. Men arxivni to'g'ridan-to'g'ri saytdan qayta yuklab oldim sourceforge, chunki u erdan buyruq satri orqali biror narsani sudrab olish og'riqdir:

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

Bu erda biz aniqlanmagan o'rnatilgan funktsiyalar haqida ogohlantirishlarni ko'ramiz, ya'ni natijada olingan ikkilik faylni bog'lashning mumkin emasligi haqida. Ko'rinishidan, 2006 yildan bu vaqtgacha gcc oraliq kompilyatsiya qilingan fayllarning o'rnatilgan funktsiyalarida ishlatiladigan belgilarni ishlab chiqarishni to'xtatgan. Keling, kalit so'zni almashtirishga harakat qilaylik inline bo'sh sharhda va natijaga qarang:

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

Yoq. Bu ham ishlamaydi. Haligacha bu funksiyalar uchun belgilar topa olmadi.

Shu nuqtada men taslim bo'ldim va Githubga qaray boshladim Heroku paketlarini qurish. Mening nazariyam shundan iborat ediki, ba'zi Heroku qurish paketlari menga kerak bo'lgan ikkilik fayllarni o'z ichiga oladi. Oxir-oqibat, qidiruv meni olib keldi mana shu yerda. Men yuklab oldim va ochdim uml.tar.gz va quyidagilarni topdi:

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*

Bu slirp ikkilik! U ishlaydimi?

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

U tushmaydi - shuning uchun u ishlashi kerak! Keling, bu ikkilik faylni o'rnatamiz ~/bin/slirp:

cp slirp ~/bin/slirp

Paket yaratuvchisi uni olib tashlagan taqdirda, I oyna yasadi.

Tarmoqni sozlash

Endi mehmon yadrosida tarmoqni o'rnatamiz. Ishga tushirish variantlarini yangilang:

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

Endi tarmoqni yoqamiz:

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

Birinchi ikkita konfiguratsiya buyrug'i /proc и /sys ish uchun zarur ifconfig, bu Slirp bilan aloqa qilish uchun tarmoq interfeysini o'rnatadi. Jamoa route barcha trafikni Slirp tunnel orqali yuborishga majburlash uchun yadro marshrutlash jadvalini o'rnatadi. Buni DNS so'rovi bilan tekshiramiz:

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

U ishlaydi!

Eslatma: Ko'rinishidan, asl xabar ish stolida simli tarmoq kartasi yoki qo'shimcha drayverlarni talab qilmaydigan boshqa konfiguratsiya bilan yozilgan. Intel-dan WiFi 8265-ga ega noutbukda tarmoqni ko'tarishda xatolik yuz beradi

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

Ko'rinishidan, yadro tarmoq kartasi drayveri bilan aloqa qila olmaydi. Mikrodasturni yadroga kompilyatsiya qilishga urinish, afsuski, vaziyatni tuzatmadi. Nashr qilingan vaqtda ushbu konfiguratsiyada yechim topish mumkin emas edi. Oddiy konfiguratsiyalarda (masalan, Virtualbox-da) interfeys to'g'ri ko'tariladi.

Qayta yo'naltirishni quyidagi qobiq skripti bilan avtomatlashtiramiz:

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

Va uni bajariladigan deb belgilang:

chmod +x init.sh

Keyin yadro buyruq satriga o'zgartirishlar kiritamiz:

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

Va yana takrorlaymiz:

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

Tarmoq barqaror!

docker fayli

Bularning barchasini tekshirishni osonlashtirish uchun men to'pladim Docker fayli, bu tasvirlangan qadamlarning ko'pini avtomatlashtiradi va sizga ishlaydigan konfiguratsiyani berishi kerak. Menda ham bor oldindan tuzilgan yadro, bu postda tasvirlangan hamma narsaga ega. Ammo shuni tushunish kerakki, men bu erda faqat minimal sozlamalarni ko'rsatdim.

Umid qilamanki, ushbu post sizga mehmon yadrosini qanday oshirishni tushunishga yordam berdi. Bu qandaydir yirtqich hayvon bo'lib chiqdi, ammo nashr ushbu oilaning operatsion tizimlarining zamonaviy versiyalarida Linuxda foydalanuvchi rejimini yaratish, o'rnatish va sozlash bo'yicha to'liq qo'llanma sifatida ishlab chiqilgan. Keyingi qadamlar mehmonlar tizimida allaqachon xizmatlar va boshqa dasturlarni o'rnatishni o'z ichiga olishi kerak. Docker konteyner tasvirlari shunchaki ommaga e'lon qilingan tarballlar bo'lgani uchun siz tasvirni orqali chiqarib olishingiz kerak docker export, va keyin mehmon yadrosi fayl tizimining ildizida uning o'rnatish yo'lini aniqlang. Xo'sh, keyin qobiq skriptini bajaring.

Freenode-dagi #lobsters-dan Rkeene-ga alohida rahmat. Uning yordamisiz Slirpni disk raskadrovka qilishda men bu qadar uzoqqa erishmagan bo'lardim. Uning Slackware tizimi slirp bilan qanday to'g'ri ishlashini bilmayman, lekin mening Ubuntu va Alp tizimlarim slirpni qabul qilmadi va ikkilik Rkeene menga taklif qildi. Lekin men uchun hech bo'lmaganda biror narsa ishlayotgani etarli.

Manba: www.habr.com

a Izoh qo'shish