Ізоляція Linux від прямих Інтернет з'єднань на базі QEMU / Virtual Machine Manager з VSOCK

В матеріалі наведено приклад ізоляції віртуальної операційної системи Linux (та відповідно - усіх її програм) від вхідних та вихідних з'єднань в Інтернет, без додаткових правил в iptables. Зв'язок передбачається виключно засобами локальної мережі Yggdrasil з використанням технології VSOCK (https://man7.org/linux/man-pages/man7/vsock.7.html), а Інтернет-інтерфейс - буде відсутній як такий.

Кому потрібен доступ в Інтернет, це можна зробити окремо - засобами локальних проксі DNS та дзеркал репозиторіїв. Тобто, така система не буде "сліпою" та з певними доопрацюваннями буде здатна оновлюватись і взаємодіяти зі світом, але робити це без витоків через дірки софту та пропущені опції в конфігах.

Нижче розглядається налаштування засобами GUI Virtual Machine Manager (https://virt-manager.org), що зручно для десктоп образів. Користувачі CLI, зокрема системні адміністратори - можуть цей допис не читати.

VSOCK

З документації: технологія VSOCK - забезпечує взаємодію між віртуальними машинами та вузлом, на якому вони виконуються. Це адресне сімейство використовується гостьовими агентами та службами супервізора, яким потрібен канал зв'язку, що не залежить від налаштувань мережі віртуальної машини.

Тобто ми вимикаємо усі мережеві інтерфейси, а для підключення до Yggdrasil - будемо використовувати локальний сокет VSOCK, який розшарено з хосту на гостьову систему (або системи) для побудови його локального дерева маршрутизації.

Yggdrasil

Так як конфігурація передбачає взаємодію виключно з мережею Yggdrasil, нам потрібно спочатку зібрати версію роутера, яка має підтримку протоколу VSOCK. Я віднайшов форк:

можливо, він втратить свою актуальність з часом або ж буде включений до апстріму в рамках PR#1223

Як на хості, так і на гостьовій системах, збирається наступним чином:

git clone https://github.com/nagy/yggdrasil-go.git
cd yggdrasil-go
git checkout vsock
./build
# опціонально встановлюється за призначенням
# install yggdrasil /usr/local/bin/yggdrasil
# install yggdrasilctl /usr/local/bin/yggdrasilctl

Налаштування модифікованого роутера майже нічим не відрізняється від базового, за тим лише виключенням, що на хост машині (де запускаються гостьові віртуалки) потрібно додати прослуховування сокету:

#/etc/yggdrasil.conf
Listen: [
vsock://host:1234
]

Перед продовженням, важливо перезапустити роутер Yggdrasil, оскільки потрібно, щоб він забіндився на вказаному інтерфейсі "vsock://host:1234"

Virtual Machine Manager

Тут вже може бути встановлено операційну систему, тому перед тим як продовжити, запустимо її та встановимо такий само форк Yggdrasil за інструкцією вище.

Після встановлення роутера, Інтернет більше не потрібен, вимикаємо гостьову систему та повертаємось до налаштувань VM. Сторінка налаштувань (Show virtual hardware details) знаходиться там де значок лампи у вікні образу

Virtual Machine Manager: Show virtual hardware details

звідки знаходимо NAT (або Route) інтерфейс і видаляємо через контекстне меню "Remove hardware" правим кліком миші; видаляємо всі "девайси" зі значком дво-направленої стрілки, що мають відношення до мережі

Virtual Machine Manager: Remove hardware

В низу вікна, натискаємо кнопку "Add hardware"

Virtual Machine Manager: Add hardware

шукаємо там "VirtIO VSOCK" та додаємо його до конфігурації з відміченою галкою "Guest CID: Auto"

Virtual Machine Manager: VirtIO VSOCK

Тепер можна запустити гостьову систему кнопкою "Power on the virtual machine" і перемкнутись на режим перегляду:

Virtual Machine Manager: Power on the virtual machine / Show the graphical console

Наступні дії виконуються в середині гостьової машини!

Після завантаження, вже має бути відсутній Інтернет - так і треба, але якщо у вас Yggdrasil автоматично запускається з systemd, його інтерфейс (стандартно tun0) має бути активним:

ifconfig

# lo
# tun0 - Yggdrasil

Нагадаю, форк роутера з підтримкою VSOCK для гостьової системи ми вже встановили раніше, тож додамо наш батьківський "vsock://host:1234" але цього разу не в "Listen" а в "Peers":

#/etc/yggdrasil.conf
Peers: [
vsock://host:1234
]

Перезапускаємо сервіс Yggdrasil та перевіряємо підключення до сокету:

sudo yggdrasilctl getpeers

вивід має бути приблизно таким:

URI                State  Dir  IP Address    Uptime  RTT     RX     TX     Down  Up  Pr  Cost Last Error
vsock://host:1234  Up     Out  200:xxxx:..   2m59s   1.61ms  1.8KB  0.6KB  -     -   0   1    -

Оверлейний пір батьківського хосту підключено, а отже тепер можна підключатись до всіх вузлів мережі Yggdrasil, без наявності Інтернет в гостьовій системі. Тобто можна безпечно качати торенти з увімкненими DHT, PEX, якщо ви десь в ЄС або просто приватно сьорфити локальну мережу без жодних додаткових налаштувань софта типу PAC для Firefox:

Безпечний перегляд сайтів Yggdrasil з Yggstack

Про те, як налаштувати локальний DNS і репозиторії, щоб зробити систему здатною до оновлень (через локальні проксі) - згодом. Стосовно DNS, я частково описував свою конфігурацію в матеріалі:

Мій пресет Alfis DNS на роутері Yggdrasil / Mycelium

звідки можна взяти приклади, замінивши Інтернет резольвери на локальні:

Взагалі думки такі, що було б не погано мати готовий образ системи, що адаптований для роботи виключно засобами певних локальних мереж. Але це вже інша історія.