LXD предоставя символно устройство от хоста на контейнер чрез добавяне на устройствен възел, а не като учи госта да създава такъв. Ако контейнерът няма /dev/net/tun, устройството може да е на хоста и гостът пак да не може да го отвори. Записът unix-char е половината от този път на страната на мениджъра и е умишлено по-тесен от привилегирован контейнер. Затова възелът на хоста и възелът на контейнера заслужават отделни проверки.

Механизмът е достатъчно кратък, за да се държи в полезрението: LXD решава път на хоста, създава съответен възел вътре в инстанцията и добавя устройството към cgroup за устройства на контейнера. След това процесът на госта се нуждае от собствено разрешение и способност, за да използва възела за каквото и да е.

Какво всъщност променя записът unix-char

Устройство unix-char казва на LXD да предостави едно символно устройство от хоста на избран път в контейнера. Записът има три важни части: етикетът на устройството, който използва мениджърът, пътят source на хоста и path, който вижда гостът. Само последните две описват самото устройство. Печатна грешка в което и да е от тях създава възел на място, което клиентът никога не отваря.

На хоста устройството обикновено е /dev/net/tun. В контейнера можете да запазите същия път или да изберете друг, но пътят трябва да съвпада с това, което очаква VPN клиентът. Запазването на /dev/net/tun избягва втори проблем с конфигурацията, защото повечето клиенти отварят този път без да питат.

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

Декларирайте устройството в инстанцията, а не в госта

Добавете записа от административния контекст на LXD, като назовете инстанцията и етикет, който да разпознаете по-късно. За контейнер с име vpnbox командата е:

lxc config device add vpnbox tun unix-char source=/dev/net/tun path=/dev/net/tun
lxc config device show vpnbox

Етикетът tun е локален за конфигурацията на инстанцията. Той не е име на интерфейс и не трябва да съвпада с нищо в госта. Ако профил вече предоставя същото устройство, добавянето на втори запис създава конфликт, а не излишък, затова първо прегледайте ефективната конфигурация.

Редактирането на файлове в контейнера е грешният слой. mknod в стартов скрипт може да изглежда, че работи в привилегирован контейнер, после да изчезне при пресъздаване или да се провали в по-малко привилегирован. Мениджърът притежава набора от устройства на инстанцията; нека притежава и възела.

Съобразете собствеността и режима с процеса на госта

Записът unix-char може да зададе uid, gid и mode за възела в контейнера. Използвайте ги, за да съответстват на акаунта, който стартира VPN клиента, вместо да отваряте устройството за всеки потребител или да превключвате контейнера в привилегирован режим.

Видимостта не е същото като разрешение. Възел, притежаван от root с режим 600, е видим за услугата, работеща като непривилегирован потребител, и пак не може да бъде отворен от нея. Проверете първо акаунта на госта, после задайте собствеността на този акаунт и дръжте режима не по-широк, отколкото клиентът изисква.

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

Знайте какво не дава записът

Видим възел не е работещ VPN. Пакетът на клиента все още трябва да се инсталира, профилът все още трябва да е валиден и услугата все още трябва да стартира. Удостоверяването, маршрутите и DNS остават работа на клиента и провал там не е доказателство, че записът на устройството е грешен.

systemd може да добави още едно ограничение. Модул с DeviceAllow или затегната политика за устройства може да откаже достъп до възел, който мениджърът на контейнери е предоставил. Проверете политиката за устройства на модула, когато възелът съществува, но услугата съобщава грешка за разрешение, и променете тази политика, вместо да разширявате контейнера.

Горещото включване е незадължително и явно. Запис с required=false изисква път на източника и може да се появи или изчезне при промяна на устройството на хоста. Такъв жизнен цикъл подхожда на хардуер, който идва и си отива; за TUN устройство, което VPN изисква при зареждане, незадължителен запис може да остави услугата да стартира преди да съществува предпоставката ѝ.

Проверете видимост, отваряне и интерфейс в този ред

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

lxc exec vpnbox -- ls -l /dev/net/tun
lxc exec vpnbox -- sh -c 'test -c /dev/net/tun && echo char-device-ok'

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

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

Подобни статии