portaldacalheta.pt
  • Основен
  • Инженерно Управление
  • Мобилен Дизайн
  • Разпределени Екипи
  • Пъргав
Технология

Тревожност при разделяне: Урок за изолиране на вашата система с пространства от имена на Linux



С появата на инструменти като Докер , Linux контейнери и други стана изключително лесно да се изолират Linux процеси в собствените им малки системни среди. Това прави възможно стартирането на цял набор от приложения на една истинска машина на Linux и гарантира, че нито едно от тях не може да си пречи помежду си, без да се налага да прибягва до използване на виртуални машини. Тези инструменти бяха огромно благо за PaaS доставчици. Но какво точно се случва под капака?

Тези инструменти разчитат на редица функции и компоненти на ядрото на Linux. Някои от тези функции бяха въведени сравнително наскоро, докато други все още изискват да поправите самото ядро. Но един от ключовите компоненти, използващ пространства от имена на Linux, е функция на Linux от пускането на версия 2.6.24 през 2008 г.



Всеки, запознат с chroot вече има основна идея за това какво могат да направят пространствата от имена на Linux и как да използва пространството от имена като цяло. Точно както chroot позволява на процесите да виждат произволна директория като корен на системата (независимо от останалите процеси), пространствата от имена на Linux позволяват и други аспекти на операционната система да бъдат независимо модифицирани. Това включва дървото на процесите, мрежовите интерфейси, точките за монтиране, комуникационните ресурси между процесите и други.

Защо да използваме пространства от имена за изолиране на процеси?

В еднопотребителски компютър може да се оправи една системна среда. Но на сървър, където искате да стартирате множество услуги, е от съществено значение за сигурността и стабилността услугите да са възможно най-изолирани една от друга. Представете си сървър, изпълняващ множество услуги, една от които се компрометира от нарушител. В такъв случай натрапникът може да бъде в състояние да експлоатира тази услуга и да си проправи път към другите услуги и дори може да компрометира целия сървър. Изолирането на пространството от имена може да осигури сигурна среда за премахване на този риск.



Например, използвайки пространството от имена, е възможно безопасно да изпълнявате произволни или неизвестни програми на вашия сървър. Напоследък нараства броят на програмните състезания и платформи за „хакатон“, като HackerRank , TopCoder , Codeforces , и много други. Много от тях използват автоматизирани тръбопроводи за стартиране и валидиране на програми, подадени от състезателите. Често е невъзможно да се знае предварително истинската същност на програмите на състезателите, а някои дори могат да съдържат злонамерени елементи. Чрез стартирането на тези програми, разположени в пълна изолация от останалата част на системата, софтуерът може да бъде тестван и валидиран, без да се излага на риск останалата част от машината. По подобен начин онлайн услугите за непрекъсната интеграция, като например Drone.io , автоматично извличат вашето хранилище на кодове и изпълняват тестовите скриптове на собствените си сървъри. Отново, изолирането на пространството от имена е това, което прави възможно предоставянето на тези услуги безопасно.

Инструментите за пространство на имена като Docker също позволяват по-добър контрол върху използването на системните ресурси от процесите, което прави тези инструменти изключително популярни за използване от доставчиците на PaaS. Услуги като Heroku и Google App Engine използвайте такива инструменти за изолиране и стартиране на множество уеб сървърни приложения на един и същ реален хардуер. Тези инструменти им позволяват да стартират всяко приложение (което може да е било внедрено от някой от множество различни потребители), без да се притесняват дали някой от тях ще използва твърде много системни ресурси или ще се намесва и / или ще влиза в конфликт с други внедрени услуги на същата машина. С такава изолация на процеса е възможно дори да има изцяло различни купчини софтуер за зависимост (и версии) за всяка изолирана среда!



Ако сте използвали инструменти като Docker, вече знаете, че тези инструменти могат да изолират процеси в малки „контейнери“. Изпълнението на процеси в контейнерите на Docker е като тяхното изпълнение във виртуални машини, само че тези контейнери са значително по-леки от виртуалните машини. Виртуалната машина обикновено емулира хардуерен слой върху вашата операционна система и след това изпълнява друга операционна система отгоре на това. Това ви позволява да стартирате процеси във виртуална машина, в пълна изолация от вашата реална операционна система. Но виртуалните машини са тежки! Докер контейнерите, от друга страна, използват някои ключови характеристики на вашата реална операционна система, включително пространства от имена, и осигуряват подобно ниво на изолация, но без да емулират хардуера и да изпълняват друга операционна система на същата машина. Това ги прави много леки.

Процесно пространство от имена

В исторически план ядрото на Linux поддържа едно дърво на процесите. Дървото съдържа препратка към всеки процес, който в момента се изпълнява в йерархия родител-дете. Процесът, при условие че има достатъчни привилегии и отговаря на определени условия, може да инспектира друг процес, като прикачи трасиращ елемент към него или дори да успее да го убие.



как се прави програмиране на c++

С въвеждането на пространства от имена на Linux стана възможно да има множество „вложени“ дървета на процеси. Всяко дърво на процеса може да има изцяло изолиран набор от процеси. Това може да гарантира, че процесите, принадлежащи към едно дърво на процесите, не могат да проверяват или убиват - всъщност дори не могат да знаят за съществуването на - процеси в други братя и сестри или родителски дървета на процеси.

Всеки път, когато компютър с Linux се стартира, той стартира само с един процес, с идентификатор на процеса (PID) 1. Този процес е коренът на дървото на процеса и той инициира останалата част от системата, като извършва подходяща работа по поддръжката и стартира правилните демони / услуги. Всички останали процеси започват под този процес в дървото. Пространството от имена на PID позволява да се отдели ново дърво със собствен PID 1 процес. Процесът, който прави това, остава в родителското пространство на имената, в оригиналното дърво, но прави детето корена на собственото си дърво на процеса.



С изолацията на пространството от имена на PID процесите в дъщерното пространство на имена не могат да знаят за съществуването на родителския процес. Процесите в родителското пространство на имена обаче имат пълен изглед на процесите в дъщерното пространство на имена, сякаш са някакъв друг процес в родителското пространство на имена.

Този урок за пространство на имена очертава разделянето на различни дървета на процеси, използващи системи за пространства от имена в Linux.



Възможно е да се създаде вложен набор от детски пространства от имена: един процес стартира дъщерен процес в ново пространство от имена на PID, а този процес се появява още един процес в ново пространство от имена на PID и т.н.

С въвеждането на PID пространства от имена, един процес вече може да има множество PID, свързани с него, по един за всяко пространство от имена, под което попада. В изходния код на Linux, можем да видим че структура с име pid, която преди е проследявала само един PID, сега проследява множество PID чрез използването на структура с име upid:



struct upid { int nr; // the PID value struct pid_namespace *ns; // namespace where this PID is relevant // ... }; struct pid { // ... int level; // number of upids struct upid numbers[0]; // array of upids };

За да създадете ново PID пространство от имена, трябва да се обадите на clone() системно повикване със специален флаг CLONE_NEWPID. (C предоставя обвивка за излагане на това системно повикване, както и много други популярни езици.) ​​Докато другите пространства от имена, обсъдени по-долу, също могат да бъдат създадени с помощта на unshare() системно повикване, PID пространство от имена може да бъде създадено само в момента, в който се създава нов процес, използвайки clone() Веднъж clone() се извиква с този флаг, новият процес веднага стартира в ново PID пространство от имена, под ново дърво на процеса. Това може да бъде демонстрирано с проста програма на C:

#define _GNU_SOURCE #include #include #include #include #include static char child_stack[1048576]; static int child_fn() { printf('PID: %ld ', (long)getpid()); return 0; } int main() pid_t child_pid = clone(child_fn, child_stack+1048576, CLONE_NEWPID

Компилирайте и стартирайте тази програма с права на root и ще забележите изход, който прилича на този:

clone() = 5304 PID: 1

PID, както е отпечатан от child_fn, ще бъде 1.

Въпреки че този урок на пространството от имена по-горе не е много по-дълъг от „Здравей, свят“ на някои езици, много неща се случиха зад кулисите. clone() функция, както бихте очаквали, е създала нов процес чрез клониране на текущия и е започнала изпълнението в началото на child_fn() функция. Въпреки това, докато го правеше, той отдели новия процес от оригиналното дърво на процеса и създаде отделно дърво на процеса за новия процес.

Опитайте да замените static int child_fn() функция със следното, за да отпечатате родителския PID от гледна точка на изолирания процес:

static int child_fn() { printf('Parent PID: %ld ', (long)getppid()); return 0; }

Изпълнението на програмата този път дава следния резултат:

създаване на уебсайт с angularjs
clone() = 11449 Parent PID: 0

Забележете как родителският PID от гледна точка на изолирания процес е 0, което означава, че няма родител. Опитайте да стартирате същата програма отново, но този път премахнете CLONE_NEWPID флаг от clone() извикване на функция:

pid_t child_pid = clone(child_fn, child_stack+1048576, SIGCHLD, NULL);

Този път ще забележите, че родителският PID вече не е 0:

clone() = 11561 Parent PID: 11560

Това обаче е само първата стъпка в нашия урок. Тези процеси все още имат неограничен достъп до други общи или споделени ресурси. Например мрежовият интерфейс: ако дъщерният процес, създаден по-горе, трябва да слуша на порт 80, това ще попречи на всеки друг процес в системата да може да слуша на него.

Пространство от имена на Linux мрежа

Това е мястото, където мрежовото пространство от имена става полезно. Мрежовото пространство от имена позволява на всеки от тези процеси да вижда изцяло различен набор от мрежови интерфейси. Дори интерфейсът за обратна връзка е различен за всяко пространство от имена на мрежата.

Изолирането на процес в собственото му пространство от имена включва въвеждане на друг флаг в clone() извикване на функция: CLONE_NEWNET;

#define _GNU_SOURCE #include #include #include #include #include static char child_stack[1048576]; static int child_fn() { printf('New `net` Namespace: '); system('ip link'); printf(' '); return 0; } int main() SIGCHLD, NULL); waitpid(child_pid, NULL, 0); return 0;

Изход:

Original `net` Namespace: 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp4s0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:24:8c:a1:ac:e7 brd ff:ff:ff:ff:ff:ff New `net` Namespace: 1: lo: mtu 65536 qdisc noop state DOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Какво става тук? Физическото Ethernet устройство enp4s0 принадлежи към пространството от имена на глобалната мрежа, както е посочено от инструмента “ip”, ​​стартиран от това пространство от имена. Физическият интерфейс обаче не е наличен в новото мрежово пространство от имена. Освен това, устройството за обратна връзка е активно в оригиналното пространство на имената на мрежата, но е „надолу“ в пространството на имената на дъщерната мрежа.

За да се осигури използваем мрежов интерфейс в дочерното пространство на имената, е необходимо да се създадат допълнителни „виртуални“ мрежови интерфейси, които обхващат множество пространства от имена. След като това бъде направено, тогава е възможно да се създадат Ethernet мостове и дори да се маршрутизират пакети между пространствата от имена. И накрая, за да работи цялото нещо, трябва да се изпълнява „процес на маршрутизиране“ в пространството на имената на глобалната мрежа, за да получава трафик от физическия интерфейс и да го насочва през подходящите виртуални интерфейси към правилните пространства на имена на дъщерни мрежи. Може би можете да разберете защо инструменти като Docker, които правят всичко това за вас, са толкова популярни!

Мрежовото пространство от имена на Linux се състои от процес на маршрутизиране към множество детски нетни пространства от имена.

За да направите това на ръка, можете да създадете двойка виртуални Ethernet връзки между родителско и дъщерно пространство от имена, като изпълните една команда от родителското пространство на имената:

ip link add name veth0 type veth peer name veth1 netns

Тук трябва да бъде заменен с идентификатора на процеса на процеса в дъщерното пространство на имената, както се наблюдава от родителя. Изпълнението на тази команда установява подобна на тръба връзка между тези две пространства от имена. Родителското пространство на имената запазва veth0 устройство и предава veth1 устройство към дъщерното пространство от имена. Всичко, което влезе в единия край, излиза през другия край, точно както бихте очаквали от истинска Ethernet връзка между два реални възела. Съответно и на двете страни на тази виртуална Ethernet връзка трябва да бъдат назначени IP адреси.

Монтирайте пространство от имена

Linux също така поддържа структура на данни за всички точки на монтиране на системата. Той включва информация като какви дискови дялове са монтирани, къде са монтирани, дали са само за четене и т.н. С пространствата от имена на Linux може да се клонира тази структура от данни, така че процесите под различни пространства от имена да могат да променят точките на монтиране, без да се засягат взаимно.

Създаването на отделно пространство за имена на монтиране има ефект, подобен на правенето на chroot(). chroot() е добре, но не осигурява пълна изолация и ефектите му са ограничени само до основната точка на монтиране. Създаването на отделно пространство от имена на монтиране позволява на всеки от тези изолирани процеси да има напълно различен изглед на цялата структура на монтиране на системата от оригиналния. Това ви позволява да имате различен корен за всеки изолиран процес, както и други точки на монтиране, които са специфични за тези процеси. Използвани внимателно според този урок, можете да избегнете излагането на каквато и да е информация за основната система.

Да научите как правилно да използвате пространството от имена има множество предимства, както е посочено в този урок за пространство на имена.

clone() флаг, необходим за постигане на това е CLONE_NEWNS:

clone(child_fn, child_stack+1048576, CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS | SIGCHLD, NULL)

Първоначално дъщерният процес вижда точно същите точки на монтиране, както би го видял неговият родителски процес. Въпреки това, тъй като е под ново пространство за имена на монтиране, дъщерният процес може да монтира или демонтира каквито и да е крайни точки, които иска, и промяната няма да засегне нито пространството от имена на родителя, нито друго пространство за име на монтиране в цялата система. Например, ако родителският процес има определен дял на диска, монтиран в корен, изолираният процес ще види точно същия дял на диска, монтиран в корена в началото. Но ползата от изолирането на пространството от имена на монтиране е очевидна, когато изолираният процес се опитва да промени основния дял на нещо друго, тъй като промяната ще засегне само изолираното пространство от имена на монтиране.

Интересното е, че всъщност това е лоша идея да се хвърли хайвел на целевия процес на дете директно с CLONE_NEWNS флаг. По-добрият подход е да започнете специален „init“ процес с CLONE_NEWNS флаг, накарайте този процес „init“ да промени „/“, „/ proc“, „/ dev“ или други точки на монтиране, както желаете, и след това стартирайте целевия процес. Това се обсъжда малко по-подробно в края на този урок за пространство от имена.

Други пространства от имена

Има и други пространства от имена, в които тези процеси могат да бъдат изолирани, а именно потребител, IPC и UTS. Потребителското пространство на имената позволява на процеса да има права на root в пространството на имената, без да му предоставя този достъп до процеси извън пространството от имена. Изолирането на процес от IPC пространството на имената му дава собствени междупроцесови комуникационни ресурси, например System V IPC и POSIX съобщения. Пространството от имена на UTS изолира два специфични идентификатора на системата: nodename и domainname.

Бърз пример за показване на това как е изолирано пространството от имена на UTS е показано по-долу:

#define _GNU_SOURCE #include #include #include #include #include #include static char child_stack[1048576]; static void print_nodename() { struct utsname utsname; uname(&utsname); printf('%s ', utsname.nodename); } static int child_fn() { printf('New UTS namespace nodename: '); print_nodename(); printf('Changing nodename inside new UTS namespace '); sethostname('GLaDOS', 6); printf('New UTS namespace nodename: '); print_nodename(); return 0; } int main() SIGCHLD, NULL); sleep(1); printf('Original UTS namespace nodename: '); print_nodename(); waitpid(child_pid, NULL, 0); return 0;

Тази програма дава следния изход:

Original UTS namespace nodename: XT New UTS namespace nodename: XT Changing nodename inside new UTS namespace New UTS namespace nodename: GLaDOS Original UTS namespace nodename: XT

Тук, child_fn() отпечатва nodename, променя го на нещо друго и го отпечатва отново. Естествено, промяната се случва само в новото пространство на имена на UTS.

Повече информация за това, което предоставят и изолират всички пространства от имена, можете да намерите в урока тук

angularjs урок за начинаещи стъпка по стъпка

Комуникация между кръстосаните имена

Често е необходимо да се установи някакъв вид комуникация между пространството от имена на родителя и детето. Това може да е за извършване на работа по конфигуриране в изолирана среда, или може просто да запази способността да надникне в състоянието на тази среда отвън. Един от начините да направите това е да поддържате демон на SSH да работи в тази среда. Можете да имате отделен SSH демон във всяко мрежово пространство от имена. Наличието на множество SSH демони, използващи много ценни ресурси като памет. Това е мястото, където специалният „init“ процес се оказва отново добра идея.

Процесът „init“ може да установи комуникационен канал между родителското пространство на имената и дъщерното пространство на имената. Този канал може да се основава на UNIX сокети или дори да използва TCP. За да създадете UNIX сокет, който обхваща две различни пространства от имена на монтиране, първо трябва да създадете дъщерния процес, след това да създадете UNIX сокет и след това да изолирате детето в отделно пространство за имена на монтиране. Но как можем първо да създадем процеса и да го изолираме по-късно? Linux осигурява unshare() . Това специално системно извикване позволява на процеса да се изолира от оригиналното пространство на имена, вместо родителят да изолира детето на първо място. Например, следният код има точно същия ефект като кода, споменат по-рано в раздела за мрежови имена:

#define _GNU_SOURCE #include #include #include #include #include static char child_stack[1048576]; static int child_fn() { // calling unshare() from inside the init process lets you create a new namespace after a new process has been spawned unshare(CLONE_NEWNET); printf('New `net` Namespace: '); system('ip link'); printf(' '); return 0; } int main() SIGCHLD, NULL); waitpid(child_pid, NULL, 0); return 0;

И тъй като процесът „init“ е нещо, което сте измислили, можете първо да го накарате да извърши цялата необходима работа и след това да се изолира от останалата част на системата, преди да изпълни целевото дете.

Заключение

Този урок е само преглед на това как да използвате пространства от имена в Linux. Тя трябва да ви даде основна представа как a Разработчик на Linux може да започне да прилага системна изолация, неразделна част от архитектурата на инструменти като Докер или Linux контейнери. В повечето случаи би било най-добре просто да използвате един от тези съществуващи инструменти, които вече са добре познати и тествани. Но в някои случаи може да има смисъл да имате свой собствен, персонализиран механизъм за изолиране на процеса и в този случай този урок за пространство от имена ще ви помогне изключително много.

Под капака има много повече неща, отколкото съм разгледал в тази статия, и има повече начини, по които може да искате да ограничите целевите си процеси за допълнителна безопасност и изолация. Но, надяваме се, това може да послужи като полезна отправна точка за някой, който се интересува да знае повече за това как наистина работи изолирането на пространството от имена с Linux.

Защо повече предприемачи избират да натрупват средства за търсене пред стартиращи фирми

Финансови Процеси

Защо повече предприемачи избират да натрупват средства за търсене пред стартиращи фирми
Влиянието на Брекзит върху сектора на финансовите услуги

Влиянието на Брекзит върху сектора на финансовите услуги

Финансови Процеси

Популярни Публикации
Плащане напред: Разбиране на изкупувания с ливъридж
Плащане напред: Разбиране на изкупувания с ливъридж
Индустриален анализ и Porter’s Five Force: По-задълбочен поглед върху силата на купувача
Индустриален анализ и Porter’s Five Force: По-задълбочен поглед върху силата на купувача
Разширена реалност vs. Виртуална реалност vs. Смесена реалност: Уводно ръководство
Разширена реалност vs. Виртуална реалност vs. Смесена реалност: Уводно ръководство
Ще отвори ли Spotify не-IPO пътя за технологичните компании?
Ще отвори ли Spotify не-IPO пътя за технологичните компании?
Прогнозиране на харесвания: Вътре в алгоритмите на прост механизъм за препоръки
Прогнозиране на харесвания: Вътре в алгоритмите на прост механизъм за препоръки
 
Ефективни стартови платки: какви са те и как да ги изградим
Ефективни стартови платки: какви са те и как да ги изградим
Ръководител на клиентския опит
Ръководител на клиентския опит
Игла в купа сено: чудесен урок за мащабен текстов алгоритъм за търсене
Игла в купа сено: чудесен урок за мащабен текстов алгоритъм за търсене
Структурата на данните Trie: Пренебрегван скъпоценен камък
Структурата на данните Trie: Пренебрегван скъпоценен камък
Краят на уеб формите
Краят на уеб формите
Популярни Публикации
  • кристал (език за програмиране)
  • какво причинява изтичане на памет
  • Урок за тестване на модули в android studio
  • как да създадете рамка
  • изтичане на памет в пример с Java
  • __________ е подреждането и външния вид на буквите в графичния дизайн.
Категории
  • Инженерно Управление
  • Мобилен Дизайн
  • Разпределени Екипи
  • Пъргав
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt