ОС: CentOS 7
nginx: 1.6.2
httpd: apache 2.4.6
cms: Drupal 7
После того, как мой сервер был взломан, я удалил все с сервера, переустановил ОС и программное обеспечение и восстановил данные из резервной копии. Сейчас я настраиваю все службы в стиле максимальной безопасности.
После детального изучения журналов доступа я решил отклонить любые запросы на файлы php, кроме index.php который находится в корневом каталоге документов сайта для повышения безопасности.
Журнал доступа Nginx содержит множество записей, например:
azenv2.php
az.php
и
/*/wp-login.php
/administrator/index.php
/MyAdmin/index.php
Первая категория - бэкдоры (и один из них взломал мои сайты, кто-то рассылал с моего сервера огромную порцию спама).
Во-вторых, кто-то хочет найти популярные cms и утилиты и попробовать какой-нибудь логин @ пароль, например admin @ 123456.
Мои причины заблокировать обе категории с помощью nginx через запросы на отказ в файлах php:
Даже если кто-нибудь выложит php-шелл - это будет невозможно использовать.
Все эти запросы априори «нехорошие» - и отказ от них со стороны nginx защитит drupal (httpd + php + mysql) для работы и потраченной энергии.
Моя текущая конфигурация для одного виртуального хоста:
server {
listen <server-ip>;
server_name <site-name>;
location ~* /sites/default/files/styles/ {
try_files $uri @imagestyles;
}
location @imagestyles {
proxy_pass http://127.0.0.1:<port>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
access_log off;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|pdf|zip|rar|mp3|flv|doc|xls)$ {
root <site-documents-root>;
access_log off;
}
location ~ (^|/)\. {
deny all;
}
location / {
proxy_pass http://127.0.0.1:<port>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
access_log <path-to-log-folder>/nginx_access.log main;
}
}
nginx.conf - после установки не менялся.
ОБНОВИТЬ
Наконец, я создаю этот конфиг для отказа:
location ~ \.php$ {
access_log /path/to/log/nginx_deny.log name_log;
deny all;
}
и этот конфиг для прокси:
location =/index.php {
proxy_pass http://127.0.0.1:<port>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location =/cron.php {
proxy_pass http://127.0.0.1:<port>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
proxy_pass http://127.0.0.1:<port>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
1). Таким образом, полная информация о попытках атак собирается в журнале.
2). Сервер не выполняет дополнительную работу по неверным запросам.
3). Drupal cron может работать.
Вы можете добиться этого несколькими способами.
Совершенно прямая интеграция с тем, что у вас есть в вашем файле конфигурации, вы можете просто включить такой раздел, как следующий;
location ~ \.php$ {
try_files index.php @error;
fastcgi_pass ...;
fastcgi_param SCRIPT_FILENAME /path/to$fastcgi_script_name;
...
}
location @error {
[config of however you want to handle errors]
}
Что будет проверять наличие запрошенного файла, прежде чем разрешить его доступ / выполнение.
Однако в дополнение к вышесказанному я бы лично рекомендовал использовать fail2ban который при правильной настройке обеспечит более полную безопасность; вы можете настроить его для мониторинга журналов доступа в режиме реального времени и запретить IP-адресам доступ к вашему серверу (-ам), автоматически создавая новые правила iptables на лету с указанным вами временем запрета.
Лично у меня есть серверы, настроенные на использование fail2ban с nginx согласно Эта статья (или, по крайней мере, исходя из этого - вы можете изменить его, как хотите).