Debian.pro/

Про Debian


Безопасность в Debian. Debian LAMP. Часть 5 — задумываемся над безопасностью нашего веб-сервера, когда на нём больше одного сайта.

Данная статья является статьей цикла «Установка LAMP на Debian/Ubuntu — very fast way»

В статье Debian, LAMP (linux+apache+php+mysql). Very fast way. Часть 4. Размещаем свой первый сайт я описал как нам быстро разместить сайт на нашем веб сервере. Но способ описанный там недостаточно безопасен, если на вашем сайте есть несколько пользователей, которые могут размещать на сервере php скрипты. Один пользователь сможет получить доступ к файлам другого пользователя. В случае с CMS вроде Joomla или Drupal — это означает, что и к чужой mysql базе доступ можно тоже поиметь.

У нас есть пользователь webuser. Пользователю необходимо разместить сайт example1.ru на нашем сервере так, чтобы скриптами с его сайта нельзя было получить доступ к файлам других пользователей (и с небольшой модернизацией алгоритма — сайтов того же пользователя). Так же нам необходимо защитить файлы пользователя webuser от доступа со стороны других пользователей. Конечно, для этого больше подходит ограничение файлового доступа пользователей вообще и запрет заходить им по ssh, но это не всегда удобно для самих пользователей. Приступим.
Создадим группу, которая поможет нам ограничивать файловый доступ пользователей.
root@debian-lamp:~# addgroup fsecure
Добавим в эту группу всех пользователей, которым мы не желаем доверять файлы других пользователей (webuser в нашем случае).
root@debian-lamp:~# usermod -G fsecure webuser
Проверим, что пользователь добавился в группу:
root@debian-lamp:~# id webuser
В списке групп пользователя должен присутствовать наша группа — fsecure.
Приступим к созданию экосистемы для нашего вебсервера. Создадим нужные каталоги:
root@debian-lamp:~# mkdir -p /home/*/data
Теперь всем пользователям, которые добавлены в группу fsecure нам необходимо изменить домашний каталог, например, с /home/webuser на /home/webuser/data в файле /etc/passwd
Помните, что в группу fsecure следует добавить (и сменить домашние каталоги) нужно всех пользователей, у которых потенциально может возникнуть идея получить доступ к чужим файлам.
Продолжим заниматься экосистемой:
root@debian-lamp:~# chown root:root /home && chmod 755 /home
Защитим каталог пользователя webuser от остальных пользователей группы secure:
root@debian-lamp:~# chown webuser:fsecure /home/webuser && chmod 501 /home/webuser
Починим домашний каталог, чтобы у пользователя не возникало проблем:
root@debian-lamp:~# chown webuser:webuser /home/webuser/data && chmod 751 /home/webuser/data
Создадим каталог pool1 для того, чтобы разместить там некоторые сайты (во второй части мануала будет и pool2):
root@debian-lamp:~# mkdir /home/webuser/data/pool1 webuser:webuser && chown /home/webuser/data/pool1 && chmod 751 /home/webuser/data/pool1
В pool1 мы расположим те сайты, которым необходим общий каталог для сессий (например wiki и форум с единой системой авторизации) и временных файлов. Если таких сайтов нет — для каждого сайта создавайте отдельный poolX.
Создадим каталоги для логов, временных файлов, сессий и самих файлов сайта и выдадим им необходимые права:
root@debian-lamp:~# mkdir /home/webuser/data/pool1/logs
root@debian-lamp:~# mkdir /home/webuser/data/pool1/tmp
root@debian-lamp:~# mkdir /home/webuser/data/pool1/www
root@debian-lamp:~# chown webuser:webuser /home/webuser/data/pool1/logs && chmod 751 /home/webuser/data/pool1/logs
root@debian-lamp:~# chown www-data:webuser /home/webuser/data/pool1/tmp && chmod 700 /home/webuser/data/pool1/tmp
root@debian-lamp:~# chown webuser:webuser /home/webuser/data/pool1/www && chmod 751 /home/webuser/data/pool1/www
Уфф. Вроде всё, каталоги создали. Файлы сайта пользователю следует размещать в подкаталогах каталога www. В нашем примере это будет www/example1.ru

Теперь приступим к написанию параметров виртуалхоста. Можете написать этот кусок конфига в /etc/apache2/apache.conf или в /etc/apache2/sites-enabled/example-ru



<VirtualHost *:80>
ServerName example1.ru
DocumentRoot /home/webuser/data/pool1/www/example1.ru # указываем, в каком каталоге расположены файлы сайта.
#SuexecUserGroup webuser webuser # директива не работает для mod_php, но оставим её на будущее.
CustomLog /home/webuser/data/pool1/logs/example1.ru.access.log combined # файл лога сайта
ErrorLog /home/webuser/data/pool1/logs/example1.ru.access.log # файл лога ошибок сайта
ServerAlias www.example1.ru # домены-алиасы для сайта
ServerAdmin webmaster@example1.ru # указываем администратора домена - эта почта отображается на страничках ошибок
php_admin_value open_basedir "/home/webuser/data/pool1:." # этой строчкой мы запрещаем скриптам сайта выходить за пределы нашего pool1
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f webmaster@example1.ru" # команда, при помощи которой скрипты сайта будут отправлять почту через функцию mail(). Чтобы корректно написать эту строку - настройте почтовый сервер. Хотя эта строка по дефолту должна работать.
php_admin_value upload_tmp_dir "/home/webuser/data/pool1/tmp" # указываем каталог с временными файлами пользователя.
php_admin_value session.save_path "/home/webuser/data/pool1/tmp" # указываем каталог для файлов сессий сайта.
AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
AddType application/x-httpd-php-source .phps
</VirtualHost>

Если у вас уже стоит nginx, то <VirtualHost *:80> стоит заменить на <VirtualHost 127.0.0.1:8080> (и в nginx это указать бэк-эндом для сайта).

Не забываем сделать /etc/init.d/apache2 restart.
Собственно всё. Повторяем алгоритм для всех пользователей, которые будут содержать у нас сайты.
Не забываем сказать пользователю про директивы, которые мы указали в настройках виртуалхоста. В настройках CMS должны быть корректно указаны каталоги с сессиями и временной каталог. PHP скрипты этого сайта не смогут выйти за пределы каталога /home/webuser/data/pool1

Не забудьте напомнить пользователю, что у системного пользователя www-data должен быть доступ на чтение к файлам его сайта (и только сайта — всё остальное необходимое в правах мы уже поправили) и на запись в каталоги вида upload и так далее.

О замеченных неточностях пишите в комментариях. Мысли разбегались кучу раз.. мог где то ошибиться.
Чуть позже я напишу ещё несколько примеров к этому мануалу.


Комментарии (40):

  1. basil :

    root@debian-lamp:~# chown /home root:root && chmod 755 /home

    should be

    root@debian-lamp:~# chown root:root /home && chmod 755 /home

  2. спасибо, поправил

  3. basil :

    А можно статьи про настройку почты и FTP ? Ж)

  4. wartur :

    php_admin_value open_basedir
    Не согласен, гораздо безопаснее пользоваться не программной а системной безопасностью с помощью apache2-mpm-itk

  5. А здесь про mpm-itk речи не шло. На нем мы atuonlamp сделаем.

  6. Evgeny :

    mkdir /home/axacter/data/axacter.com && chown axacter:axacter /home/axacter/data/axacter.com && chmod 751 /home/axacter/data/axacter.com

  7. Evgeny :

    mkdir /home/webuser/data/webuser.com/logs && chown webuser:webuser /home/webuser/data/webuser.com/logs && chmod 751 /home/webuser/data/webuser.com/logs
    mkdir /home/webuser/data/webuser.com/tmp && chown www-data:webuser /home/webuser/data/webuser.com/tmp && chmod 700 /home/webuser/data/webuser.com/tmp
    mkdir /home/webuser/data/webuser.com/www && chown webuser:webuser /home/webuser/data/webuser.com/www && chmod 751 /home/webuser/data/webuser.com/www

  8. Evgeny :

    <копипаст с чужого блога удален>.

  9. Evgeny :

    у меня вопрос нащет php_admin_value open_basedir «/home/webuser/data/pool1:.»
    как его описат если например скрипты gallery2 исползуют бинарники из /usr/bin
    так как если я добавлю :/usr/bin то смысл в php_admin_value open_basedir

  10. Задайте этот вопрос разработчикам скрипта лучше =)

  11. Evgeny :

    esli ispolzovat apache2-mpm-itk вх запускаетса от имени webuser значит все папки и файлы сайта должны chown webuser:webuser ?

  12. mpm-itk запускается от того пользователя, который прописан в AssignID для конкретного виртуалхоста.

  13. Evgeny :

    webuser to username
    password to userpassword
    webuser.com to userdomain

    if not exists

    addgroup fsecure

    useradd -d /home/webuser/data -s /bin/sh -G fsecure -p password webuser
    mkdir -p /home/webuser/data
    chown root:root /home && chmod 755 /home
    chown webuser:fsecure /home/webuser && chmod 501 /home/webuser
    chown webuser:webuser /home/webuser/data && chmod 751 /home/webuser/data
    mkdir /home/webuser/data/webuser.com && chown webuser:webuser /home/webuser/data/webuser.com && chmod 751 /home/webuser/data/webuser.com
    mkdir /home/webuser/data/webuser.com/logs && chown webuser:webuser /home/webuser/data/webuser.com/logs && chmod 751 /home/webuser/data/webuser.com/logs
    mkdir /home/webuser/data/webuser.com/tmp && www-data:webuser /home/webuser/data/webuser.com/tmp && chmod 700 /home/webuser/data/webuser.com/tmp
    mkdir /home/webuser/data/webuser.com/www && chown webuser:webuser /home/webuser/data/webuser.com/www && chmod 751 /home/webuser/data/webuser.com/www

  14. Evgeny :

    pochti skript kto znaet kak sdelat iz etogo skript budu rad skatat )
    vynesti peremennye i td )

    addclient username password domain additionlgroup

  15. Evgeny :

    vot vrode nabrosok eshjo ne proverjal )

    #!/bin/bash
    #echo $1 to username
    #echo $2 to userecho $2
    #echo $3 to userdomain
    #echo $4 additionalGroup
    useradd -d /home/echo $1/data -s /bin/sh -G echo $4 -p echo $2 echo $1
    mkdir -p /home/echo $1/data
    chown root:root /home && chmod 755 /home
    chown echo $1:echo $4 /home/echo $1 && chmod 501 /home/echo $1
    chown echo $1:echo $1 /home/echo $1/data && chmod 751 /home/echo $1/data
    mkdir /home/echo $1/data/echo $3 && chown echo $1:echo $1 /home/echo $1/data/echo $3 && chmod 751 /home/echo $1/data/echo $3
    mkdir /home/echo $1/data/echo $3/logs && chown echo $1:echo $1 /home/echo $1/data/echo $3/logs && chmod 751 /home/echo $1/data/echo $3/logs
    mkdir /home/echo $1/data/echo $3/tmp && www-data:echo $1 /home/echo $1/data/echo $3/tmp && chmod 700 /home/echo $1/data/echo $3/tmp
    mkdir /home/echo $1/data/echo $3/www && chown echo $1:echo $1 /home/echo $1/data/echo $3/www && chmod 751 /home/echo $1/data/echo $3/www

  16. Не мучайся, в новой версии anlamp эту штуку вкручу уже. Учитывая модульность — можно будет отдельно выдернуть.

  17. alex13 :

    Опечатка: chown /home/webuser/data/pool1 webuser:webuser (поменять местами)
    Логи ошибок в апаче разве не в отдельный файл лучше записывать?

    Настроил за день свой первый ВДС по вашим статьям. Спасибо )

  18. Ага, спасибо, поменял.

    > Логи ошибок в апаче разве не в отдельный файл лучше записывать?
    Это уж как хотите =)

  19. oleg :

    Здравствуйте! Скажите пожалуйста, я все сделал по данной интсрукции. Зашел по SSH от имени пользователя, но не могу зайти в папки www и logs, а в tmp попадаю. Выдает такую ошибку:
    can’t cd to /www
    can’t cd to /logs
    can’t cd to /www/mysite1.ru

    ls -l выдает такое:

    drwxr-x—x 2 user1 user1 4096 Jun 5 11:37 logs
    drwx—— 2 user1 user1 4096 Jun 5 11:26 tmp
    drwxr-x—x 3 user1 user1 4096 Jun 5 11:31 www

    Очень прошу Вас помочь!

  20. oleg :

    Прошу прощения, вопрос снимается. Оказывается cd для пользователя показывается несколько по иному, и я получается обращался с папки tmp к папкам www т.д. Спасибо всем! Можно удалить мои комменатрий.

  21. Влад :

    Не подскажите в чем беда , apache не хотит рестартиться
    php_admin_value takes two arguments, PHP Value Modifier (Admin)

  22. grep -rni php_admin_value /etc/apache2
    покажите

  23. Влад :

    grep -rni php_admin_value /etc/apache2
    /etc/apache2/sites-available/default:5: php_admin_value open_basedir «/home/workstat/www-data/public:.»
    /etc/apache2/sites-available/default:6: php_admin_value sendmail_path «/usr/sbin/sendmail -t -i -f developer@lancer.in.ua»
    /etc/apache2/sites-available/default:7: php_admin_value upload_tmp_dir «/home/workstat/www-data/tmp»
    /etc/apache2/sites-available/default:8: php_admin_value session.save_path «/home/workstat/www-data/tmp»
    /etc/apache2/mods-available/php5.conf:25: php_admin_value engine Off
    /etc/apache2/sites-enabled/lancer~:5: php_admin_value open_basedir «/home/workstat/www-data/public:.»
    /etc/apache2/sites-enabled/lancer~:6: php_admin_value sendmail_path «/usr/sbin/sendmail -t -i -f developer@lancer.in.ua»
    /etc/apache2/sites-enabled/lancer~:7: php_admin_value upload_tmp_dir «/home/workstat/www-data/tmp»
    /etc/apache2/sites-enabled/lancer~:8: php_admin_value session.save_path «/home/workstat/www-data/tmp»

  24. Влад :

    кажется доперло)) я симлинк просто переименовал

  25. Влад :

    не помогло , на 6 строчку матерится .

  26. На 6ю строчку чего) ? Что в консоли пишут, целиком показывайте.

  27. Влад :

    service apache2 restart
    Syntax error on line 6 of /etc/apache2/sites-enabled/lancer:
    php_admin_value takes two arguments, PHP Value Modifier (Admin)
    Action ‘configtest’ failed.

  28. А если закомментировать
    php_admin_value sendmail_path «/usr/sbin/sendmail -t -i -f developer@lancer.in.ua»
    ?

  29. Влад :

    во так запустилось ) спасибо )

  30. Ну если вам почту с этого сайта из php отсылать не нужно — то сойдет. Если нужно — то придется разобраться, какой вы там модуль недоставили или сломали)

  31. Влад :

    Скажите как с Вами можно связаться icq / skype / jabber / irc
    хотелось бы спросить немного про виртуализацию?

  32. Влад :

    Коммент к вчерашнему не работающему сендмайлу, после настройки запустилось , не не работало , писало в еррор лог что openbase_dir не позволяет выполнить скрипт , зарпещенная директория, в итоге заменил все ««» на » , заработало). Настроил почту по Вашему ману )) у провайдера закрыт 25 порт, а почта все еже приходит , правда только на яндекс и в спам )

  33. Влад :

    у Вас Wp кавычки режет )

  34. wp кавычки у всех режет без тега code:
    ""

  35. > не позволяет выполнить скрипт , зарпещенная директория
    Тогда basedir проще вообще отключить.

  36. Ну или если нужна и там есть другие сайты — разобраться, что апачу в правах не понравилось

  37. Влад :

    помоему ему такие кавычки не понравились » , заменил на "

  38. А блин. Понял, откуда проблема, извиняюсь) Сейчас в посте кавычки поправлю.

Написать комментарий