Немає tun0? Зіставте розшифрований IPsec у nftables за допомогою meta ipsec
Шлюз на основі політик пересилає відкриті внутрішні пакети, які досі надходять на eth0. Зіставляйте шлях безпеки й службу, а не відсутній інтерфейс.
Ви чекаєте інтерфейс тунелю, шукаєте його, а в міжмережевому екрані немає чого зіставляти. Це нормально для шлюзу на основі політик: зашифрований обмін надходить на фізичний інтерфейс, і розшифрований внутрішній пакет, який потім пересилається, теж спостерігається як такий, що надходить на той самий інтерфейс. tun0 немає, бо ніщо його не створило.
Внутрішній запит залишається окремим пакетом із власним джерелом, призначенням і службою, і ядро знає, з якої асоціації безпеки він вийшов. Саме ці знання й може зіставити правило міжмережевого екрана.
Два пакети, один інтерфейс
Уявіть вхідний напрямок. Надходить пакет, інкапсульований в ESP або UDP, ядро знаходить відповідну політику, розшифровує його й передає відкритий пакет на шлях пересилання. Правило, яке дивиться лише на ім'я інтерфейсу, не може відрізнити цей пакет від будь-якого іншого трафіку, що надходить тим самим дротом.
Відрізняє його контекст вхідного шляху безпеки, прикріплений до пакета. nftables показує його як meta ipsec exists, що є істинним, коли пакет надійшов через шлях безпеки IPsec. Поєднайте його з пулом клієнтів, призначенням і службою, і правило стане достатньо конкретним, щоб бути безпечним.
Оминути контекст — типова помилка, і це помилка безпеки, а не косметична. Правило, яке приймає все з пулу клієнтів, так само охоче прийме підроблений пакет із локальної мережі, бо адреса джерела сама по собі нічого не доводить. Контекст шляху безпеки — найдешевший спосіб зробити джерело осмисленим. Пишіть правило з ним від самого початку, а не додавайте після аудиту.
Напишіть правило пересилання
Припустімо, є автентифікована служба віддаленого доступу IPv4 з клієнтами в 10.90.0.0/24 і одне схвалене призначення на 203.0.113.40. Фрагмент правила для цього потоку виглядає так.
meta ipsec exists ip saddr 10.90.0.0/24 \
ip daddr 203.0.113.40 tcp dport 443 \
oifname "eth0" counter accept
Адреси та інтерфейс — це приклади для заміни. Розмістіть перевірений еквівалент у політиці пересилання перед правилом, яке інакше відхилило б потік, і не очищайте наявний набір правил, щоб його встановити; шлюз — не експеримент у чистій кімнаті.
Термін oifname варто зберегти. Він документує рішення про вихід і не дає правилу збігтися в напрямку, якого ви не мали на увазі, а це важливо на шлюзі з кількома шляхами до інтернету. На тестовій машині з одним висхідним каналом термін здається зайвим, і саме тому його прибирають раніше, ніж машина отримає другий канал.
Дозволи для зовнішнього обміну окремі. Вхідному шляху шлюзу потрібні порти IKE і ESP або інкапсуляції UDP, які він справді використовує, і ці дозволи нічого не дозволяють щодо розшифрованого пакета всередині. Змішувати одне з одним — це шлях, яким робочий тунель опиняється з міжмережевим екраном, що пересилає все.
Вхідний контекст — не вихідний контекст
Те саме сімейство виразів охоплює інший напрямок через rt ipsec, який описує вихідну асоціацію безпеки, яку використає пакет. Він відповідає на інше питання: не звідки прийшов цей пакет, а чи буде він захищений на наступній ділянці.
Ця різниця важлива на шлюзі, який одночасно завершує один тунель і пересилає до іншого. Пакет може надійти розшифрованим і все ж має піти зашифрованим, а дозвіл, написаний лише для вхідного контексту, нічого не каже про вихідну вимогу. Якщо політика вимагає такого захисту, набір правил має це висловити, а не припускати, що маршрутизація дасть раду.
Тримайте два питання в окремих правилах, щоб читач бачив, яке з них застосовується. Одне хитромудре правило, що перевіряє обидва, важче переглянути й значно важче налагодити, коли одна його половина перестає збігатися. Два правила з лічильниками також повідомляють, яка вимога не виконується, чого об'єднане правило ніколи не зробить.
NAT — це не рішення міжмережевого екрана
Трафіку в інтернет із приватного пулу клієнтів зазвичай потрібен переклад джерела, щоб відповідь знайшла зворотний шлях. Але трафік, вибраний для іншої вихідної політики IPsec, повинен зберегти потрібний виняток, і маскування кожного приватного джерела без думки про наступне рішення щодо захисту це ламає.
Дозвіл усередині ланцюжка NAT теж не є загальним дозволом. NAT і фільтрування мають різні завдання, і ланцюжок NAT не переглядає кожен наступний пакет встановленого потоку, і саме тому розрахунок на нього в питаннях безпеки дає правила, які виглядають робочими в тесті й відмовляють під навантаженням.
Зворотне теж правда і застає людей зненацька: дозвіл десь в одному базовому ланцюжку фільтрування нічого не важить проти пізнішого відхилення в іншому застосовному ланцюжку. Результат визначають порядок і обсяг ланцюжка, а не наявність дозволу у файлі.
Перевірте точну внутрішню службу
Перевірте конкретне призначення й порт, які ви дозволили, зі справжнього клієнта й переконайтеся, що відповідь повертається. Потім перевірте щось, чого ви не дозволяли, і переконайтеся, що воно не проходить, бо занадто широке правило проходить першу перевірку так само добре, як правильне. Запит, який узагалі не залишає клієнта, теж не є результатом міжмережевого екрана, тож читайте лічильники, щоб побачити, чи пакет узагалі оцінювався. Дві перевірки й одне читання лічильника розкажуть більше, ніж цілий день читання набору правил.
Довідник nftables документує meta ipsec, rt ipsec і вирази, залежні від напрямку, і саме там перевіряють синтаксис щодо встановленої версії. І тримайте обсяг явним: це приклад IPv4, він нічого не каже про IPv6 і не перетворює довільне пересилання публічних портів на частину служби VPN.