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

Три роли, които в момента споделят всичко

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

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

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

Разделете три роли, а не три процеса

Три госта на един хост дават три набора от права и три мрежови позиции. Те не дават три домейна на отказ и дизайнът трябва да го каже на глас.

Разделението помага само ако компрометирането на един гост не дава автоматично права на останалите, а това е настройка на хипервизора, а не конвенция за имена. Назоваването на една ВМ шлюз не пречи на друг гост да достигне хоста. Четете конфигурацията на виртуалния комутатор вместо името на хоста и после потвърдете, че всеки гост стои там, където мислите.

host
├─ vpn-gw      10.60.10.2/24   public 51820/udp only
├─ services    10.60.0.10/24   no route to the management network
└─ ci-runner   10.60.20.2/24   outbound only, no host socket

Запишете топологията и после я проверете с инструментите, които я притежават. Гост, който се появи на грешния бридж, е находка, а не подробност. Коригирайте мрежата, преди да промените каквато и да е конфигурация на услуга.

Нека гостът VPN отваря само вратите, които притежава

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

Мрежата от частната страна трябва да достига услугите, от които отдалечените потребители се нуждаят, и да спира там. Удостоверяването на приложението остава включено, защото тунелът е транспорт, а не вход. Дръжте таблицата за маршрутизация на госта VPN достатъчно малка, за да се опише с едно изречение. Ако не можете да я опишете толкова просто, границата вече е размита.

virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'

Всичко, което слуша на хоста и не е нужно за управление, не трябва да слуша изобщо. Това включва API на хипервизора, който лесно остава открит на публичен интерфейс.

Задачите за сборка се нуждаят от различен вид граница

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

Изпълнителите на контейнери са по-тесни, а привилегированият контейнер не е от тесните. Дръжте runner-а в отделен гост със собствен мрежов обхват и му дайте само достъпа до артефакти и разгръщане, който задачите изискват. Еднократните работници намаляват запазеното състояние; те не намаляват достижимостта или излагането на тайни. И двете все още се нуждаят от явни ограничения.

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

Планирайте отказа, който и трите споделят

Един хост е един домейн на отказ. Рестартът премахва тунела и всяка частна услуга в един и същ момент и точно тогава пътят навътре е най-важен.

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

virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'

Редът на стартиране на процесите не доказва нищо за маршрутите и DNS, затова тествайте пътя, а не състоянията на unit-ите. Пътят е това, от което отдалеченият потребител наистина се нуждае.

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