Я уже довольно долгое время хочу формализовать все свои мысли, опыт, ежедневно применяемый на практике, и многое другое в одном месте и предоставить их общественности. Уверен, многим этот материал будет полезен. Он посвящен различным моментам в конфигурации серверного ПО Linux и безопасным подходам к созданию сайтов/приложений на php (все же это до сих пор одна из самых популярных связок, хоть её успешно и подвигают другие технологии).
Т.е. речь идет о типичной ситуации. Проект (стартап), купили под него сервер и разворачиваем на нем сайт. Бизнесу не нужно тратить лишних денег на сервера (поэтому будут выбраны наиболее производительные связки ПО), а так же нужно, чтобы все было безопасно, при чем бесплатно :)
Конфигурация серверного ПО
Nginx + php-fpm
Начал бы я с объяснения выбранной связки. У меня были различные ресурсы, довольно высоконагруженные, где нужно было уживаться сразу нескольким приложениям, а кроме того, не только вебу. Я перепробовал всевозможные связки (apache, apache с отдачей статики nginx'ом, nginx + php в режиме cgi и т.д.) и наилучшим вариантом все-таки оказалась связка nginx + php-fpm. Как по стабильности, так и по гибкости настройки, так и в плане безопасности. Ну а если у вас до сих пор Apache, то прекратите им пользоваться прямо сейчас (С) не помню откуда (хотя следующие советы легко портируются и подходят и для любой другой связки).
Прежде всего хотел бы сказать, что стоит разделять машины для каждого ресурса. Да, можно каждый сайт изолировать друг от друга, как это делается на shared-хостингах, но все же сейчас аренда виртуальных серверов не так высока (задумайтесь над этим, прежде чем разместить еще один сайт на этой же машине, пусть даже соблюдая различные правила: разные юзеры для каждого ресурса и т.д. Ну или пытайте jail ;).
Начнем с конфига самого сайта:
location /index.php {
...
fastcgi_pass unix:/var/run/php-fpm/php-fpm.socket;
...
}
Желательно спроектировать веб-приложение так, чтобы оно могло работать всего от одного php-файла в htdocs и подобным образом настроить location — /index.php. Это исключает вообще возможность выполнения залитого php-шелла в htdocs. Мы вернемся к этому во второй части этой статьи.
Фиксим багу с fix_pathinfo, описанную тут. Редактируем php.ini и меняем значение параметра fix_pathinfo на
cgi.fix_pathinfo=0
Усложняем жизнь скрипт-кидди и блочим популярные сканеры по UA (из статьи):
if ( $http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan) ) {
return 403;
}
Верьте мне, львинная часть «хакеров» отсеется :)
X-Frame-Options
Добавляем жизненно необходимые заголовки (так же почерпнем информации из статьи VladimirKochetkov. Во-первых, запретим показ нашего ресурса в iframe:
add_header X-Frame-Options DENY;
Это спасет наш ресурс от возможного DDOS'a через iframe, а так же от возможного clickjacking'a на сайте.
X-Content-Type-Options
add_header X-Content-Type-Options: nosniff;
Это скажет IE, что нет необходимости автоматически определять Content-Type, а необходимо использовать уже отданный content-type. Уже были security-баги у IE, связанные именно с автоматическим определением типа содержимого.
X-XSS-Protection
add_header X-XSS-Protection: 1; mode=block;
Так же заголовок для IE. Активирует встроенную XSS-защиту.
X-Content-Security-Policy
Довольно специфичный заголовок, будьте осторожны с ним
add_header X-Content-Security-Policy: allow 'self';
add_header X-WebKit-CSP: allow 'self';
Определяет, с каких доменов можно подгружать JS (X-Content-Security-Policy для IE10 и X-WebKit-CSP для FF/Chrome). В примере выше указано правило, которое позволит подгружать JS только с этого же домена.
Strict-Transport-Security
Если Ваш ресурс работает через https и происходит редирект с 80го порта на 443 (для удобства) то клиент можно поддерживать некоторое время незащищенное соединение. Данный заголовок исключает возможность MITM в этот самый, довольно короткий, промежуток времени (перехват трафика в TOR). Подробнее здесь.
Firewall
Одна из важнейших конфигураций. Общая идея такая — разрешаем несколько, запрещаем все остальное. Я не гуру iptables, возможно кто-нибудь в комментариях меня поправит и мы придем к более лучшему решению. Считаем, что eth0 у нас внешний интерфейс и будем ограничивать именно его (обычно доступ из внутренней сети полный).
-A INPUT -i eth0 -p icmp -j ACCEPT # разрешаем пинг до нашаего ресурса
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT # разрешаем только уже поднятые или порождаемые соединения
-A INPUT -s 12.34.56.78 -i eth0 -j ACCEPT # здесь указываем IP адрес, с которого бы нам желательно иметь полный доступ ко всем портам (если это требуется)
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # ssh
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT # web
-A INPUT -i eth0 -j DROP # запрещаем все остальное
К данной конфигурации так же можно добавить авто-баны при ддосе, но я предпочитаю не использовать их до первой необходимости.
Мониторим файловую систему
Linux для мониторинга файловой системы предоставляет отличное API — inotify (более подробная статья от youROCK). И существует уже готовый скрипт на perl (конечно, есть аналоги) — iwatch, который полностью автоматизирует процесс мониторинга нужных нам директорий. Установка в debian системах проста:
apt-get install iwatch
И получаем отличные часики Конфиг файл находится по адресу etc/iwatch/iwatch.xml и выглядит следующим образом:
<?xml version="1.0" ?>
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
<config lang="xml">
<guard email="youremail@gmail.com" name="IWatch"/>
<watchlist>
<title>Operating System</title>
<contactpoint email="root@localhost" name="Administrator"/>
<path type="single" syslog="on">/bin</path>
<path type="single" syslog="on">/sbin</path>
<path type="single">/etc</path>
<path type="recursive">/lib</path>
<path type="exception">/lib/modules</path>
</watchlist>
</config>
Все довольно очевидно. Перечисляем нужные нам папки, что надо — исключаем и указываем почту, куда слать отчеты (на gmail все отлично приходит).
Если решите просто скачать скрипт с sourceforge, то нужные зависимости в perl доставляются очень просто — cpan #modulename, например cpan XML::SimpleObject::LibXML.
AppArmor, SELinux, chroot и другие приблуды
К сожалению, если в гугле ввести «SELinux» то первой подсказкой будет «SELinux disable». С AppArmor похожая песня. Частично это связано с тем, что этих средства защиты включены по-умолчанию и доставляют проблемы работающему софту. И ты уже потратил битый час и выпил третью кружку кофе, разбираясь, почему не работает нужный скрипт/софт. Я бы предложил все-таки разобраться с этими «магиями мира Linux» и ознакомиться со следующими статьями:
- SELinux на практике: DVWA-тест от isox
- Введение в SELinux: модификация политики targeted для сторонних веб-приложений так же от isox
- Механизмы безопасности в Linux от nuald
Хочу сказать, что на практике действительно бывают проблемы при пентесте/взломе от подобных механизмов, так что постарайтесь не пренебрегать ими.
IPS, IDS, WAF
Если у вас уже действующий бизнес-проект, то предлагаю пропустить чтение каких-либо статей по настройке WAF/IPS/IDS и воспользоваться готовыми решениями например от F5 или от Cloudflare. С Cloudflare вообще куча проблем (для атакующих). Если я вижу, что ресурс на нем, это сразу означает потраченное время х 5. Могу сказать, что Anonymous и другие pro-security люди используют именно Cloudflare (никакой рекламы, это просто факт). Конечно, есть варианты обхода и этих систем, но они обычно требуют от атакующего дополнительных растрат, к примеру на аренду машин в облаке с кучей разных IP-адресов, но это уже тема немного другого топика.
Ну а если проект только в начале своего пути и нет денег на подобные сервисы, то предлагаю следующие статьи к прочтению:
- SNORT как сервисная IPS от sandman
- Использование snort для блокирования атак скрипт-киддисов от kreon
На Хабре нет ничего про Suricata (мне ее настойчиво рекомендовал один знакомый хакер из Африки). К сожалению, сам ничего сказать не могу о ней, и не знаю ссылок на хорошие обзоры. Я придерживаюсь использования защитных проксирующих сервисов перечисленных в начале.
Про ведение бэкапов, верные chmod/chown, мониторинг логов (error.log в т.ч.) и событий системы я умолчу, это должно быть само собой разумеющимся.
Автор: BeLove