os: CentOS 7
nginx: 1.6.2
httpd: apache 2.4.6
cms: Drupal 7
After my server was compromised I removed all from server, reinstalled OS and soft, and restored data from backup.
Now I configure all services in maximum security style.
After detail researching access logs – I decided to deny any requests for php files except index.php which is in the site documents root for improving security.
Nginx access log contents a lot of records like:
azenv2.php
az.php
and
/*/wp-login.php
/administrator/index.php
/MyAdmin/index.php
First category – backdoors (and one of them hacked my sites, somebody send huge portion of spam from my server).
Second – somebody want to find popular cms and utilities and try some login@password, like admin@123456
My reasons to block both categories by nginx through deny requests to php files are:
-
Even if somebody will upload php-shell – it will be impossible to use it.
-
All these requests are 'not good' a priory – and to refuse them by nginx will protect drupal(httpd+php+mysql) to work and spent power.
My current config for one virtual host:
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 – was not changed after installation.
UPDATE
Finally I create this config for deny:
location ~ \.php$ {
access_log /path/to/log/nginx_deny.log name_log;
deny all;
}
and this config for proxy:
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). So full information about attacks attempts is collects in log.
2). Server not make additional work for bad requests.
3). Drupal cron may work.
Best Answer
You can achieve this in a number of ways.
Integrating quite directly with what you have in your config file, you may wish to simply include a section such as the following;
Which will check for the existence of the requested file before allowing its access/execution.
Further to the above however, I would actually personally recommend using fail2ban which will provide you more comprehensive security if configured correctly; you can configure it to monitor your access logs in real-time and ban IPs from accessing your server(s) by automatically creating new iptables rules on-the-fly, with ban times which you specify.
Personally I have my servers configured to use fail2ban with nginx as per this article (or at least based upon that - you may alter it as you wish).