Збережіть правило ip rule після повторного підключення з systemd-networkd
Правило ip, додане з оболонки, зникає під час наступної події з'єднання. Оголосіть правило, його таблицю та маршрути в systemd-networkd, щоб політика створювалася заново.
Додайте правило політики через ip rule, і воно працює, доки з'єднання не зникне; у цей момент його просто немає. Ніщо не впало зі звуком: стан ядра змінився, і жоден власник конфігурації не знав, що правило має існувати. У цьому вся різниця між правилом, яке виживає, і тим, яке ні. На хості з systemd-networkd рішення — дати правилу власника, а не повторювати команду після кожного повторного підключення.
Правило існує лише тоді, коли в нього є власник
Політика маршрутизації ядра — це стан, а не конфігурація. Вона живе в системі, що працює, і все, що руйнує інтерфейс, від якого вона залежить, може забрати її з собою. Команда в оболонці змінює цей стан і не залишає жодного запису про намір.
Мережеві менеджери працюють навпаки: вони читають конфігурацію, застосовують її та застосовують знову, коли подія з'єднання робить попередній стан недійсним. Правило, оголошене в їхній конфігурації, створюється заново, а правило, додане поруч, — це чужий об'єкт без власника.
У цієї відмінності є ім'я в networkd, і його варто прочитати, перш ніж щось вмикати. Чужі правила в нових версіях типово видаляються, що дивує тих, хто очікував, що їхні ручні записи залишаться.
Прочитайте версію, перш ніж довіряти налаштуванню
Поведінкою володіння керує налаштування в networkd.conf, і цього налаштування немає в старих випусках systemd. Перевірте встановлену версію, перш ніж проєктувати навколо неї, бо старий хост поводиться інакше, ніж документація, яку ви читаєте.
Важливі два значення. Одне вирішує, чи видаляються правила, не оголошені в конфігурації networkd, а друге робить те саме для маршрутів. Обидва стосуються володіння, а не змісту політики, і обидва типово обирають суворішу поведінку в поточних випусках. Глобальне вимкнення зберігає життя кожному чужому правилу, а це значно ширше рішення, ніж оголосити одну потрібну політику VPN.
systemctl --version | head -1
networkctl --version | head -1
grep -R "ManageForeign" /etc/systemd/ /usr/lib/systemd/ 2>/dev/null
Цей grep каже, що задано локально і яке типове значення постачальника. Відсутність теж є інформацією, бо означає, що діє скомпільоване значення. Запишіть його в нотатки, щоб наступній людині не довелося відкривати його знову.
Оголосіть правило й таблицю, на яку воно вказує
Правило у файлі .network називає таблицю, і це все, що робить ім'я. Воно не створює маршрути всередині цієї таблиці й не перевіряє, чи мають вони сенс. Оголошення правила без маршрутів дає політику, яка зіставляє трафік і потім відкидає його.
Оголосіть маршрути в тому ж файлі, з досяжними наступними переходами та правильною таблицею. Збережіть пріоритет в оголошеному правилі, щоб воно потрапило туди, де ви очікуєте, у впорядкованому списку. Правило, яке досягає хибної таблиці раніше запланованого, змінює більше трафіку, ніж служба, яку ви хотіли виправити. Читайте фрагмент нижче як форму, а не як повний файл, бо володіння інтерфейсом і решта з'єднання все ще мають бути наявні.
[RoutingPolicyRule]
Family=ipv4
IPProtocol=tcp
SourcePort=443
Table=100
Priority=1000
[Route]
Destination=10.80.0.0/24
Gateway=10.80.0.1
Table=100
Потім перезавантажте й прочитайте стан ядра, а не файл. Конфігурація, розібрана чисто, все одно може дати правило, якого ви не планували, і обидва подання збігаються лише тоді, коли оголошення було повним.
Виберіть одного власника для інтерфейсу
Два менеджери на одному тунелі створюють боротьбу, яка виглядає як помилка в обох. Імпорт наявного налаштування wg-quick у networkd — це міграція, а не доповнення, і запуск обох залишає інтерфейс та його правила під двома власниками.
Зробіть міграцію за один прохід: зупиніть старий юніт, вимкніть його, оголосіть інтерфейс і його маршрути в networkd, потім перезавантажте. Перевірте, що старий юніт не може повернутися під час завантаження. Залишковий юніт, який знову активується після перезавантаження, перезаписує стан, який ви щойно оголосили. Тримайте старий файл конфігурації, доки новий не переживе повторне підключення, а потім виведіть його з ужитку.
Володіння міткою заслуговує на таку саму турботу: якщо правило збігається з міткою міжмережевого екрана, щось має ставити цю мітку. Правило, що посилається на мітку, яку ніхто не ставить, — це мертва конфігурація, яка виглядає навмисною.
Відпрацюйте події життєвого циклу
Конфігурація варта стільки, скільки варта її поведінка протягом подій. Опустіть з'єднання, підніміть його, перезапустіть службу й оновіть адресу. Після кожного з них прочитайте список правил і вміст таблиці.
sudo networkctl reload
ip rule show
ip route show table 100
sudo systemctl restart systemd-networkd
Запланований результат — та сама політика з власником, створена заново, і застарілий стан, виведений з ужитку, що міцніше, ніж знову додавати правило оболонки після кожного повторного підключення. Тримайте один рядок у журналі змін, де названо файл, що володіє правилом, і версію, яка його підтримує. Тоді наступний інженер зможе знайти політику, не риючись в історії оболонки. Правило, яким ніхто не володіє, — це правило, яке знову буде втрачено.