Уявіть медіаприставку на домашньому каналі, яка має виходити в інтернет лише через тунель. Коли тунель падає, застосунок має зупинитися, а не тихо продовжувати через фізичний інтерфейс. Отримати таку поведінку — це завдання міжмережевого екрана, а не маршрутизації, і різниця важлива, бо маршрут можна замінити перезапуском демона, а фільтр лишається там, куди ви його поставили. Далі — як шлях пакета насправді ухвалює рішення і як потім обмежити винятки, які дозволяють тунелю перепідключатися.

Локальний вихід — це інший гак, ніж пересилання

Пакет, що залишає застосунок на машині, проходить через вихідний гак; пакет, який машина маршрутизує для іншого хоста, проходить через пересилання. Політика, що згадує лише forward, обмежує другий випадок і залишає перший широко відкритим, тому стільки замків виходу виглядають правильними й нічого не роблять. Зіставлення інтерфейсу належить до того самого правила: oifname "tun0" accept пропускає трафік, який уже було маршрутизовано через тунель. Маршрутизація та фільтрування також лишаються окремими рішеннями, тож маршрут до провайдера може існувати, поки фільтр відхиляє пакет. Саме на цей поділ ви й покладаєтеся.

Шлюзу, який пересилає трафік інших пристроїв, потрібні обидва гаки. Замикання лише виходу захищає саму машину і залишає кожному клієнту нижче свободу витікати.

Список винятків пишіть від кінцевої точки назовні

Почніть із кінцевої точки тунелю: одна адреса призначення або невеликий затверджений набір, транспортний протокол і порт призначення, наприклад udp dport 1194 ip daddr 203.0.113.7 accept. Якщо клієнт розв'язує ім'я хоста, початковому обміну DNS потрібне власне правило, обмежене розв'язувачем і портом 53, а не загальний дозвіл на адресу цього розв'язувача. Кожен виняток має називати причину свого існування. Дозвіл на весь UDP-трафік до порту VPN покриває значно більше, ніж та єдина автентифікована служба, яку ви мали на думці.

Початкове розв'язування імен — це місце, де замки зазвичай гниють. Набір адрес, що оновлюється за таймером, потребує визначеної поведінки, коли оновлення не вдається, і цією поведінкою не може бути відкриття каналу до успіху. Оновлюйте через тунель, поки тунель піднятий, інакше повертайтеся до останньої відомої справної кінцевої точки.

Локальне адміністрування потребує того самого підходу. Керівна підмережа не заслуговує довіри лише тому, що її адреси приватні, а правило, яке їй довіряє, запрошує другий шлях навколо замка.

Зіставлення інтерфейсу не доводить справність тунелю

Правила, які приймають усе, що виходить із tun0, припускають, що пакет на цьому інтерфейсі прийшов із тунелю. Імена інтерфейсів перестворюються, а ім'я не є криптографічною ідентичністю. Партнер також може зникнути, поки інтерфейс лишається піднятим, і тоді правило перетворюється на вельми переконливу бездіяльність.

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

Що переживає падіння демона

Фільтр, встановлений скриптом, який запускається після підняття тунелю, зникає разом із тунелем — саме в той момент, коли він був потрібен. Завантажуйте замок під час старту і дозвольте демону керувати лише його винятками.

Видалення маршруту за замовчуванням теж не заміна. Маршрут — це стан, яким володіє й який переписує демон, і його видалення може забрати шлях, потрібний для перепідключення. IPv6 потребує власного плану, бо виявлення сусідів і оголошення маршрутизатора — це служби каналу, які мають продовжувати працювати, поки звичайний трафік заблоковано. DHCP належить до тієї самої категорії. Запишіть це як винятки з метою, а не виявляйте пізніше як збої.

Шлях відновлення перед упровадженням

Перевірте замок так, як він відмовить: завантаження без тунелю, убивство демона, зміна кінцевої точки й перепідключення. Кожен випадок має зупиняти застосунки й залишати канал відновлення працездатним. Робіть це з консолі, бо віддалена оболонка — це сеанс, який найчастіше замикається вашим же правилом.

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

Схожі статті