S
S
sllugovskih2016-07-21 12:47:13
PHP
sllugovskih, 2016-07-21 12:47:13

How to protect yourself from shells on the server?

Есть виртуальный выделенный сервер. На нем крутятся порядка 50 сайтов, все на разных CMS и версиях. Недавно все сайты практически были заражены шеллами и рассылали письма со спамом. После чего пришлось восстанавливать бэкап. Как можно обезопаситься? Обновлять CMS не представляет возможности, есть модули которые заточены только под текущую версию joomla или opencart например.
Возможно взломали только один сайт и через соседнии директории заразили остальные.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vamp, 2016-07-21
@sllugovskih

First you need to separate the sites from each other physically. The site scripts themselves, temporary files and session files.
For example, the structure might be:

/var/www
  + toster.ru
  |  + site
  |  + sessions
  |  + temp
  + example.com
  |  + site
  |  + sessions
  |  + temp
  + остальные сайты

The site folder contains site scripts. Usually this folder (or one of its subfolders) is the site's document root.
Sessions contains session files for site visitors. If they are not separated, then hacking one site will automatically discredit the sessions of all users of other sites. That is, by hacking example.com, you can steal the toster.ru administrator session. The path to this folder is configured by the session.save_path directive.
And temp contains temporary files uploaded by users via html forms (upload_tmp_dir directive). It's also a good idea to send the rest of the temporary files generated by the tmpfile(), tempnam() functions, independently (using the result of the sys_get_temp_dir() function to build the path) or any other function that uses the system temporary directory. Unfortunately, the sys_temp_dir directive responsible for this only appeared in php 5.5.0. If you have an earlier version, then you need to take into account the fact that sites can go to / tmp and you cannot block access to this folder.
---
Next, you need to set up normal access rights. Often on the Internet you can see advice "do chmod 777 on everything". You can't do that. Such permissions have the worst effect on security, because they make it possible to edit any script on the site and embed a small backdoor into the most inconspicuous script belonging to the CMS. It will be possible to reliably get rid of such a appendage only by a complete reinstallation of the CMS. Or you can drive the entire site into the version control system, as Maxim Grechushnikov suggested , and find out which scripts were infected with one command. However, one does not exclude the other. The version control system will allow you to detect infection after the fact, and normal rights will not make it possible to infect a file in principle.
I recommend setting permissions on folders to 755, and on files to 644. At the same time, the owner of all folders and files should be anyone, but not the user under which the web server or php is running (for example, the user under which you yourself log in to the server via ssh). But such rights cannot be set for everything either. The site in the course of its work can generate its own temporary files (for example, cache something to a file, compile templates, store some settings), so for folders into which the site can write something, the rights should be different. Here you can already set 777 for folders and 666 for files. This is quite painstaking work, because each site (especially if they are on different CMS) has its own folders and often the definition of such folders is not trivial.
И права доступа не решают всех проблем. Злоумышленник может встроить вредоносный код в скомпилированный шаблон или отравить кеш. Тогда не помогут ни права (так как для нормальной работы сайту нужно иметь права на запись в такие файлы), ни система контроля версий (так как подобные файлы слишком часто меняются и, как правило, не хранятся в репозитории). Хотя надо сказать, этот способ внедрения сложнее и недолговечнее, чем встраивание в нормальный скрипт.
И ещё автоматическое обновление сайта перестанет работать. Если CMS позволяет обновить себя через кнопку в веб-интерфейсе админки, то такое обновление не будет работать, так как права доступа не разрешают веб-серверу модифицировать скрипты. Обновлять скрипты теперь можно только вручную от имени пользователя, которому принадлежат все файлы. Безопасность и удобство - разные концы одной палки.
Даже с учётом всех недостатков - нормально настроенные права доступа на файлы и папки значительно сокращают вектор возможных атак. Так что обязательно разберитесь с этим вопросом.
---
После раскидывания сайтов по своим папкам и настройки прав, необходимо ограничить доступ сайтов друг к другу. Проще всего это сделать настройкой php директивы open_basedir. Эта директива определяет список директорий, внутри которых (а так же во всех вложенных папках) скрипты могут читать и писать. Доступ за пределы этих директорий будет пресекаться. То есть нужно каждому сайту прописать в open_basedir путь к своей папке и к /tmp (если версия php < 5.5.0 и нельзя установить sys_temp_dir).
Для Apache с mod_php конфигурация прописывается в httpd.conf:
<VirtualHost *:80>
  ServerName example.com
  php_admin_value open_basedir /var/www/example.com/:/tmp/
  php_admin_value upload_tmp_dir /var/www/example.com/temp/
  php_admin_value sys_temp_dir /var/www/example.com/temp/
  php_value session.save_path /var/www/example.com/sessions/
</VirtualHost>

Для php-fpm в конец php.ini файла вписывается специальная секция, определяющая индивидуальную конфигурацию для каждого сайта:
[HOST=example.com]
open_basedir /var/www/example.com/:/tmp/
upload_tmp_dir /var/www/example.com/temp/
sys_temp_dir /var/www/example.com/temp/
session.save_path /var/www/example.com/sessions/

[HOST=toster.ru]
; конфиг для toster.ru и т.д.

У open_basedir есть недостатки:
1. Замедление файловых операций, так как необходимо проверить вхождение каждого открываемого файла в список open_basedir. Если проекты не highload, то некритично.
2. Есть варианты обхода. Но их далеко не всегда удаётся эксплуатировать. Тем более они закрываются со временем в новых версиях php.
3. Realpath cache не работает вместе с включенной open_basedir.
---
Есть вариант запускать каждый сайт от своего пользователя. В apache это делается опцией AssignUserId. В php-fpm - отдельной конфигурацией pool. Но в любом случае нужно для каждого сайта создавать не только отдельного юзера, но и группу. При этом права на основную папку сайта (/var/www/example.com) должны быть 750, а группа должна соответствовать той, от которой будет запускаться процесс apache (или пул php-fpm), ответственный за обслуживание сайта.
Проще показать на примере. После имени файла я буду указывать права, владельца и группу в формате (права, владелец:группа)
/var/www         (755, root:root)
  + toster.ru    (750, my_user:toster)
  |  + site      (755, my_user:toster)
  |  + sessions  (777, my_user:toster)
  |  + temp      (777, my_user:toster)
  + example.com  (750, my_user:example)
  |  + site      (755, my_user:example)
  |  + sessions  (777, my_user:example)
  |  + temp      (777, my_user:example)
  + остальные сайты - всё аналогично

my_user - это пользователь, под которым ни в коем случае нельзя запускать веб-сервер и php. Это может быть ваш собственный пользователь, под которым вы заходите на сервер по ssh. В этом случае у вас будут все права на сайт, а у сайта только необходимый минимум.
<VirtualHost *:80>
  ServerName example.com
  AssignUserId exapmle example
</VirtualHost>
<VirtualHost *:80>
  ServerName toster.ru
  AssignUserId toster toster
</VirtualHost>

Разумеется, в системе должны быть заранее созданы пользователи с именами toster, example и с одноимёнными основными группами.
Вобщем, рекомендую более подробно ознакомиться с системой прав и пользователей в линуксе. Пригодится всегда.
---
Более сложным и предпочтительным вариантом является упаковка каждого сайта в свой отдельный виртуальный контейнер lxc/docker. Я не смогу в двух словах описать как это добро настраивать, но эффект будет такой, как будто каждый сайт работает на своём собственном VPS сервере.
---
Ещё немного про базу. Для доступа к базе у каждого сайта должен быть свой собственный логин с паролем. Причем, доступ должен ограничиваться исключительно той базой, в которой находятся данные сайта. И права должны быть не все подряд, а только SELECT, INSERT, UPDATE, DELETE. В редких случаях CMS может самостоятельно создавать таблицы для своих нужд в процессе своей работы (не в процессе первичной установки). В этом случае можно добавить права CREATE, ALTER, INDEX юзеру этого сайта. Иногда бывает в базе есть какие-то процедуры/функции. Для их вызова требуются права EXECUTE.
---
Безопасность - дело большое и очень разнообразное. И уж точно не простое. Всё что я здесь написал - это далеко не полный список. Есть ещё настройки уровня операционной системы (особенно фаервол) и прочего установленного в системе софта. Так же отдельным пунктом идёт система мониторинга и оповещения, которые почему-то никто не делает - не считают нужным разбираться ещё и в этом. Так что если у вас нет хорошего админа в запасе, то проще будет заказать услугу администрирования прямо у того же хостера, у которого вы арендуете VPS. Или найти админа-фрилансера. Или же перевезти сайты на shared хостинг, где администрирование уже включено в ценник, да и сам переезд хостеры часто предлагают сделать бесплатно силами своих админов.

M
Maxim Grechushnikov, 2016-07-21
@maxyc_webber

no way. joomla and opencart are synonymous with holes. Well, maybe not they themselves, but their components. Recently I hacked one site through a blunt insertion, I went through a file upload file that was not closed for direct access from TinyMCE or whoever, I don’t remember
at one time I defended myself as follows (although I protected Bitrix and frameworks, but it doesn’t change the essence)
I kept all sites in git repositories and gave all site files read-only access 0555
If some kind of infection appeared, it was enough for me to restore everything with one command. and git easily showed which files changed and what was changed
, and most importantly, never keep all sites under one user. do not be lazy to create different users. including for databases, and even better install (if you have a vps) control panel

P
Puma Thailand, 2016-07-21
@opium

scatter all sites among different users
if the sites do not change, prohibit writing to files and folders and mark all files as unchanged

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question