Monthly Archives: October 2016


apt-get install build-essential libpcre3-dev libssl-dev zlib1g-dev

sudo tar -xzf nginx-1.10.1.tar.gz
sudo tar -xzf ngx_cache_purge-2.3.tar.gz

sudo ./configure –sbin-path=/usr/sbin –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –pid-path=/var/run/ –lock-path=/var/lock/nginx.lock –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/body –http-proxy-temp-path=/var/lib/nginx/proxy –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –with-debug –with-http_stub_status_module –with-http_flv_module –with-http_ssl_module –with-http_dav_module –with-ipv6 –add-module=/tmp/ngx_cache_purge-2.3
make && make install

mkdir -p /var/lib/nginx
mkdir -p /var/lib/nginx/body
mkdir -p /var/lib/nginx/fastcgi


user www-data;
#GROUP www-data;
worker_processes 8;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/;

events {
worker_connections 1024;

http {
include mime.types;
default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain text/html text/css
application/x-javascript text/xml
application/xml application/xml+rss

upstream php {
#this should match value of "listen" directive in php-fpm pool
# server unix:/var/run/php5-fpm.sock;

proxy_cache_path /opt/nginx/cache/proxy levels=1:2 keys_zone=microcache:8m max_size=1000m inactive=600m;
proxy_temp_path /tmp/nginx;
proxy_cache_key "$scheme$request_method$host$request_uri";

#move next 3 lines to /etc/nginx/nginx.conf if you want to use fastcgi_cache across many sites
fastcgi_cache_path /opt/nginx/fastcgicache levels=1:2 keys_zone=WORDPRESS:500m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;

map $http_host $blogid {
default 0; 1; 1;


listen 80 default_server;
server_name _; # This is just an invalid value which will never trigger on a real hostname.
access_log /var/log/nginx/default.access.log;
server_name_in_redirect off;

root /var/www/default/htdocs;
server {
listen 80;

root /home/arcai/public/;
index index.php;

#fastcgi_cache start
set $no_cache 0;
set $loggable 1;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $no_cache 1;
if ($query_string != "") {
set $no_cache 1;

# Don't cache uris containing the following segments
if ($request_uri ~ "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|paypal/|netCut/|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $no_cache 1;

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $no_cache 1;

if ($request_uri ~ ^/(about-arcai-com|speed-test|netcut-defender-download|netCut/sharenetcut.html|netCut/sharenetcutdefender.html|netcut-defender|cut-off-action|root-android) )
set $no_cache 0;

if ($http_user_agent ~* "(Mediapartners-Google|wget)") {

set $no_cache 0;


location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico)(\?.*)?$ {
expires 365d;
set $no_cache 0;
add_header Cache-Control "public";

location ~* \.(exe|apk)$ {
expires 1h;
add_header Cache-Control "public";

location ~ ^/netCut/(sharenetcut.html|netcutst.php|Update|Internet.php|billengine.php)
#set $host "";
proxy_set_header Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 100M;
client_body_buffer_size 1m;
proxy_intercept_errors on;
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 256 16k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_max_temp_file_size 0;
proxy_read_timeout 300;
set $no_cache 0;

include global/restrictions.conf;

# Additional rules go here.

# Only include one of the files below.
include global/wordpress-ms-subdir.conf;

location ~ /purge(/.*) {
# Uncomment the following two lines to allow purge only from the webserver
#deny all;

fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";

# concurs with nginx's one
location ~ /\.ht {
deny all;

include /etc/nginx/sites-enabled/*;

access_log /var/log/nginx/ combined if=$no_cache;
error_log /var/log/nginx/;



# Global restrictions configuration file.
# Designed to be included in any server {} block.
location = /favicon.ico {
log_not_found off;
access_log off;

location = /robots.txt {
allow all;
log_not_found off;
access_log off;

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;


# WordPress multisite subdirectory rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
location / {
try_files $uri $uri/ /index.php?$args;

# Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 24h;
log_not_found off;

location ~ ^/[_0-9a-zA-Z-]+/files/(.*)$ {
try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ;
access_log off; log_not_found off; expires max;

#avoid php readfile()
location ^~ /blogs.dir {
alias /var/www/ ;
access_log off; log_not_found off; expires max;

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-ms-subdir-wp-super-cache.conf;
#include global/wordpress-ms-subdir-w3-total-cache.conf;

# Rewrite multisite '.../wp-.*' and '.../*.php'.
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;

location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
# This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)

include fastcgi.conf;
fastcgi_index index.php;
# fastcgi_intercept_errors on;
fastcgi_pass php;

fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 10m;

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;



Put togther Nginx + ngx_cache_purge for WordPress on Ubuntu / CentOS

Ubuntu find release name

lsb_release -a


lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.9 (wheezy)
Release: 7.9
Codename: wheezy


lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial


fail2ban new wordpress VPS setup must have

Install: apt-get install fail2ban




SSHD and wordpress

enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 3600
bantime = 7200


enabled = true
filter = wordpress
logpath = /var/log/auth.log
port = http,https
maxretry = 10
findtime = 3600
bantime = 7200

TO USE WORDPRESS fail2ban,  also need to install wordpress plug-in “WP fail2ban


enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/apache2/*access.log
# maxretry is how many GETs we can have in the findtime period before getting narky
maxretry = 400
# findtime is the time period in seconds in which we’re counting “retries” (300 seconds = 5 mins)
findtime = 60
# bantime is how long we should drop incoming GET requests for a given IP for, in this case it’s 5 minutes
bantime = 72000
action = iptables[name=HTTP, port=http, protocol=tcp]


# Fail2Ban configuration file


# Option: failregex
# Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match.
# You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives.

failregex = ^<HOST> -.*”(GET|POST).*

# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
ignoreregex = (jpg|png) HTTP