Имах лабораторна машина, която приемаше тунел от отдалечен сайт и същевременно набираше до мрежа на доставчик. Изходящият профил работеше от седмици. След добавянето на входящия сървър изходящият се свърза и след това спря да пропуска трафик в рамките на секунди или отказа да стартира с грешка „адресът се използва“. Конфигурационните файлове не бяха променени; хостът просто се сдоби с втори процес на OpenVPN със собствено мнение за портове и маршрути.

Отказът не е случаен и не е проблем с удостоверяването. Два демона на една машина се състезават за един и същ локален сокет и една и съща таблица за маршрутизиране и този, който стартира или се свърже последен, обикновено печели. Знанието кое от тези две стълкновения имате решава къде да погледнете първо.

Прочетете симптома наобратно

Започнете с момента, в който тунелът умира. Грешка при обвързване при стартиране сочи към страната на слушане: нещо вече притежава този порт и OpenVPN отказва да стартира, вместо да го сподели. Тунел, който се вдига и след това замлъква, сочи към маршрутизирането, защото маршрут, инсталиран от другата инстанция, може да издърпа пакетите на външната връзка от пътя им.

И двата случая пораждат една и съща жалба от потребителя, затова циклите за повторен опит и скриптовете за наблюдение не поправят нищо. Те свързват клиента отново в същия конфликт. Полезният първи въпрос е дали процесът все още работи, когато трафикът спре.

Един сокет и едно устройство на инстанция

Слушащият сървър обвързва своя порт; изходящият клиент също се нуждае от локален порт за своя инкапсулиран трафик. Когато и двата живеят на един и същ хост, поведението по подразбиране на клиента може да се сблъска с порта на сървъра. Локалният порт на клиента може да бъде закрепен и обвързването може да се пропусне там, където партньорът не се нуждае от фиксиран изходен порт:

lport 1195
nobind
dev tun1

Тези числа са примери, а не изискване. Важното е клиентът да спре да се състезава за порта на сървъра и всяка инстанция да получи отделно тунелно устройство. Два демона, споделящи tun0, презаписват състоянието на устройството си един на друг, дори когато портовете им се различават, така че едно устройство на тунел не е по избор.

nobind принадлежи на страната на клиента. Сървърът все още трябва да обвързва и слуша, така че не копирайте реда в конфигурацията на сървъра и не изключвайте обвързването на клиент, чийто партньор филтрира по фиксиран изходен порт.

Изберете един собственик на маршрута по подразбиране

Само една връзка може да инсталира маршрут по подразбиране. Ако и двата профила пренасочват целия трафик, второто свързване безшумно замества първото и първото изглежда счупено. Или запазете изходящия тунел разделен и изпращайте само префиксите на доставчика, или му дайте отделна таблица за маршрутизиране.

ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2

Адресите и номерът на таблицата по-горе са запълващи. Веднага след добавянето на правилото потвърдете, че собственият адрес на VPN сървъра все още се разрешава през нормалната таблица; таблица, която прихваща външния транспорт, чупи тунела, който е трябвало да защити, а цикълът на повторно свързване след това изглежда като ненадежден доставчик.

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

Проверете с таблицата, не с реда за състояние

Клиент, който съобщава, че е свързан, доказва само своя контролен канал. Запишете състоянието на маршрутизирането преди и след всяко свързване, след което попитайте ядрото кое устройство би използвала реална дестинация:

ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194

Ако избраното устройство за адреса на доставчика се промени при стартирането на втория тунел, имате сблъсък на маршрути. Ако и двата процеса се покажат на един и същ локален порт, имате сблъсък на сокети. Поправянето на първото без второто просто премества отказа към следващото повторно свързване.

Запишете портовете, устройствата, таблиците и собственика на маршрута в runbook-а на хоста. Иначе следващият човек, който добави трети тунел, ще открие отново същото стълкновение и единственото видимо доказателство ще бъде връзка, която работи, докато не се рестартира демонът на някой друг.

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