Добавете правило за политика с 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

Желаният резултат е същата политика със собственик, пресъздадена, и остаряло състояние, пенсионирано, което е по-трайно от повторно добавяне на шел правило след всяко свързване. Запазете един ред в записа за промени, който назовава файла, притежаващ правилото, и версията, която го поддържа. Тогава следващият инженер може да намери политиката, без да рови в историята на шела. Правило, което никой не притежава, е правило, което ще бъде изгубено отново.

Подобни статии