Свежие журналы контейнера часто заканчиваются жалобой Read-only file system на /proc/sys/net/ipv4/route/flush, и эту строку винят в проблемах туннеля, который может быть совершенно исправен. Запись за ней адресована записи ядра, которая больше ничего полезного не делает, поскольку кэш маршрутов IPv4 исчез. Внутри контейнера /proc/sys монтируется только для чтения, поэтому перенаправление отклоняется до того, как попадёт хоть какое-то значение, и оболочка печатает этот отказ. Рабочий туннель может печатать это предупреждение, пока старая строка остаётся в скрипте, и --privileged никогда не делает запись осмысленной.

Что скрипт пытался сбросить

Старые скрипты подключения заканчивались очисткой кэша: записать значение в управляющий файл ядра и попросить стек IPv4 сбросить свой кэш маршрутизации, чтобы новый маршрут туннеля выбирался, не дожидаясь истечения устаревших записей. Файл адресовался в /proc/sys/net/ipv4/, что делало операцию перенаправлением оболочки, а не командой маршрутизации. Ядро 3.6 удалило этот кэш, а вместе с ним и причину существования сброса. Ничто в текущем пути данных не зависит от этой записи.

Сама запись сохранилась как устаревший файл только для записи, поэтому скрипт, который всё ещё пишет в него, доходит до реального пути и реальной проверки прав. На хосте запись возвращает успех и ничего не меняет. В контейнере то же перенаправление упирается в /proc/sys только для чтения и завершается с EROFS, который оболочка печатает как сообщение файловой системы только для чтения. На ядрах, где путь действительно отсутствует, формулировка становится No such file or directory, и вывод не меняется.

Две ошибки говорят о разном, и разницу стоит держать ясной. Read-only file system означает, что ядро дошло до записи и отказало в записи; No such file or directory означает, что записи больше нет. Ни одно сообщение не сообщает об устройстве туннеля, маршрутах или разрешении имён, поэтому ни одно не может оправдать больше привилегий.

Именно порядок заставляет сообщение выглядеть причинным. Скрипт подключения устанавливает маршруты, меняет состояние интерфейса и переписывает разрешение имён, прежде чем дойти до очистки в конце, поэтому последняя напечатанная строка — та, которую цитируют, даже когда каждый важный шаг вернул успех. Туннель, который устанавливается и несёт трафик, печатая это предупреждение, точно соответствует описанному механизму.

Проверьте монтирование и маршрут, прежде чем добавлять привилегии

Три проверки отделяют косметическое предупреждение от настоящего сбоя: несёт ли установленный скрипт эту строку, как смонтирован /proc/sys и куда на самом деле идёт трафик приложения. Выполняйте их в том же пространстве имён контейнера или на том хосте, где появилось предупреждение, потому что проверка на посторонней машине отвечает на другой вопрос.

grep -n 'ipv4/route/flush' /usr/share/vpnc-scripts/vpnc-script
findmnt -no OPTIONS /proc/sys
ip -4 route get 10.20.5.10

Ответ grep слабее, чем кажется, потому что находка доказывает наличие строки, а не то, что она выполняется без защиты; поддерживаемый скрипт может держать запись внутри проверки, которая её пропускает. findmnt -no OPTIONS /proc/sys напрямую решает вопрос с монтированием, а ro в этом выводе означает, что любая запись ниже этой точки отклоняется, что бы скрипт ни делал. Затем поиск маршрута показывает, разрешается ли нужный приложению адрес через интерфейс туннеля или через шлюз контейнера по умолчанию. Поиск, выбирающий шлюз по умолчанию, означает, что туннель поднялся и в него ничего не маршрутизируется, а это проблема маршрутизации, а не привилегий.

Откуда на самом деле берётся исправление

Поддерживаемое исправление живёт в скрипте, а не в флагах контейнера. upstream vpnc-script изменил обработку этой операции, поэтому сравните копию внутри образа с текущим upstream и обновите через пакет или сборку образа, которая её поставляет. Файл, отредактированный вручную в работающем контейнере, не подлежит проверке и не переживёт следующую сборку.

--privileged документирован как предоставляющий все возможности и широкий доступ к устройствам — большая уступка ради сообщения, которое ничего не меняет, поэтому назовите недостающую возможность, если её действительно нет. После обновления повторите поиск маршрута и дайте приложению использовать туннель, потому что тихий журнал и работающее соединение — разные результаты.

Похожие статьи