Повідомлення «File exists» OpenVPN на маршруті — не проблема файлу
Повідомлення надходить із таблиці маршрутів ядра, а не з файлової системи. Прочитайте запис, який уже володіє префіксом, перш ніж змінювати політику LAN.
Почніть там, де з'являється повідомлення. Клієнт підключається, тунель піднімається, і потім журнал повідомляє, що команда додавання маршруту в Linux завершилася помилкою File exists. Ніщо в цьому реченні не стосується сертифіката, ключа чи файлу конфігурації, хоча слова це підказують. Ядро описує свою таблицю маршрутів, і префікс, який ви просили встановити, уже має запис.
Дотримуйтеся власного порядку клієнта: що він запросив, що вже містила таблиця, хто розмістив цей запис там, і лише потім що змінювати. Кожен крок прибирає одного можливого власника.
Що клієнт насправді запитував
Перед збоєм клієнт записує маршрут, який збирається додати, зазвичай як пункт призначення, маску мережі, шлюз і іноді як метрику або таблицю. Цей рядок — запит. Наступна помилка — відповідь ядра, і обидва треба читати поруч.
journalctl -u openvpn-client@office -b --no-pager | grep -nE 'route|File exists'
openvpn --config /etc/openvpn/client/office.ovpn --verb 4 --log /tmp/ovpn.log
Ненульовий код виходу помічника маршрутів менш інформативний, ніж текст під ним, бо різні відповіді ядра дають ненульовий статус. Збережіть точне повідомлення; різниця між наявним записом і недосяжним шлюзом визначає, який із наступних розділів застосовний.
Читайте наявний маршрут, а не лише адресу
Пошуку в таблиці того самого крапкового четвірки недостатньо. Об'єкт маршруту визначається родиною адрес, таблицею, префіксом призначення, метрикою, протоколом і вихідним пристроєм, і записи, що поділяють префікс, можуть законно співіснувати, коли ці атрибути різняться. Зіштовхується весь об'єкт, а не текст.
ip -4 route show table all | grep -F '10.40.'
ip -4 route show match 10.40.0.0/16
ip -4 route get 10.40.0.5
Остання команда відповідає на інше питання, ніж перші дві: не що існує, а який запис ядро вибрало б для цього призначення просто зараз. Обидва подання корисні, і вони розходяться достатньо часто, щоб їх варто було порівняти перед будь-яким висновком. Розбіжність між ними — це цікавий випадок, а не помилка округлення.
Запишіть префікс, таблицю, метрику й пристрій поруч із невдалим запитом. Якщо наявний запис має ті самі атрибути й той самий наступний стрибок, у вас дубльована інструкція, а не проблема маршрутизації.
Чотири власники, які можуть бути в префікса
Підключені маршрути походять із призначеної адреси й перестворюються системою щоразу, коли ця адреса існує. Клієнт DHCP або менеджер з'єднань встановлює маршрути як частину свого життєвого циклу. Інший клієнт VPN може вже нести той самий префікс. А локальний хук або скрипт може додати такий, про який більше нічого не знає.
Кожному власнику потрібна своя корекція. Підключений маршрут не ваш для видалення; його видалення може порушити локальний доступ до того, як тунель стане придатним, і ядро поверне його. Маршрут, який належить менеджеру, слід змінювати через цього менеджера, а не вручну за допомогою ip route del, яке скасує наступне перепідключення.
Збережений інтерфейс полегшує ту саму плутанину. Коли пристрій тунелю переживає перепідключення, маршрути, встановлені власним кодом налаштування, можуть залишатися й при другому запуску, тому скрипт, який припускає чистий стан, падає вдруге й працює вперше. Або навмисно очистіть застарілий запис, або зробіть код налаштування ідемпотентним.
block-local відповідає на інше питання
Коли профіль надсилає весь трафік через тунель, клієнт має вирішити, що відбувається з локальною мережею. Прапорець block-local змінює це рішення, спрямовуючи локальну LAN через тунель і зберігаючи задокументований виняток для шлюзу LAN; це вибір політики трафіку з видимими наслідками для доступності.
Це не пояснює, чому додавання маршруту повернуло помилку про наявний запис, і прийняття цього як універсального виправлення приховує реальний конфлікт за зміною політики. Якщо ваші локальні ресурси стають недоступними після редагування профілю, цей прапорець — одна з перших речей, які треба перевірити; якщо додавання маршруту не вдається, це не відповідь.
Ставтеся до нього як до рішення про те, які призначення залишаються локальними, ухваленого свідомо й записаного. Це не перемикач, який варто пробувати, коли журнал виглядає тривожно.
Замкніть цикл: видаліть дублікат у його джерелі
Коли ви знаєте, який власник тримає запис, видаліть дубльовану інструкцію там, де вона визначена. Це може бути рядок route у профілі, push із сервера або хук, якому більше не потрібно виконуватися.
ip -4 route show match 10.40.0.0/16
ip -4 route get 10.40.0.5
journalctl -u openvpn-client@office -b --no-pager | tail -n 15
Потім перепідключіться й підтвердьте три речі: тунель піднімається, потрібне призначення розв'язується в бажаний шлях, і збій зникає, не залишаючи на своєму місці нового. Чистий журнал із неправильно вибраним шляхом — не виправлення.
Якщо префікс означає локальну LAN з одного боку й віддалену мережу з іншого, проблема в перекритті адрес, а не в дублікаті, і жодне видалення не зробить обидва значення істинними одночасно. Цей випадок потребує іншого плану для однієї з двох мереж. Вирішіть, який бік буде перенумеровано, перш ніж торкатися будь-якого.