CentOS 5 -> 6: SELinux как часть работы, а не помеха
Переводим файловые и веб-серверы с CentOS 5 на 6. Главный сюрприз - SELinux включён по умолчанию, и обойти его setenforce 0 уже не хочется.
Линейка CentOS 6.x закрепляется как основная для production-серверов
Перевод клиентских серверов с CentOS 5 на 6 - задача, которую мы откладывали последние полгода. Не потому что страшно, а потому что «работает - не трогай» звучит убедительно, когда у клиента на сопровождении два десятка машин и нет окна для плановых простоев.
Но пятая ветка уже получает только критические патчи безопасности, и этот аргумент убедил нас запланировать миграцию.
Что изменилось между пятёркой и шестёркой
Разница не катастрофическая, но и не косметическая. Главные точки трения:
Init-система. CentOS 6 всё ещё использует SysV init с upstart поверх - не systemd, к которому все привыкли на Fedora. Rc-скрипты работают, большинство написанных под пятёрку стартапников заработали без правок. Один нюанс: upstart-задания в /etc/init/ имеют приоритет над традиционными скриптами в /etc/init.d/, и если в пакете есть оба - иногда получаешь неожиданное поведение.
Версии пакетов. PHP 5.3 вместо 5.2, Apache 2.2 та же, MySQL 5.1 та же. В целом мягко, но PHP 5.3 сломал несколько старых приложений по части deprecated-функций. ereg_* вместо preg_* - классика, всплыла у двух клиентских скриптов.
SELinux. Вот здесь всё по-настоящему.
SELinux: включён и злой
В пятёрке SELinux чаще был выключен или стоял в permissive. Именно потому что с ним лень было разбираться, а setenforce 0 решало проблему за три секунды. В CentOS 6 он включён в enforcing по умолчанию, и Red Hat явно дал понять что отключать его - плохая идея. Мы решили не спорить.
Первый же Apache с нестандартным DocumentRoot за пределами /var/www встал колом. 403 Forbidden, в логах ничего, nginx (который мы ставили реверс-прокси) ругался на upstream. Полчаса ушло на то чтобы вспомнить: SELinux не пускает httpd читать файлы без правильного контекста.
Диагностика строится на трёх командах:
ausearch -m avc -ts recent- смотрим последние denied в audit-логеaudit2why- человекочитаемое объяснение что именно заблокированоaudit2allow -a- генерирует черновик политики на основе того что было заблокировано
Для нашего случая с нестандартным DocumentRoot правильное решение - выставить нужный контекст на директорию:
semanage fcontext -a -t httpd_sys_content_t "/data/sites(/.*)?"
restorecon -Rv /data/sites
Это ровно пять минут работы, если знаешь инструменты. Но в первый раз - двадцать минут гугления и осознания что ls -Z показывает контексты.
Боготворим audit2allow, но с осторожностью
audit2allow искушает: скармливаешь ему лог, он генерирует .te-файл политики, компилируешь, загружаешь - и всё работает. Проблема в том что сгенерированная политика может быть избыточно широкой. Мы натолкнулись на ситуацию, где автогенерированное правило давало httpd доступ к типу файлов, который ему видеть незачем. Пришлось ручками сужать.
Рабочий подход: audit2allow как отправная точка для понимания, не как готовое решение для прода.
Несколько практических моментов
Booleans делают жизнь проще. Для типовых сценариев в SELinux есть встроенные булевы переключатели. setsebool -P httpd_can_network_connect on - разрешает Apache коннектиться наружу (нужно для PHP-приложений, ходящих к API). getsebool -a | grep httpd показывает все доступные переключатели для httpd. Прежде чем писать кастомную политику - смотри список boolean, скорее всего нужное уже есть.
NFS и SELinux. На файловом сервере с NFS-экспортами пришлось повозиться с контекстами для nfs_t. Монтируемые клиентами директории требуют samba_share_t или явно разрешённых типов на клиентской стороне - зависит от того кто монтирует.
Логи - в /var/log/audit/audit.log. Если что-то не работает и непонятно почему - туда. Почти всегда SELinux denied там, если не в /var/log/messages.
Про upstart и сервисы
Несколько кастомных init-скриптов пятёрки переехали без правок. Один скрипт для самописного демона пришлось переписать под upstart - старый не стартовал нормально при перезагрузке из-за конфликта порядка зависимостей. Upstart-синтаксис немного непривычный после SysV, но проще чем кажется.
Итог на этой точке
Восемь серверов переведено, ещё шесть в очереди. Основной вывод: миграция с 5 на 6 технически некритична, если заложить время на SELinux. Не на его отключение - на понимание. audit.log + audit2why + нужные boolean - и большинство проблем решаются без написания кастомных политик.
setenforce 0 мы не трогали ни разу. И это приятно.
- Puppet 3: первый манифест вместо баш-скриптов · 7 февраля 2013
- SSD в серверной: первый опыт с enterprise-накопителями и подводными камнями · 31 января 2013