Нові з'єднання на новому виході VPN, старі потоки залишаються як є
Планове зливання переміщує лише некласифіковані потоки. Порівняйте це з заміною маршруту та подивіться на позначки, таблиці й стан conntrack, які це утримують.
Два здорові виходи VPN, одне довге завантаження вже виконується, і вимога, щоб наступне з'єднання використовувало інший тунель. Є два способи це виконати, і лише один із них безпечний на робочому шлюзі. Заміна маршруту за замовчуванням переміщує кожен пакет, зокрема ті, що належать завантаженню. Планове зливання змінює вибір для нових з'єднань і залишає відстежувані потоки на шляху, де вони почалися.
Два способи перемкнути вихід
Заміна маршруту — це одна команда, і її можна відкотити за секунди, тому її використовують під час інцидентів. Вона також невибіркова: пакети наявного завантаження раптом виходять через інший тунель, з іншою публічною адресою джерела й окремим станом трансляції.
Якщо віддалений бік відстежує потоки за адресою джерела, завантаження може просто перестати розпізнаватися. Зливання уникає цього, ухвалюючи рішення один раз на з'єднання й зберігаючи його, тому старе завантаження зберігає свій вихід до завершення. У цьому вся цінність вправи: віддалений бік не бачить жодних змін, які йому треба інтерпретувати. Він продовжує отримувати пакети, що відповідають з'єднанню, яке він уже знає.
Ціна — складність: дві таблиці маршрутизації, класифікатор, що працює на потрібному хуку, і позначки, які треба узгодити з усім іншим на машині, що їх використовує.
Дайте кожному виходу власну таблицю
Зарезервуйте таблицю маршрутизації для кожного виходу та різні значення позначок або біти для двох варіантів. Кожній таблиці потрібні маршрути, доречні її ролі, а не лише ім'я, і їй потрібен навмисний результат збою для відсутнього випадку. Порожня таблиця, що мовчки провалюється в основну таблицю — так трафік виходить через вихід, якого ніхто не вибрав.
ip rule add fwmark 0x10/0x10 table 101
ip rule add fwmark 0x20/0x20 table 102
ip route add default via 192.0.2.1 dev wg-a table 101
ip route add default via 198.51.100.1 dev wg-b table 102Додайте маршрут blackhole в кінець кожної таблиці, щоб пошук без збігу голосно зазнавав невдачі, а не тікав до маршруту за замовчуванням, який ви не вибирали.
Виберіть один раз, на першому пакеті
Класифікуйте після того, як з'явилося відстеження з'єднань, і перед тим пошуком маршруту, що має значення. Для нового, некласифікованого з'єднання LAN виберіть вихід і збережіть його в стані з'єднання. На наступних пакетах відновіть збережене значення в позначку пакета, яку читає маршрутизація за політикою.
Тонкість у тому, що означає нове. Conntrack усе ще може повідомляти NEW для ранніх пакетів і повторних передач, доки не побачено відповідь, тому класифікатор, що спирається лише на цей стан, може перезаписати вже зроблений вибір. Перед призначенням перевірте, що для з'єднання не збережено жодного виходу.
nftables тримає позначки пакета й з'єднання окремо, і посібник з метаінформації документує явне копіювання між ними. Позначка з'єднання сама не стає позначкою пакета, з якою збігається ваше правило, і це найчастіша причина, чому ретельно написаний класифікатор не дає ефекту.
Обмежте відновлення тим напрямком і трафіком, які ви маєте на увазі. Застосування позначки інтернет-виходу до пакетів, що повертаються, може надіслати відповіді до виходу замість LAN, і симптом — однобічне з'єднання, що виглядає як проблема брандмауера. Прочитайте шлях відповіді, перш ніж торкатися правила брандмауера, бо пакет маршрутизується, просто не назад до відправника.
Чотири фази зливання
Підготуйте B, не торкаючись A: маршрутизація, пересилання, авторизація, NAT і зворотний шлях. Установіть його таблицю й політику вибору через наявного власника конфігурації шлюзу.
Перемкніть класифікатор, щоб нові, некласифіковані з'єднання вибирали B, зберігаючи збережені вибори. Атомарна транзакція nftables уникає вікна, у якому треба очистити старий стан.
Залиште A увімкненим, доки його потоки не завершаться. Його інтерфейс, таблиця, віддалений вихід і зіставлення NAT досі є частиною цих потоків, а редагування правила NAT не перебудовує вже наявні прив'язки.
Виведіть A з експлуатації, коли умову зливання виконано, судячи зі стану з'єднань і поведінки застосунку, а не з одного тихого інтервалу.
Чого зливання не може обіцяти
Запит браузера — це не нове транспортне з'єднання; об'єднання продовжує надсилати запити старим. Навпаки, потік UDP може застаріти з conntrack, і пізніший пакет класифікується заново. Зливання йде за відстежуваними потоками, а не за уявленням застосунку про сеанс.
Якщо A відмовить до завершення його потоків, збережена позначка їх не врятує. Вони перепідключаються через B або не перепідключаються взагалі. Планове зливання купує безперервність, доки початковий шлях здоровий; це не реплікація стану між незалежними виходами.
Перевірте обидві половини
Запустіть тривале дозволене з'єднання до зміни й справді нове після неї. Підтвердьте, який тунель використовує кожне й яку публічну адресу джерела бачить віддалений бік, потім перевірте, що зворотний трафік повертається.
Не очищайте таблицю conntrack, щоб новий вибір з'явився. Це знищує саме той стан, який зливання має зберегти, і перетворює контрольовану міграцію на збій із чисто виглядаючим тестом.