27 апреля 2011 г.

WEB SERVER. Права доступа к файлам и каталогам сайта.

Каждый системный администратор, которому доводилось управлять работой любого web сервера, сталкивался с несколькими проблемами связанными с разграничением доступа к файлам (будь-то скрипты, фотографии, js, css, и т.д.). Для начала рассмотрим типичные ситуации приводящие к проблемам в дальнейшем:
1. Ничего не делание или "я поставил сайт по инструкции производителя". Так, в основном, поступают начинающие администраторы или те, кому лень думать, а тем более, делать что-либо. Тоесть скачали, распаковали, положили сайт со скриптами, скажем, в /var/www/super-site, прописали конфиги web сервера, нового сайта для подключения к БД и все! Работа зделана и http://super-site.com.ua открывается, пользователи регистрируются, картинки и файлики заливаются - все работает!
2. Заливка файлов на сервер или "что-то пользователи не могут залить свои файлы на сервер!?". Ах, ну да, мы же не дочитали до конца, - там ведь написано, что web сервер должен иметь права на запись в папочку upload где-то в файловой структуре сайта. Не долго думая, ставим 0777 на нужную папочку и вот - файлики пишутся - проблема решена!
3. Совместная работа или "что-то программист Вася не может зделать необходимый ребрендинг нашего супер сайта". Да, оказывается Вася не может редактировать файлы в структуре сайта, - нет прав на запись. Не беда, - дадим Васе нужные права. Вот только не ясно, сколько таких Вась будет в дальнейшем, - да не будем заморачиваться и поставим на весь сайт права 0777. Вот - теперь программист Вася и его коллеги (вебмастер Коля, SEO оптимизатор Ваня) смогут безпроблемно поменять файлы в сайте так, как им надо. Вуаля!..

Для мало-мальски соображающих админов описанный сюжет - предверие апокалипсиса с данными сайта, а потенциально и со всем сервером. На выходе мы имеем набор каталогов и файлов которые может модифицировать/удалить любой пользователь системы в т.ч. и злоумышленник, проникший на сайт, от имени web сервера.

Поделюсь своим видением того, как правильно организовать разграничение прав доступа.
1. Самое главное в начале разработки модели доступа полностью описать все "действующие лица". Первое, что приходит в голову: собственно процесс web сервера (httpd/nginx/lighttpd/...) и персонал обслуживающий сайт на уровне прямого доступа к файлам (программисты, дизайнеры и пр.). Все вроде бы правильно, однако не стоит забывать, что есть ещё и системы резервного копирования, системы автоматизированного деплоймента, сторонние сервисы (как то ftp для прямого доступа к контенту сайта), и прочие.
2. Не менее важно правильное определение "узких" мест фаловой структуры сайта. Каталоги для записи пользовательского контента, разнообразных кешей скриптов, статических библтотек и прочего. Все эти места будут имет отличные от основной части права на доступ к своему содержимому.

Предположим в тестовой системе имеется несложный сайт с такой структурой:
/var/www/site
                |->application-core
                |->public-files
                     |->users-content
                |->cache
и имеем web сервер, 2-х программистов, одного дизайнера и систему резервного копирования.
Далее решаем задачу с правами пользуясь знаниями (man chown, man chmod, man usermod, bash scripting) и логикой описанной ниже.
1. Ясно, что для того, чтобы содержимое сайта было отображено клиенту необходимо, чтобы web сервер мог читать все необходимые ему файлы и входить в каталоги. Однако, старайтесь давать web серверу минимум прав и только там, где это нужно. К примеру, если вы после установки сайта запустили скрипт setup.php или install.php, по его завершении, уберите возможность web серверу читать этот файл - так вы обезопасите себя от возможности его повторного запуска. Собственно для того, что бы вев-сервер имел доступ на чтение файлов достаточно установить права на чтение (r) для всех файлов сайта для пользователей отличных от владельца/группы. Установите так же права на исполнение (x) для всех каталогов.
2. Дайте програмистам и дизайнеру почти полную свободу в доступе к файлам сайта, - зделайте для этих людей отдельную группу в системе (скажем, developers) и пропишите её как основную для каждого аккакунта (usermod -g вам в помощь). Назначте владельцем файлов и каталогов сайта кого-то из программистов и задайте им группу developers. Дайте полные права для владельца и группы (rw) для файлов, а для каталогов, - ещё и доступ на вход (x).
3. Не забывайте о том, что атрибут eXecute (x) - совершенно ненужная вещь для файлов сайта (конечно если это не cgi скрипты, которые необходимо запускать), а вот для каталогов - очень даже необходимая.
4. Систему резервного копирования можно по сути в разрезе прав доступа приравнять к веб серверу, - соответственно для её функционирования будет достаточно прав указанных в п.1
5. Есть ещё несколько каталогов в которые веб-сервер должен иметь возможность записывать файлы (загруженный пользователями контент, свои кэши и прочее) для них необходимо поступить с правами так: сделать их владельцем учётную запись от которой работает веб-сервер, группой назначить developers (см. п. 2). Владельцам и группе дать полные права (rw), а  для каталогов ещё и выполение (x), остальным пользователям системы дать доступ только для чтения (для системы резервного копирования).

Соблюдая такие простые правила можно легко обезопасить свой сайт от многих потенциальных угроз. Естественно, во многих случаях модель раздачи прав может быть достаточно более комплексной, но это уже предмет рассмотрения других статей.