Почему перенос сертификата VPN ломает его метку SELinux
Переименование сохраняет inode и его контекст, поэтому режим может быть идеальным, а служба всё равно откажет. Сравните фактическое с ожидаемым, затем восстановите сопоставление.
Сертификаты могут лежать в правильном каталоге с читаемым режимом и владельцем root, а служба всё равно может сообщить, что не может открыть файл. В системе SELinux такое сочетание указывает на один конкретный механизм, а не на права. Метка переехала вместе с файлом, потому что переименование не создаёт новый объект. Inode сохранил контекст безопасности, который был у него на старом пути, а политика нового пути так и не получила возможности назначить свой.
Что переименование на самом деле делает с меткой
Файл несёт свой контекст SELinux как данные атрибута, привязанные к inode. Переименование в пределах одной файловой системы меняет запись каталога и больше ничего, что быстро и атомарно, и именно поэтому контекст переживает перенос. Никакая политика не запрашивается, никакое значение по умолчанию не применяется, и никакое предупреждение не печатается.
Копирование ведёт себя иначе. Копия создаёт новый inode в целевом каталоге, и политика назначает контекст по типу этого каталога, поэтому скопированный сертификат обычно получает правильную метку, а перенесённый остаётся неверным. Именно это единственное различие объясняет большую часть путаницы в этом классе заявок.
Переносы между файловыми системами возвращаются к семантике копирования, поэтому одна и та же команда может вести себя по-разному на двух машинах в зависимости от того, живёт ли /etc на отдельном томе. Проверьте это, прежде чем заключить, что инструмент ненадёжен. Один взгляд на таблицу монтирования скажет вам, какой вид переноса вы выполнили.
Прочитайте текущую метку напротив ожидаемой
Три команды только для чтения отвечают на вопрос, ничего не меняя. Первая показывает, что у файла есть сейчас, вторая сообщает, что политика ожидает для именно этого пути, а третья перечисляет каждый файл в каталоге, чья метка отличается.
ls -lZ /etc/openvpn/client/office-ca.crt
matchpathcon /etc/openvpn/client/office-ca.crt
restorecon -Rn -v /etc/openvpn/client
Доверять стоит пробному прогону, потому что он называет каждый файл, чей контекст отклоняется от политики, и при этом оставляет систему нетронутой. Если сертификат появился в этом списке, вы нашли расхождение между тем, что означает путь, и тем, что утверждает файл. Если его там нет, метка уже такая, какой её хочет политика, и ваше время принадлежит другому месту.
Затем сопоставьте различие с реальным отказом. Несовпадение — это доказательство неверной метки, а не доказательство того, что служба отказала из-за него, и исправление, применённое без соответствующего отказа в журнале, — это догадка с лишними шагами.
Восстановите сопоставление вместо того, чтобы изобретать исключение
Для стандартного расположения политика уже сопоставляет путь, поэтому restorecon применяет его, и работа сделана. Держите область в пределах каталога, который вы чините; перемаркировка всей файловой системы медленна, разрушительна и хоронит исходную ошибку под очень большим изменением.
Для нестандартного каталога порядок важен, и его обращение даёт команду, которая сообщает об успехе, ничего не меняя. Сопоставление принадлежит политике, перемаркировка принадлежит концу, а пробный прогон принадлежит перед обоими. Пропуск этой последней части — это способ перемаркировать путь, который никогда не был неверным.
semanage fcontext -a -t openvpn_etc_t '/etc/openvpn/custom(/.*)?'
restorecon -Rv /etc/openvpn/custom
restorecon применяет сопоставление; придумать его он не может. Если ни одно правило не описывает путь, восстанавливать не из чего, поэтому постоянное сопоставление должно существовать до перемаркировки. Запишите, какая конфигурация владеет этим сопоставлением, потому что иначе более поздний перенос, обновление пакета или перемаркировка снова создают неисправность, и следующий человек начинает с нуля.
Почему chcon не решение
chcon записывает контекст прямо в файл. Он действует сразу и это наименее долговечный из доступных вариантов, потому что перемаркировка файловой системы заново применяет политику и выбрасывает ручные изменения, не спрашивая. Файл выглядит исправленным, а у исправления есть срок годности, который никто не записал. Вместо этого вам нужно правило, описывающее путь, чтобы каждый файл, попадающий туда, автоматически получал ту же обработку.
Хуже того, это учит неверному уроку: базовое сопоставление всё ещё отсутствует, поэтому неисправность возвращается через недели без очевидного триггера и без памяти об обходном пути. Используйте chcon только как временный эксперимент для подтверждения гипотезы, затем замените его сопоставлением, которое переживёт следующую перемаркировку, и проверьте, что замена действительно на месте.
Когда метка верна, а доступ всё равно не работает
Начните с родительских каталогов. Разрешение на проход проверяется на каждом компоненте пути, поэтому правильно помеченный сертификат в каталоге, куда служба не может войти, остаётся нечитаемым. И SELinux, и обычное разрешение должны допускать каждый шаг, и исправление одного не исправляет другого.
Затем проверьте идентичность процесса и собственную песочницу службы. Юнит с ограничительной песочницей может отказать в доступе к файлу, который политика охотно разрешила бы, и по строке журнала обе причины выглядят одинаково. Подтвердите, какой процесс на самом деле спрашивает, а не тот, который вы предполагаете спрашивающим.
Помните, что правила dontaudit могут подавлять сообщения об отказе, поэтому пустой журнал аудита — слабое доказательство, а не доказательство. Если политика выглядит правильной, а доступ всё равно не работает, разберитесь, прежде чем создавать широкий модуль разрешений, и не отключайте SELinux, чтобы симптом исчез. Оба коротких пути дают систему, которая кажется работающей, и положение безопасности, которое никто не может описать. Короткое расследование лучше любого из них.