WordPress.org

Ready to get started?Download WordPress

Forums

iThemes Security (formerly Better WP Security)
FIX for Plesk 11.5 (Ubuntu) and NGINX (5 posts)

  1. Tim Reeves
    Member
    Posted 2 months ago #

    iTS recognises if you are using nginx and writes a nginx.conf to the document root directory. Unfortunately, one or two of the rules are poorly formulated and the most important ones don't work because they set a "location" for .php files - but the Plesk config has already set a location rule for ALL .php files, thus pre-empting the attempts of iTS.

    This is how you can fix things in Plesk: Go to <domain> | Web Server Settings and in the section "nginx settings" make sure that the first and last checkboxes are checked, but the middle one "Serve static files directly by nginx" must be UNchecked. Then add this block of directives into the box "Additional nginx directives":

    if (!-e $request_filename) { rewrite ^(.*)$ /index.php break; }
    
    location = /nginx.conf { deny all; }
    
    include "/var/www/vhosts/<domain path>/nginx.conf";
    
    # Begin until corrected in iTS
    
    rewrite /wp-config.php /forbidden last;
    rewrite /install.php /forbidden last;
    rewrite ^/wp-includes/(.*).php /forbidden last;
    rewrite ^/wp-admin/includes(.*)$ /forbidden last;
    # Prevent php execution in uploads
    rewrite ^(.*)/uploads/(.*).php(.?) /forbidden last;
    location = /forbidden { deny all; }
    
    # End until corrected in iTS
    
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
     expires 30d;
     add_header Pragma public;
     add_header Cache-Control “public”;
     try_files $uri @fallback;
    }
    
    location ~* \.(ac3|avi|bmp|bz2|cue|dat|doc|docx|dts|exe|flv|gz|htm|html|img|iso|mkv|mp3|mp4|mpeg|mpg|ogg|pdf|ppt|pptx|qt|rar|rm|swf|tar|tgz|txt|wav|xls|xlsx|zip)$ {
     try_files $uri @fallback;
    }
    
    gzip on;
    gzip_proxied any;
    gzip_types text/plain text/xml text/css application/x-javascript;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    NOTE You must edit YOUR path into the include statement near the start of the above directives!

    For those wanting to know more...

    Nginx location directive
    location {modifier | empty} { prefix string | regex }
    prefix string: Matches the start of the URI; regex: Is a regex :)
    prefix string locations are tested first, longest match wins
    If modifier is one of = or ^~ then no regex-testing is performed if any prefix string match was found;
    Otherwise the search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
    Modifiers:
    = Exact match of „prefix“ string and location (full uri)
    ^~ (NOT regex) If this prefix string matches don't do any regex testing
    ~ regex case-sensitive
    ~* regex case-insensitive

    Plesk rule for php files: location ~ \.php(/.*)?$
    Matches .php with optionally any string tacked on after a slash, e.g. .php/abc
    The following rule in the { } brackets sets up fastcgi processing!

    location ~ ^wp-includes/(.*).php { deny all; } FAILS – executed (bad rule)
    Correct: location ~ ^/wp-includes/(.*).php FAILS TOO, but we need a regex...
    But same problem with ALL „locations“ matching to .php – Plesk got there first!
    Problem: Regex needed to match all .php but ONLY .php – so this regex would need to come before the one from Plesk for executing .php files.
    BUT if you switch off „Process PHP by nginx“ in the Plesk settings, then a LOT gets removed from the Plesk nginx config – 4 „locations“ each in 4 sections, including the domain-dependent path to php-fpm.sock. So one could copy paste all those directives into the „Additional nginx directives“ box – but is there a better way?
    YES there is a better way: rewrite the undesired URI to a dummy location and catch that, as I have shown in the code above.

    @Chris: Could you update the way iTS creates its nginx.conf to incorporate these insights? Ta!

    https://wordpress.org/plugins/better-wp-security/

  2. iThemes Support
    Member
    Plugin Author

    Posted 2 months ago #

    Hey Tim,

    Thanks for sharing! I've informed Chris of this thread.

    Thanks,

    Gerroald

  3. Chris Wiegman
    Member
    Plugin Author

    Posted 2 months ago #

    Hi Tim,

    I'm willing to update. Not being a plesk user myself I can see where having plesk set a location for all php could cause issue. Can you contact me directly (Same username on Twitter and nearly every other network) and I'll get you a version to test?

  4. Tim Reeves
    Member
    Posted 2 months ago #

    Hi Chris,

    I can certainly try out a test version for you, as I noted the robust way in general seems to be to use a rewrite rather than a location, a rewrite leading to a deny all.

    I don't use any social networks but my contact details are on my (old) website (I'm just busy creating a new one - in WordPress).

    Cheers!

  5. Tim Reeves
    Member
    Posted 2 months ago #

    Here is an improved version of the Nginx directives for the Plesk box "Additional nginx directives" - I noticed that you must have location directives for ALL the static resource types used by your site. Otherwise the "rewrite" for Permalinks (first statement below) takes precedence and the resource is "not found". Also I beefed up the gzipping. Hope this helps!

    if (!-e $request_filename) { rewrite ^(.*)$ /index.php break; }
    
    # try_files in locations is required to pre-empt the above rewrite
    
    # Security directives of iThemes Security
    include "/var/www/vhosts/<domain path>/nginx.conf";
    
    # Begin until corrected in iTS
    rewrite /wp-config.php /forbidden last;
    rewrite /install.php /forbidden last;
    rewrite ^/wp-includes/(.*).php /forbidden last;
    rewrite ^/wp-admin/includes(.*)$ /forbidden last;
    rewrite ^(.*)/uploads/(.*).php(.?) /forbidden last;
    location = /forbidden { deny all; }
    # End until corrected in iTS
    
    # Now the generic stuff which is good for all PHP sites
    
    location = /nginx.conf { deny all; }
    
    location ~* \.(txt)$ { charset utf-8; }
    
    # Pics and Fonts valid 90 Days in Cache
    location ~* \.(png|jpg|jpeg|gif|ico|bmp|img|ttf|otf|eot|svg|woff)$ {
     expires 90d;
     add_header Pragma public;
     add_header Cache-Control public;
     try_files $uri @fallback;
    }
    
    # Zips + PDF valid 2 weeks in Cache
    location ~* \.(bz2|exe|gz|pdf|rar||tgz|zip)$ {
     expires 2w;
     add_header Pragma public;
     add_header Cache-Control public;
     try_files $uri @fallback;
    }
    
    # Media files (large) valid 1 week in Cache
    location ~* \.(ac3|avi|flv|iso|mp3|mp4|mpeg|mpg|ogg|qt|rm|swf|wav)$ {
     expires 1w;
     add_header Pragma public;
     add_header Cache-Control public;
     try_files $uri @fallback;
    }
    
    # Possibly modified content valid 1 week in Cache
    location ~* \.(js|css|htm|html|xhtml|xml|dat|doc|docx|dts|ppt|pptx|tar|txt|xls|xlsx)$ {
     expires 1w;
     add_header Pragma public;
     add_header Cache-Control public;
     try_files $uri @fallback;
    }
    
    # Switch gzipping on
    gzip on;
    gzip_proxied any;
    gzip_min_length 100;
    gzip_buffers 8 16k;	# number size, default 32 4k|16 8k
    gzip_types text/css text/plain text/javascript application/javascript application/json application/x-javascript application/xml application/xml+rss application/xhtml+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject image/svg+xml image/x-icon application/rss+xml application/atom_xml;
    gzip_vary on;
    gzip_comp_level 9;
    gzip_http_version 1.0;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

Reply

You must log in to post.

About this Plugin

About this Topic