nginx - отклонить все запросы *.php, кроме index.php по соображениям безопасности

ОС: 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:

  1. Даже если кто-то загрузит php-оболочку - использовать его будет невозможно.

  2. Все эти запросы "плохие", как правило, - и отказ от них с помощью 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 - не был изменен после установки.


ОБНОВИТЬ
Наконец-то я создаю этот конфиг для deny:

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 может работать.

1 ответ

Вы можете достичь этого несколькими способами.

Непосредственно интегрируясь с тем, что у вас есть в вашем конфигурационном файле, вы можете захотеть просто включить следующий раздел:

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 в соответствии с этой статьей (или, по крайней мере, основываясь на этом - вы можете изменить его по своему желанию).

Другие вопросы по тегам