Особенности установки Drupal на хостинг с mod_php и включеным safe_mode, а также open_basedir

Очень многие сталкиваются с проблемами установки и начальной настройки Drupal на хостинги, где PHP работает в режиме mod_php, при включеном safe_mode и open_basedir. Неискушённые пользователи просто не понимают, что такое safe_mode и как при этом устанавливать или работать с Drupal. Данная статья призвана ответить на эти вопросы!

Автор: Виктор Вислобоков
Лицензия: CC-BY-NC-ND


Первым делом, хочется сказать, что Drupal будет работать в safe_mode и даже со включеным open_basedir. Однако, для этого возможно будет необходимо привлечь вашего хостера!

Внимание! Прежде чем начать установку и настройку после установки СПЕРВА ПРОЧТИТЕ ВСЮ статью, чтобы не сталкиваться с проблемами, которых можно избежать!

Начнём с того, что убедимся, что у вас именно такой хостинг, про который мы говорим. В любом случае у вас должен быть FTP-доступ к каталогу web-сервера на хостинге. Создайте в этом каталоге (или скопируйте со своей машины) файл phpinfo.php следующего содержимого:

<?php
phpinfo
();
?>

Затем вызовите эту же страничку через браузер: (http://yoursite.ru/phpinfo.php), где разумеется yoursite.ru нужно заменить на имя вашего сайта. Вы увидите страницу со справочной информацией о PHP, установленном на хостинге, а также всех его настройках. Для нас, в данном случае, интерес представляют следующие параметры:

  • Server API. Этот параметр должен выглядеть так: Apache 2.0 Handler или Apache 1.3 Handler. Такие значения означают, что PHP на хостинге работает в режиме mod_php. Если значение CGI/FastCGI, то дальше статью можно не читать - не ваш случай.
  • safe_mode. Этот параметр должен быть установлен в On. Вернее данная статья рассматривает ситуацию, когда значение On. Если же значение Off - это уже совсем другая история и из данной статьи применим только параграф 1.
  • open_basedir. Этот параметр может иметь, например такое значение: /tmp:/home/z0000013/public_html. Но может иметь и другие значения, в зависимости от пути, который использует тот или иной хостер для вашей учётной записи (аккаунта) на хостинге. Для нас же главное, что есть какое-либо значение. Также, обратите внимание, что данный параметр имеет силу при ЛЮБОМ значение safe_mode. Т.е. не важно включен или выключен safe_mode.

1. Ограничение mod_php


В режиме mod_php, любой PHP-скрипт работает с правами не вашей учётной записи, а с правами web-сервера[1]! Обычно web-сервер (Apache) запускается от имени либо пользователя apache, либо пользователя nobody, хотя возможны и другие варианты. Однако, вне зависимости от этих вариантов, важно то, что для вашего домашнего каталога хостер устанавливает такие права, согласно которым писать в этот каталог (и все его подкаталоги) может только его владелец! Т.е. по-умолчанию, web-сервер не может писать никаких файлов в ваш каталог или изменять в нём какие-либо файлы. Однако, в процессе работы Drupal, ему требуется сохранять закаченые файлы и создавать временные файлы. Это первая проблема, с которой обычно сталкивается пользователь. Чтобы её решить, он вынужден создавать в нужных для Drupal местах каталоги, в которые даются права на запись ВСЕМ пользователям или группе владельца (если в неё входит пользователь, от имени которого работает web-сервер). Но тут же возникает вторая проблема, связанная уже с безопасностью: если в каталог может писать любой пользователь, то он автоматически становится доступен любому PHP-скрипту, который выполняется на этом же хостинг-сервере, даже если этот PHP-скрипт выполняется не на вашем сайте! Таким образом, вредоносные скрипты с других сайтов, расположенных на этом же физическом сервере получают возможность изменять или удалять ваши файлы, что является дырой в безопастности и недопустимо! Именно поэтому и был придуман safe_mode и директива open_basedir!

2. Ограничение safe_mode


safe_mode в переводе с английского означает "безопасный режим". В этом режиме некоторый функционал PHP просто выключен. Очень хорошо о том, что такое safe_mode описано здесь. Кроме того, что в этом режиме не работают многие функции PHP, для нас наиболее важным является вот это: Когда safe_mode включён/on, PHP проверяет, совпадает ли владелец текущего скрипта с владельцем файла, которым оперирует функция работы с файлами.. Непонятно? Поясняю. Допустим вы заливаете ваши PHP-скрипты на хостинг по FTP или распаковываете архив с PHP-скриптами, зайдя по SSH. Владелец залитого или распакованого файла будет установлен согласно вашей учётной записи (аккаунту) (права же доступа к PHP-скриптам определяются либо настройками системы по умолчанию, либо теми правами, которые сохранены в распаковываемом архиве, либо теми правами, которые устанавливает в процессе закачки ваш FTP-клиент). Теперь, когда вы попытаетесь открыть какой-либо файл залитым PHP-скриптом, будет произведена проверка владельца того файла, который вы пытаетесь открыть. Если данный владелец не совпадёт с владельцем PHP-скрипта (т.е. вашим аккаунтом), будет выдано сообщение об ошибке. Таким образом, вы не сможете открыть ни одного файла, владельцем которого вы не являетесь. Это предохраняет ваши данные от чтения и записи чужими пользователями! Однако остаётся ещё одна возможность атаки на ваши данные. Как уже говорилось, для нормальной работы Drupal вам необходимо дать права на запись в каталог web-серверу. При этом, создаваемые web-сервером файлы и каталоги будут иметь другого владельца! Этим владельцем станет пользователь, от имени которого работает web-сервер. Т.е. если с помощью вашего Drupal записали PHP-скрипт, то теперь вы можете запустить этот PHP-скрипт и читать/писать (если конечно позволяют права) с его помощью все файлы, владельцем которых является web-сервер, даже если эти файлы находятся в каталоге вашего соседа по хостингу (который точно также вынужден был открыть этот каталог на запись web-серверу, чтобы иметь возможность закачивать файлы (например картинки) через PHP. Снова дыра в безопасности! И вот чтобы эту дыру закрыть и была придумана директива open_basedir.

3. Ограничение open_basedir


open_basedir содержит перечень каталогов, в которых вы можете открывать файлы. Напоминаю, что open_basedir работает как при включеном, так и при выключеном safe_mode. Таким образом, попытка открыть любой файл в любом каталоге, который не перечислен в open_basedir, приведёт к ошибке, даже если владелец открываемого файла и владелец PHP-скрипта, который пытается открыть этот файл один и тот же. Таким образом, с одной стороны обеспечивается безопасность при работе PHP в режиме mod_php, а с другой стороны создаётся куча проблем для нормальной работы PHP-скриптов в том случае, если требуется что-то не предусмотренное такой системой безопасности, например запуск внешних программ, установленных в операционной системе.

4. Установка Drupal


Итак, поехали с учётом всего вышесказанного. Скачиваете архив с Drupal и распаковываете его в каталог web-сервера на хостинге. Если у вас доступ только по FTP, то распаковывайте на вашей машине и заливайте на хостинг-сервер по файлово. Далее, считаем, что вы уже создали на хостинге базу данных MySQL и пользователя с необходимыми для работы с этой базой данных правами. Обычно это делается в панели управления хостингом - если не знаете как, спросите у вашего хостера (панелей слишком много, чтобы рассказывать об этом здесь). Наконец в браузере набираете: http://yoursite.ru, где разумеется заменяете yoursite.ru на имя вашего сайта. Появляется стандартное приглашение Drupal к установке:

Щёлкните по ссылке "Install Drupal in English". Появится следующий экран:

Там написано, что вам необходимо скопировать файл ./sites/default/default.settings.php в файл ./sites/default/settings.php и установить на него необходимые права. Таким образом, теперь вам необходимо сделать (по FTP или SSH) копию файла default.settings.php под именем settings.php и установить на этот файл права 0666, что означает доступ ВСЕМ. Пока не волнуйтесь, ибо это временная мера.

Там же написано, что каталог sites/default/files не существует, что попытка его автоматического создания не удалась (ещё бы, ведь web-сервер не может писать в ваши каталоги (помните параграф 1?)) и что его необходимо создать, а также дать необходимые права на запись. Итак, создаёте (по SSH или FTP) подкаталог files в каталоге sites/default и устанавливаете на его права 0777 (увы это уже не лечится по причине mod_php).

Теперь собственно можно щёлкать по ссылке "Try again". Появляется следующий экран:

Введите в поле "Database name" имя ранее созданной mysql базы данных (в нашем случае drupal), в поле "Database username" имя пользователя, которому мы предоставляли доступ к базе данных drupal (в нашем случае имя совпадает с базой данных) и в поле "Database password" соответственно пароль пользователя drupal (вы должны были выбрать его сами при создании пользователя). Все эти данные нужны для подключения к базе данных.

Есть некоторые дополнения. Например, если ваш сервер баз данных MySQL находится на другой машине, то вы можете использовать его. Для этого нажмите на "Advanced option" и увидите дополнительные поля:

В них вы можете указать имя сервера, на котором работает MySQL в поле "Database host" (по умолчанию указано значение localhost, (что означает, что подключение MySQL будет производится к локальной машине через сокет, а не по протоколу TCP/IP) и порт, по которому производится подключение к MySQL в поле "Database port". Ещё вы можете указать в поле "Table prefix" указать приставку, которая будет использована при создании имён таблиц Drupal. Это может быть полезно, если вы используете уже существующую базу данных, где уже есть какие-либо таблицы. Указание префикса позволит избежать конфликта в именах таблиц.

После нажатия кнопки "Save Configuration" вы увидите на экране индикатор прогресса установки Drupal, который сменяется следующим экраном:

Вверху вы видите в красной рамочке сообщение, что теперь необходимо, из соображений безопасности, сменить права на файл settings.php (который мы создавали ранее), чтобы запретить web-серверу запись в этот файл. Соответственно теперь можно это сделать и хоть как-то обезопасить свою конфигурацию. Установите на данный файл права 0644, что будет означать возможность чтения файла всеми, но запись будет доступна только владельцу. По уму надо бы чтобы и на чтение всеми прав не было, потому что если прочтут пароль к вашей базе данных, то хорошего в этом, сами понимаете, ничего нет. Однако мы в mod_php и web-сервер должен иметь права на чтение этого файла, иначе ваши PHP-скрипты не смогут подключаться к базе данных. Поэтому остаётся уповать на safe_mode.

Далее, вводим начальные настройки. В поле "Site e-mail address" введите E-mail адрес, который будет использоваться Drupal как E-mail адрес сайта. Обычно вводится E-mail адрес будущего администратора Drupal. Как только вы введёте значение, вы увидите, что внизу в группе полей "Administrator account" это же значение автоматически скопировалось в поле "E-mail address" администратора. Далее в поле "Username" введите имя пользователя, который будет администратором вашего сайта (например имя "admin" является хорошим выбором). Далее в полях "Password" и"Confirm password" вы должны ввести один и тот же пароль, для данного пользователя.

Далее, внизу вы видите сообщение в жёлтой рамочке о том, что "чистые" URL вашей текущей конфигурацией не поддерживаются! На вашем хостинге возможно вместо сообщения в жёлтой рамочке, вы получите сообщение в зелёной рамочке, что чистые ссылки активированы. Возможно, вам они и не нужны, но могу сказать, что большинство людей сразу пытаются их настроить и работать только с "чистыми" URL. О том, что это такое, вы можете прочитать здесь.

И наконец вы видите галочку "Check for updates automatically", которая означает, что Drupal будет автоматически проверять наличие обновлений. По умолчанию галочка включена, но если вы по каким-то причинам не хотите автоматической проверки обновлений, снимите её.

Нажмите кнопку "Save and continue" и если всё было сделано корректно, вы увидите следующий экран:

На этом этап установки закончен! А вот теперь начинается самое веселье. Идём по адресу http://yoursite.ru/admin/settings/file-system (разумеется yoursite.ru нужно заменить на имя вашего сайта) и тут же наступаем по полной программе на ограничения safe_mode:

Вот как раз это сообщение:

* warning: fopen() [function.fopen]: SAFE MODE Restriction in effect. The script whose uid is 500 is not allowed
  to access /var/www/html/yoursite.ru/data/sites/default/files/tmp owned by uid 48
  in /var/www/html/yoursite.ru/data/includes/file.inc on line 129.
* warning: fopen(sites/default/files/tmp/.htaccess) [function.fopen]: failed to open stream: Success in
  /var/www/html/yoursite.ru/data/includes/file.inc on line 129.
* Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your
  sites/default/files/tmp directory which contains the following lines:
      SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
      Options None
      Options +FollowSymLinks

появляется только, если у вас включен safe_mode. Надеюсь вы помните почему? Если нет, то прочтите ещё раз параграф 2. Также становится понятно что с этим делать. Необходимо изменить владельца у созданных Drupal каталога sites/default/files/tmp и файла sites/default/files/.htacces. Всё бы классно, однако с вашими правами доступа вы не сможете этого сделать, ведь для смены владельца файла необходимы права администратора! Более того, теперь вы и удалить каталог sites/default/files не сможете, потому что в нём содержаться файлы, которые у вас нет прав удалить. Так что о смене владельца вам придётся просить хостера! Но можно и не просить, если до перехода на страницу http://yoursite.ru/admin/settings/file-system вы САМИ создадите каталог sites/default/files/tmp, назначите на него права 0777, а в каталоге sites/default/files САМИ создадите файл .htaccess следующего содержимого:

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
Options None
Options +FollowSymLinks

и установите на него права 0644. Ещё такой же файл с такими же правами нужно создать и в sites/default/files/tmp

Теперь проверим всё ли работает как надо. Перейдём на страницу настройки модулей: http://yoursite.ru/admin/build/modules, установим галочку напротив модуля Upload и нажмём кнопку Save Configuration.

Теперь попробуем создать какой-либо материал с прикреплёнными к нему файлами. Для этого перейдём на страницу http://yoursite.ru/node/add/story. Напишите что либо в заголовке (Title) и теле (Body) статьи. Подготовьте какую-либо небольшую картинку в JPEG формате. Разверните поле закачки файла, щёлкнув на странице по File attachments (ниже Body). Укажите имя файла для закачки, нажав Обзор, а затем нажмите Attach. Если вы выбрали небольшую картинку, то закачка должна завершиться успешно и вы увидите файл, прикреплённый к материалу. Теперь нажмите кнопку Save внизу страницы. Вы должны увидеть в зелёной рамочке сообщений о том что "Story created" и увидеть набраный вами текст с прикреплённой внизу картинкой (сама картинка показана не будет)!

5. Неочевидные минусы или возможные грабли


Надеюсь вы уже поняли, что всё-таки лучше нормальный хостинг, а не тот где mod_php, а тем более с включеным safe_mode. Тем не менее, таких хостингов много и теперь вы знаете как и что делать, чтобы ваш Drupal работал. Осталось только не забыть несколько правил.

  1. Другие модули Drupal могут создавать каталоги для собственных нужд. В этом случае вы либо должны создать эти каталоги в нужных местах сами и дать на них права как было сказано в конце предыдущего параграфа до того как их создаст сам Drupal. Либо уже после того как он создаст эти каталоги и матерно выругается на отсуствие доступа и safe_mode, вам придётся просить хостера сменить владельца этих каталогов с web-сервера на вас.
  2. Не забывайте про open_basedir. Если при вызове какой-либо внешней программы или открытии какого-либо файла или каталога вы получите сообщения об отсутствии доступа, например:
     * warning: file_exists() [function.file-exists]: open_basedir restriction in effect.
     File(/style.css) is not within the allowed path(s):
     (/home/z000001) in /home/z000001/yoursite.ru/includes/theme.inc on line 67.
    
    * warning: realpath() [function.realpath]: open_basedir restriction in effect.
     File(/tmp) is not within the allowed path(s):
     (/home/z000001) in /home/z000001/yoursite.ru/includes/file.inc on line 287.
    
    * warning: tempnam() [function.tempnam]: open_basedir restriction in effect.
     File(/tmp) is not within the allowed path(s):
     (/home/z000001) in /home/z000001/yoursite.ru/includes/file.inc on line 526.
    * Невозможно создать файл.
    
    то читайте параграф 3. Если проблема не в ваших PHP-скриптах, использующих неправильные пути, то возможно вам снова потребуется помощь хостера.

1. Исключение составляют нестандартные окружения со специально заточеным Apache, который умеет работать в mod_php, но с правами отдельной учётной записи для каждого виртуального хоста. Однако, такие окружения на момент написания статьи считаются ненадёжными и нестабильными в работе.

ВложениеРазмер
screen6.jpg48.99 kb
screen17.jpg83.76 kb
screen18.jpg57.35 kb