While there are many ways to harden the security on your NginX server with peripheral applications like  Google PAM, OSSEC, Fail2Ban and SNORT, the best place to start is probably the default security policies that are implemented natively in NginX and on your Linux Distro. In this instance, we’ll be bolstering the security on NginX only.

    To keep things clean and easily readable, I like to create separate .conf files my own best practice for security policies. So in this example we’ll create the policies using this logic.

    First we’ll write a new file via Nano Editor and call it sec.conf. We’ll place this file in the NginX native folder located at /etc/nginx/common:

    sudo nano /etc/nginx/common/sec.conf

    Inside this file we’re going to add 8 security policies to guard and protect against some of the most common threats. You’ll note that I use return 404 for all of them. This is because rendering specific error codes actually provides better insight to hackers than you probably want them to have. You’ll need to copy and paste each one so that the end result looks like figure #9:

    1
    Protect Against SQL Injection

    ##
    # Protect against SQL injection
    ##
    location ~* "(eval()" { deny all; }
    location ~* "(127.0.0.1)" { deny all; }
    location ~* "([a-z0-9]{2000})" { deny all; }
    location ~* "(javascript:)(.*)(;)" { deny all; }
    location ~* "(base64_encode)(.*)(()" { deny all; }
    location ~* "(GLOBALS|REQUEST)(=|[|%)" { deny all; }
    location ~* "(<|%3C).*script.*(>|%3)" { deny all; }
    location ~ "(|...|../|~|`|<|>||)" { deny all; }
    location ~* "(boot.ini|etc/passwd|self/environ)" { deny all; }
    location ~* "(thumbs?(_editor|open)?|tim(thumb)?).php" { deny all; }
    location ~* "('|")(.*)(drop|insert|md5|select|union)" { deny all; }
    location ~* "(https?|ftp|php):/" { deny all; }
    location ~* "(='|=%27|/'/?)." { deny all; }
    location ~ "({0}|(/(|...|+++|"")" { deny all; }
    location ~ "(~|`|<|>|:|;|%||s|{|}|[|]||)" { deny all; }
    location ~* "/(=|$&|_mm|(wp-)?config.|cgi-|etc/passwd|muieblack)" { deny all; }
    location ~* "(&pws=0|_vti_|(null)|{$itemURL}|echo(.*)kae|etc/passwd|eval(|self/environ)" { deny all; }
    location ~* ".(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" { deny all; }
    location ~* "/(^$|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell).php" { deny all; }

    2
    Block SQL Injection Attempts

    ##
    # Block SQL injections
    ##
    set $block_sql_injections 0; if ($query_string ~ "union.*select.*(") { set $block_sql_injections 1; }
    if ($query_string ~ "union.*all.*select.*") { set $block_sql_injections 1; }
    if ($query_string ~ "concat.*(") { set $block_sql_injections 1; }
    if ($block_sql_injections = 1) { return 404; }

    3
    Block File Injections

    ##
    # Block File injections
    ##
    set $block_file_injections 0;
    if ($query_string ~ "[a-zA-Z0-9_]=http://") { set $block_file_injections 1; }
    if ($query_string ~ "[a-zA-Z0-9_]=(..//?)+") { set $block_file_injections 1; }
    if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { set $block_file_injections 1; }
    if ($block_file_injections = 1) { return 404; }

    4
    Block Common Exploits

    ##
    # Block common exploits
    ##
    set $block_common_exploits 0;
    if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { set $block_common_exploits 1; }
    if ($query_string ~ "GLOBALS(=|[|%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }
    if ($query_string ~ "_REQUEST(=|[|%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }
    if ($query_string ~ "proc/self/environ") { set $block_common_exploits 1; }
    if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|%3D)") { set $block_common_exploits 1; }
    if ($query_string ~ "base64_(en|de)code(.*)") { set $block_common_exploits 1; }
    if ($block_common_exploits = 1) { return 404; }

    5
    Block SPAM

    ##
    # Block SPAM
    ##
    set $block_spam 0;
    if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { set $block_spam 1; }
    if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") { set $block_spam 1; }
    if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { set $block_spam 1; }
    if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { set $block_spam 1; }
    if ($block_spam = 1) { return 404; }

    6
    Block User Agents

    ##
    # Block user agents
    ##
    set $block_user_agents 0;
    # Don't disable wget if you need it to run cron jobs!
    #if ($http_user_agent ~ "Wget") { set $block_user_agents 1; }
    # Disable Akeeba Remote Control 2.5 and earlier
    if ($http_user_agent ~ "Indy Library") { set $block_user_agents 1; }

    7
    Protect Against Bandwidth Hogs and Hacking Tools

    ##
    # Protect against common bandwidth hoggers and hacking tools.
    ##
    if ($http_user_agent ~ "libwww-perl") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GetRight") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GetWeb!") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Go!Zilla") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Download Demon") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Go-Ahead-Got-It") { set $block_user_agents 1; }
    if ($http_user_agent ~ "TurnitinBot") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GrabNet") { set $block_user_agents 1; }
    if ($block_user_agents = 1) { return 404; }

    8
    Protect Against IP Spoofing

    Important: Here, you'll need to edit 159.203.14.3 and 127.0.0.1, replacing them with the actual public and internal server IPs:

    ##
    #Protect against IP spoofing
    ##
    if ($host !~* ^(.*ayrne.com|d+.d+.d+.d+)$ ) { return 404; }
    server_name 159.203.14.3; # Public IP
    server_name 127.0.0.1; # Private IP

    9
    Your Complete Sec.conf Should Look Like This

    ##
    # Protect against SQL injection
    ##
    location ~* "(eval()"  { deny all; }
    location ~* "(127.0.0.1)"  { deny all; }
    location ~* "([a-z0-9]{2000})"  { deny all; }
    location ~* "(javascript:)(.*)(;)"  { deny all; }
    location ~* "(base64_encode)(.*)(()"  { deny all; }
    location ~* "(GLOBALS|REQUEST)(=|[|%)"  { deny all; }
    location ~* "(<|%3C).*script.*(>|%3)" { deny all; }
    location ~ "(|...|../|~|`|<|>||)" { deny all; }
    location ~* "(boot.ini|etc/passwd|self/environ)" { deny all; }
    location ~* "(thumbs?(_editor|open)?|tim(thumb)?).php" { deny all; }
    location ~* "('|")(.*)(drop|insert|md5|select|union)" { deny all; }
    location ~* "(https?|ftp|php):/" { deny all; }
    location ~* "(='|=%27|/'/?)." { deny all; }
    location ~ "({0}|(/(|...|+++|"")" { deny all; }
    location ~ "(~|`|<|>|:|;|%||s|{|}|[|]||)" { deny all; }
    location ~* "/(=|$&|_mm|(wp-)?config.|cgi-|etc/passwd|muieblack)" { deny all; }
    location ~* "(&pws=0|_vti_|(null)|{$itemURL}|echo(.*)kae|etc/passwd|eval(|self/environ)" { deny all; }
    location ~* ".(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" { deny all; }
    location ~* "/(^$|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell).php" { deny all; }
    ##
    # Block SQL injections
    ##
    set $block_sql_injections 0; if ($query_string ~ "union.*select.*(") { set $block_sql_injections 1; }
    if ($query_string ~ "union.*all.*select.*") { set $block_sql_injections 1; }
    if ($query_string ~ "concat.*(") { set $block_sql_injections 1; }
    if ($block_sql_injections = 1) { return 404; }
    ##
    # Block File injections
    ##
    set $block_file_injections 0;
    if ($query_string ~ "[a-zA-Z0-9_]=http://") { set $block_file_injections 1; }
    if ($query_string ~ "[a-zA-Z0-9_]=(..//?)+") { set $block_file_injections 1; }
    if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { set $block_file_injections 1; }
    if ($block_file_injections = 1) { return 404; }
    ##
    # Block common exploits
    ##
    set $block_common_exploits 0;
    if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { set $block_common_exploits 1; }
    if ($query_string ~ "GLOBALS(=|[|%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }
    if ($query_string ~ "_REQUEST(=|[|%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }
    if ($query_string ~ "proc/self/environ") { set $block_common_exploits 1; }
    if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|%3D)") { set $block_common_exploits 1; }
    if ($query_string ~ "base64_(en|de)code(.*)") { set $block_common_exploits 1; }
    if ($block_common_exploits = 1) { return 404; }
    ##
    # Block SPAM
    ##
    set $block_spam 0;
    if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { set $block_spam 1; }
    if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") { set $block_spam 1; }
    if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { set $block_spam 1; }
    if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { set $block_spam 1; }
    if ($block_spam = 1) { return 404; }
    ##
    # Block user agents
    ##
    set $block_user_agents 0;
    # Don't disable wget if you need it to run cron jobs!
    #if ($http_user_agent ~ "Wget") { set $block_user_agents 1; }
    # Disable Akeeba Remote Control 2.5 and earlier
    if ($http_user_agent ~ "Indy Library") { set $block_user_agents 1; }
    ##
    # Common bandwidth hoggers and hacking tools.
    ##
    if ($http_user_agent ~ "libwww-perl") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GetRight") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GetWeb!") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Go!Zilla") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Download Demon") { set $block_user_agents 1; }
    if ($http_user_agent ~ "Go-Ahead-Got-It") { set $block_user_agents 1; }
    if ($http_user_agent ~ "TurnitinBot") { set $block_user_agents 1; }
    if ($http_user_agent ~ "GrabNet") { set $block_user_agents 1; }
    if ($block_user_agents = 1) { return 404; }
    ##
    #Protect against IP spoofing
    ##
    if ($host !~* ^(.*ayrne.com|d+.d+.d+.d+)$ ) { return 404; }
    server_name 159.203.14.3; # Public IP
    server_name 127.0.0.1; # Private IP

    10
    Save The Sec.conf File

    Assuming your complete file looks like the one above, go ahead and close out the file and save it.

    11
    Make the New Security Policies Active

    To make your new security policies active you'll need to call the file from your default NginX configuration by adding the following line to include it:

    include common/sec.conf;

    You'll also need to restart NginX for the new policies to go into effect, but before doing that, let's verify the integrity of the entries we've made:

    nginx -t

    If all is well, you'll get a confirmation that looks like this:

    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    root@nginxisawesome:~#
    

    Now restart NginX so that the policies become active:

    service nginx restart
    

    That's it - you're done!

    Tags:

    • Show Comments (0)

    Your email address will not be published. Required fields are marked *

    comment *

    • name *

    • email *

    • website *

    Ads

    You May Also Like

    How to Resolve Multiple Domains to a Single WordPress Instance with EasyEngine

    I’ve been working more with WordPress lately, rather than my usual Drupal development, and ...

    How to Install Redis Server on Ubuntu 16.04 with WordPress

    The quick easy and totally correct way to setup Redis object cache to work ...

    How to Bulk Optimize JPG and PNG Images on Ubuntu

    While there are lots of Wordpress plugins that compress image files, they're mostly paid, ...