Pi як VPN-клієнт: один менеджер чи власний скрипт?
Порівняйте профіль NetworkManager із написаним вручну клієнтським скриптом на Raspberry Pi, включно з повним тунелем, DNS, IPv6 і поведінкою, коли тунель падає.
Raspberry Pi, якому треба захищати лише власний вихідний трафік, має два реалістичні варіанти: дозволити мережевому менеджеру володіти тунелем або тримати скрипт, який ним володіє. Обидва можуть передавати трафік. Вони відмовляють у різних місцях, і збій, який ви можете діагностувати віддалено о другій годині ночі, — той, який варто обрати. Порівняйте їх за володінням, за тим, що означає повний тунель, коли задіяні IPv6 і DNS, і за тим, що відбувається в момент падіння тунелю.
Два власники одного тунелю
Варіант A — це профіль усередині мережевого менеджера системи: імпортований профіль OpenVPN або нативне з’єднання WireGuard, яке під час завантаження активує та сама служба, що піднімає Ethernet і Wi-Fi. Варіант B — ваша власна одиниця, яка запускає клієнт безпосередньо, редагує конфігурацію резолвера й встановлює власні маршрути та правила брандмауера. Обидва законні; вони різняться тим, кому дозволено змінювати таблицю маршрутизації.
Збої різняться, бо різняться власники. За A профіль, що не активується, залишає інтерфейс піднятим, а тунель опущеним, і журнали менеджера кажуть чому. За B скрипт, що вдався наполовину, залишає маршрути, які переживають процес, що їх створив. Запускати обидва — найгірший результат: два процеси пишуть маршрут за замовчуванням, дві правки резолвера змагаються під час завантаження, і два набори секретів треба ротувати.
Виберіть одного власника на тунель і вимкніть іншого, перш ніж щось тестувати. Два власники означають і два місця, куди дивитися, коли тунель піднятий і нічого не розв’язується. Це єдине правило запобігає більшості заплутаних станів, описаних у обговореннях Pi VPN.
Що створює імпорт, а що ні
У Raspberry Pi OS Bookworm і новіших стандартний інструмент налаштування мережі — NetworkManager, тож профіль є природним домом для клієнтського тунелю. Імпорт потребує встановленого відповідного плагіна; без нього імпорт завершується повідомленням про непідтримуваний тип з’єднання, що й є чесним сигналом зупинитися й установити плагін.
nmcli connection import type openvpn file ./provider.ovpn
nmcli connection show
nmcli --ask connection up id provider-name
Імпорт зберігає профіль. Він не доводить доступність іншого боку й не гарантує, що кожна директива у файлі пережила перетворення. Прочитайте отримане з’єднання й перевірте частини, що несуть ідентичність і довіру: сертифікат, віддалений хост і порт, а також чи запитується пароль чи він зберігається.
Активація з --ask тримає парольну фразу поза історією оболонки на спільній машині. Для Pi без нагляду ви зрештою захочете, щоб профіль піднімався під час завантаження, а це окреме рішення від одноразового підняття вручну.
Повний тунель у порівнянні обох варіантів
Повний тунель — це твердження про маршрути, а не про намір, і два варіанти виражають його по-різному. Підхід із профілем просить менеджер установити маршрут за замовчуванням і свої налаштування резолвера; підхід зі скриптом робить те, що каже скрипт, включно з нічим. Жоден варіант не покриває IPv6, якщо йому не сказано, і недоторканий маршрут IPv6 за замовчуванням охоче понесе трафік поза тунелем, поки IPv4 виглядає бездоганно.
ip -4 route get 198.51.100.23
ip -6 route show default
resolvectl query example.org
Для пошуку маршруту використовуйте адресу з документації й підставте хост, який вам дозволено перевіряти. Перша команда показує, який інтерфейс Pi використав би для звичайного призначення; друга показує, чи ще існує маршрут IPv6 за замовчуванням; третя доводить, який резолвер відповів. Прочитайте всі три, перш ніж вірити будь-якому твердженню про повний тунель.
Якщо інструкції провайдера обіцяють повний тунель, але маршрут IPv6 за замовчуванням залишається, Pi протікає. Вимкніть IPv6 на висхідному каналі або попросіть профіль заявити його, і вирішіть свідомо, а не виявляйте це пізніше.
Відкрита відмова проти закритої
Коли тунель падає, таблиця маршрутизації, що втрачає маршрут за замовчуванням, просто повертається до фізичного висхідного каналу, і трафік іде відкрито. Це відкрита відмова, і це типова поведінка обох варіантів, якщо щось не заважає. Більшість людей виявляють це через тижні, читаючи журнал брандмауера.
Закрита відмова забирає у вас віддалений доступ, коли тунель опущений, тож їй потрібен свідомий виняток для шляху керування. Один зі способів — правило, що дозволяє поза тунелем лише адресу партнера VPN:
sudo nft add table inet vpnkill
sudo nft 'add chain inet vpnkill out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet vpnkill out oifname != "tun0" ip daddr != 203.0.113.24 reject
Порівняйте експлуатаційні витрати чесно. Профіль зазвичай не може виразити це правило, тож закрита відмова штовхає вас до варіанта зі скриптом або до невеликої одиниці, яка встановлює правило незалежно від тунелю. У будь-якому разі тиждень записуйте відмови: тиха відмова виглядає так само, як зламана служба, і лічильник знадобиться, коли користувач повідомить, що один сайт перестав завантажуватися.
Вибір для Pi без екрана
Якщо образ уже запускає NetworkManager, тунель не потребує нічого екзотичного і ви хочете, щоб він автоматично йшов за висхідним каналом, беріть профіль. Якщо вам потрібне маршрутизування за політиками, кілька тунелів, що вибираються за призначенням, або правило закритої відмови, яке має існувати до підняття тунелю, беріть скрипт і володійте кожною його частиною, включно з порядком завантаження й очищенням. Змішування двох варіантів коштує дорожче за кожен окремо.
Перехід між ними — переважно питання порядку: вимкніть старого власника, переконайтеся, що не залишилося застарілого маршруту чи запису резолвера, потім увімкніть нового й перезавантажтеся двічі. Одне перезавантаження може приховати гонку, яку викриває друге. Завершіть перевіркою Pi, а не тунелю: розв’яжіть ім’я, отримайте щось через IPv4, отримайте через IPv6, якщо ви його зберегли, потім упустіть тунель і підтвердіть, що обрана поведінка справді настає. Інтерфейс у ip link — початок перевірки, а не кінець.