########################
ModSecurity Rules Guide
########################


Installing ModSecurity Rules
=============================

For installation instructions for ModSecurity, please see this `article`_

.. _article: ../../gotrootModsec/asl.html


-------------

Disabling Global Rules
======================

**Phase:1 Rules:**

   .. note:: Atomic Protector users should disable rules from the rule manager. There is no need to create custom rules, apache configuration files or other customizations when using Atomic Protector, and Atomic Protector supports disabling any rule on both a global and per domain basis.
   
   * For non-Atomic Protector users, LocationMatch and Location do not work for phase:1 rules. Location and LocationMatch are not available in apache until phase:2. If you need to disable a phase:1 rule, use Atomic Protector which can disable phase:1 rules on a per domain and global basis.

   * If you are not using Atomic Protector, and need to disable a phase:1 rule, you will need to create a custom rule to do this. This following is an example of a custom rule to do this for rule 123456.

      .. code-block:: console
	  
         SecRule REQUEST_HEADERS:Host "example.com$" "phase:1,id:91001,t:none,t:lowercase,pass,nolog,noauditlog,ctl:ruleRemovebyID=123456"

      In the example above, "example.com" is the domain to exclude this rule. This custom rule must be loaded before the rule you want to disable.

   * If you do not know how to create this kind of custom rule, please contact support and we'll put a quote together to help develop these custom rules for you.

   

**Disabling Mod_Security Globally**
   
   * If you are using Atomic Protector, just change this setting: **MODSEC_ENABLED**
	  
   * If you are not using Atomic Protector, you will need to do this manually. Please follow the steps below:
	  
      Step 1: Disable the config file by running the following command:

         .. code-block:: console

            mv /etc/httpd/conf.d/00_mod_security.conf /etc/httpd/conf.d/00_mod_security.conf.disabled

			   
      Step 2: Restart Apache by running the following command:
		 
         .. code-block:: console
			
            service httpd restart
			   			   
			   
**Disable Mod_Security on a global URL**
   
   Step 1: Create a global exclude file by running the following command:
	  
      .. code-block:: console
		 
         vim /etc/httpd/modsecurity.d/00_custom_exclude.conf

			
   Step 2: Add the LocationMatch for the URL to the exclude file. Example: /server.php
	  
      .. code-block:: console
		 
         <LocationMatch /server.php>
          <IfModule mod_security2.c>
           SecRuleEngine Off 
          </IfModule>
         </LocationMatch>
			
			
   Step 3: Restart Apache by running the following command:
	  
      .. code-block:: console
		 
         service httpd restart
			
			

**Set a URL to Alert Only**
   
   Step 1: Create a global exclude file by running the following command:
	  
      .. code-block:: console
		 
         vim /etc/httpd/modsecurity.d/00000_custom_exclude.conf

			
   Step 2: Add a custom rule to the global exclude file you created in step 1. 
	  
      In this example the URL is: **/foo/bar**
		 
         .. code-block:: console
			
            SecRule REQUEST_URI "/foo/bar" "phase:1,id:1000000,t:none,t:lowercase,pass,nolog,noauditlog,ctl:ruleEngine=DetectionOnly"

     
   Step 3: Restart Apache by running the following command:
	  
      .. code-block:: console
		 
         service httpd restart
			
-----------

Disabling Rules Per Domain
==========================

**Disabling Mod_Security Per Domain**

   **For Plesk Based Systems:**
   
      For Plesk and similar systems you cn also disabled ModSecurity in the Apache configuration.
	  
      Step 1: Edit the /vhost/vhost_ssl.conf for the domain by running the following command:
	  
         .. code-block:: console
		 
            vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf
			
			
      Step 2: Add the following lines to **/vhost/vhost_ssl.conf**:
	  
         .. code-block:: console
		 
            <IfModule mod_security2.c>
              SecRuleEngine Off
            </IfModule>  

 
      Step 3: Restart Apache by running the following command:

         .. code-block:: console

            service httpd restart 


      .. note:: If you are using Plesk then you must proceed to step 3


      Step 3: Add vhost.conf to the domain config by running the following command:

         **Plesk 9**:
		 
            .. code-block:: console
			
               /usr/local/psa/admin/bin/websrvmng -a
			   
			   
         **Plesk 10/11**:
		 
            .. code-block:: console
			
               /usr/local/psa/admin/bin/httpdmng --reconfigure-domain <domain_name>

			   
      Step 4: Restart Apache by running the following command:

         .. code-block:: console

            service httpd restart


   **For CPanel based systems with EasyApache 4:**
   
      For full information about include file path expectations, see the official `CPanel`_ documentation.
	  
      .. _CPanel: https://documentation.cpanel.net/display/EA4/Modify+Apache+Virtual+Hosts+with+Include+Files
	  
	  
      Step 1: Create the following paths by running the following commands, replacing <user> and <domain> with the correct values for your needs:
	  
         .. code-block:: console
		 
            mkdir -p /etc/apache2/conf.d/userdata/ssl/2_4/<user>/<domain>
            mkdir -p /etc/apache2/conf.d/userdata/std/2_4/<user>/<domain>
			
			
      Step 2: Create a file called *vhost.conf* in each of the paths above by navigating to the directory and running the following command:
	  
         .. code-block:: console

            touch vhost.conf	
	  
	  
      Step 3: Add in the lines below to **vhost.conf**:
	  
         .. code-block:: console
		 
            <IfModule mod_security2.c>
              SecRuleEngine Off
            </IfModule>

			
      Step 4: After any addition, modification, or remove of userdata file, CPanel requires both of the following scripts to be run:
	  
         .. code-block:: console
		 
            /usr/local/cpanel/scripts/rebuildhttpdconf
            /usr/local/cpanel/scripts/restartsrv_httpd
			
			
   **For CPanel based systems with EasyApache 3:**
   
      Step 1: Create the custom ModSecurity configuration directory for the domain by running the following command:
	  
         For Example, if the domain is example.com, you would need to create this directory:

            .. code-block:: console

               mkdir /usr/local/apache/conf/userdata/std/2/username/example.com


      Step 2: Create the file **vhost.conf** in this directory by running the following commands:

         .. code-block:: console

            cd /usr/local/apache/conf/userdata/std/2/username/example.com
            touch vhost.conf


      Step 3: Add in the following lines to **vhost.conf**: 

         .. code-block:: console

            <IfModule mod_security2.c>
              SecRuleEngine Off
            </IfModule>	


      Step 4: Run the vhost includes script, for example if the domains username is 'example':

         .. code-block:: console

            /scripts/ensure_vhost_includes --user=example

-------------

Disabling ModSecurity Per Domain for an IP Address
==================================================		 

   **For Plesk based systems**
   
      Step 1: Edit the **vhost/vhost_ssl.conf** for the domain by running the following command:
	  
         .. code-block:: console
		 
            vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf

			
      Step 2: Add the following lines the file opened in step 1: 
	  
         .. code-block:: console
		 
            <IfModule mod_security2.c>
              SecRule REMOTE_ADDR "^1.2.3.4$" "phase:1,t:none,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off,id:9999"
            </IfModule>   


      .. note:: You must change id: to a number that you have not used for any other custom rules. Customer generated rules should use the range 1-99999. Numbers about 99999 are reserved and will cause conflicts and are not supported.


      .. note:: If you are on a Plesk based system, you must proceed to step 4.
	  
	  
      Step 3: Restart Apache by running the following command:

         .. code-block:: console

            service http restart


      Step 4: Add **vhost.conf** to domain config by running the following command:

         **Plesk 9:**

            .. code-block:: console

               /usr/local/psa/admin/bin/websrvmng -a


         **Plesk 10/11:**

            .. code-block:: console

               	/usr/local/psa/admin/bin/httpdmng --reconfigure-domain <domain_name>
				
				
      Step 5: Restart Apache by running the following command:
	  
         .. code:: console
		 
            service httpd restart
			
			
			
   **For CPanel based systems**
   
      Step 1: Create the custom ModSecurity configuration directory for the domain by running the following command:
	  
         For Example: If the domain is example.com, you would need to run the following command:
		 
            .. code-block:: console
			
               mkdir /usr/local/apache/conf/userdata/std/2/username/example.com


      Step 2: Create the file *vhost.conf* in this directory by running the following commands:
	  
         .. code-block:: console
		 
            cd /usr/local/apache/conf/userdata/std/2/username/example.com
            touch vhost.conf
			
			
      Step 3: Add the following lines to **vhost.conf**:
	  
          .. code-block:: console
		  
             <IfModule mod_security2.c>
              SecRule REMOTE_ADDR "^1.2.3.4$" "phase:1,t:none,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off,id:9999"
             </IfModule>
			 
			 
         .. note:: You must change id: to a number that you have not used for any other custom rules. Customer generated rules should use the range 1-99999. Numbers about 99999 are reserved and will cause conflicts and are not supported.
		 
		 
      Step 4: Run the vhost includes script, for example if the domains username is "example":
	  
         .. code-block:: console
		 
            /scripts/ensure_vhost_includes –user=example

---------------

Disable a Rule for a Single Domain
==================================

**If you have Atomic Protector installed**

   **Method 1:**
   
      Step 1: Log into the Atomic Protector GUI, and click on the "Atomic Protector" tab. Then click "WAF & HIDS Rules", then click the "Rules" tab, then click the "WAF" tab. Type in the rule ID and the rule manager will pull up the rule. Click on the green down error which will pull up the options for this rule.
	  
      Step 2: Type in the hostname into the Text box on the left side of the options you want to exclude the rule for, then click "add".

      .. note:: Keep in mind this is literal, so if you have a vhost with the name "example.com" that serves content for "ftp.example.com" and "www.example.com" you will need to add those FQDNs as well, or a regular expression .example.com. You can use regular expressions in this field, but each end of the expression is anchored.
	  
	  
   **Method 2:**
   
      Step 1: Run the following command as root:

         .. code-block:: console

            asl -drv RULE_ID[,RULE_ID...] VHOST[,VHOST...]
			
            For Example:  asl -drv 111111,222222,333333 www.example.com,ftp.example.com,example.com

			
			
**If you do not have Atomic Protector installed**

   Step 1: Edit your domains in **vhost.conf** (the location of this file will vary across systems) by running the following command:
   
      .. code-block:: console
	  
         vim vhost.conf
		 
		 
   Step 2: Add the LocationMatch for the file to exclude (Example: ruleid 950005) by adding the following lines to **vhost.conf**
   
      .. code-block:: console
	  
         <LocationMatch .*>
           <IfModule mod_security2.c>
            SecRuleRemoveById 950005
           </IfModule>
         </LocationMatch>      
		 
		 
   Step 3: If you want to disable multiple rules, add LocationMatch for the rule to exclude (Example: 950005 and 950006)
   
      .. code-block:: console
	  
         <LocationMatch .*>
          <IfModule mod_security2.c>
           SecRuleRemoveById 950005
           SecRuleRemoveById 950006
          </IfModule>
         </LocationMatch>   


------------

Disable a Rule for All Domains
==============================

There are three methods to disable a rule for across all domains, both are described below:

   **Method 1:**		 

      Step 1: Log into the Atomic Protector GUI, and click on the "Configuration" tab. Then click "Rule Management", then click the "Rules" tab, then click the "WAF" tab. Type in the rule ID and the rule manager will pull up the rule. Click on the green down error which will pull up the options for this rule.   
	  
      Step 2: Set "disabled" to yes and click update. 
	  
	  
   **Method 2 (If Atomic Protector is installed):**
   
      Step 1: Use Atomic Protector utility to disable rule by ID, by running the following command Example: 950005
	  
         .. code-block:: console
		 
            asl --disable-rule 950005

			
   **Method 3 (If Atomic Protector is NOT installed):**
   
      Step 1: You can disabled a rule globally by manually adding a rule to your own custom rules file by adding the following lines to that file (Example: ruleid 34000)
	  
         .. code-block:: console
		 
            <LocationMatch .*>
             <IfModule mod_security2.c>
              SecRuleRemoveById 340000
             </IfModule>
            </LocationMatch>   

			
.. note:: Custom rules should be loaded after atomicorp rules. A good place to add this, again only if you do not have Atomic Protector installed, is in the 999_user_exclude.conf file. If you don't have this file, just create it. Then make sure your modsecurity configuration is setup to load this file.


--------------

Disabling Rules Per IP or Network
=================================

**Disable ModSecurity Rule for an IP Address**

   **If you have Atomic Protector installed**
   
      Step 1: In the Atomic Protector Web Console, just click the 'Whitelist' button.

   .. note:: For this rule to work, in Atomic Protector you must have the MODSEC_00_WHITELIST ruleset enabled.
	  
	  
   **If you do not have Atomic Protector installed**
   
      Step 1: Add your IP Address to the file **/etc/asl/whitelist**
	  
      Step 2: Restart Apache by running the following command:
	  
         .. code-block:: console
		 
            service httpd restart
			
   .. note:: If you are not using Atomic Protector, then you must have the 00_asl_whitelist.conf ruleset loaded.


**Disabling ModSecurity Rule for a Network**

   Step 1: You will need to create a custom rule, loaded after all your other rules. Lets say you wanted to exclude rule id 330039 for the network 1.2.0.0/16. You would construct a custom rule like this:

      .. code-block:: console
   
         SecRule REMOTE_HOST "@ipmatch 1.2.0.0/16" \
         "id:12345,phase:2,t:none,pass,nolog,noauditlog,ctl:ruleRemovebyID=330039" 

      .. note:: pmatch can also use a list, with a combination of IPs and network for example:

         .. code-block:: console

            @ipmatch 1.2.0.0/16,5.6.7.8,127.0.0.0/8


.. note::  If the CIDR is invalid, this may cause a segfault of the mod_security module. Check to make sure your CIDR is valid before use.


------------

Disabling ModSecurity Rules Per Application
============================================	 

**Disabling ModSecurity for a Specific Web Application**

   .. note:: This is **NOT** recommended.**
   
   Step 1: Add a custom rule (see the section below on creating custom rules) after all your rules have been loaded. For example, if you wanted to disable modsecurity for the application /foo/bar.cgi you would add a custom rule like this:
   
      .. code-block:: console
	  
          <LocationMatch /foo/bar.cgi>
           SecRuleEngine Off
          </LocationMatch>
		  
		  
**Disabling a ModSecurity Rule for a Specific Web Application**

   Step 1: Add a custom rule (see the section below on creating custom rules) after all your rules have been loaded. For example, if you wanted to disable rule 950005, you would add a custom rule like this:

      .. code-block:: console
	  
          <LocationMatch /URL/path/to/application.php>
           SecRuleRemoveById 950005
          </LocationMatch>
		  
		  
**Disable a ModSecurity Rule for a Specific Application in a Single Domain**

   Step 1: Edit the virtual servers configuration for the domain for the domain. For Example:
   
      .. code-block:: console
	  
         vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf

		 
   Step 2: Add the LocationMatch for the rule to exclude by adding the following to the file in step 1. Example, ruleid 950005
   
      .. code-block:: console
	  
         <LocationMatch /URL/path/to/application.php>
          SecRuleRemoveById 950005
         </IfModule>
		 
   .. note:: LocationMatch variable must match the URL, not the path on the system.
   
   
**Disabling ModSecurity Rules by domain, for a Specific Application for a List of IPs**

   Step 1: Edit the **vhost/vhost_ssl.conf** for the domain
   
      .. code-block:: console
	  
         vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf
		 
		 
   Step 2: Add the LocationMatch for the rule to exclude by adding the following to the file above
   
      .. code-block:: console
	  
         <LocationMatch /foo/bar.php>
          <IfModule mod_security2.c>
           SecRule REMOTE_ADDR "@pmFromFile /etc/asl/whitelist" "nolog,phase:1,allow"
          </IfModule>
         </LocationMatch> 
		 
		 
   Step 3: Add IPs to **/etc/asl/whitelist** by running the following command for each IP to whitelist
   
       .. code-block:: console
	   
          echo "10.11.12.13" >> /etc/asl/whitelist
		  
		  
   .. note:: The following is an alaternative set of steps if you want to whitelist an IP for that specific application.
   
   
   Step 1: Edit the **vhost/vhost_ssl.conf** for the domain
   
      .. code-block:: console
	  
         vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf

		 
   Step 2: Add the LocationMatch for the rule to exclude by adding the following to the file above
   
      .. code-block:: console
	  
         <LocationMatch /foo/bar.php>
          <IfModule mod_security2.c>
           SecRule REMOTE_ADDR "@pmFromFile /path/to/your/custom/whitelist_for_this_application" "nolog,phase:1,allow,id:9999"
          </IfModule>
         </LocationMatch>
		 
		 
   .. note:: You must change id: to a number that you have not used for any other custom rules. Customer generated rules should use the range 1-99999. Numbers about 99999 are reserved and will cause conflicts and are not supported.
   
   
   Step 3: Create your custom whitelist and add IPs to **/etc/asl/whitelist**
   
      .. code-block:: console
	  
         echo "10.11.12.13" >> /path/to/your/custom/whitelist_for_this_application

   .. note:: Keep in mind these custom lists are *not* managed by Atomic Protector, so if you want to add IPs to these lists you will need to do it from the command line.


   
**Disable a ModSecurity Rule for a Specific Argument for a Specific Application**

You can also tell modsecurity to change a rule, in some cases, without editing or forking the rule. For example, if you want to configure modsecurity to ignore a specific argument (in the argument below the argument is "foo"), for a specific application (in the example the application name is /example/application), for a specific rule (in the example below the rule if is 12345), you would create a custom rule like this:

   .. code-block:: console
   
      SecRule REQUEST_URI "^/example/application" \
      "id:9999,phase:1,t:none,t:lowercase,nolog,pass,ctl:ruleRemoveTargetByID=12345;ARGS:foo"
	  
As with all custom rules, this rule also needs a unique id as explained in the article above. And this type of custom rule must be loaded before the rule it modifies.

.. note:: This does not support regular expressions for the excluded argument. At this time, they must be explicitly defined.


**Disable ModSecurity Rule for a Specific Argument**

As is the example above, a rule can also be changed to exclude a specific argument, but for all applications. For example, if you want to configure modsecurity to ignore a specific argument (in the argument below the argument is "foo"), for a specific rule (in the example below the rule if is 12345), you would create a custom rule like this:

   .. code-block:: console
   
      SecAction "phase:1,id:9999,t:none,auditlog,nolog,pass,ctl:ruleRemoveTargetById=12345;ARGS:foo"

As with all custom rules, this rule also needs a unique id as explained in the article above. And this type of custom rule must be loaded before the rule it modifies.

.. note:: This does not support regular expressions for the excluded argument. At this time, they must be explicitly defined. 


----------

Changing the Action of a Rule
=============================

You can also change the default action for a rule by using the SecRuleActionById directive.

**Changing a Rule to Detect only by ID**

   * To change a rule to only detect, but not block attacks, simply change the action for the rule with the above directive. For example, to change the action for rule 12345, simply add this rule directive to your custom rules.
   
      .. code-block:: console
	  
         SecRuleUpdateActionById 12345 "pass,status:200"


   .. note:: This directive must be added after the rule it is modifying has been loaded. This does not work if you are using the redirect action.
   
   
   
**Change a Range of Rules to be Detected only by an ID**

   * This is similar to the method above, however you can define a range of rule IDs. For example, if you want to disable rules 1000-2000:

      .. code-block:: console
	  
         SecRuleUpdateActionById 1000-2000 "pass,status:200"


   .. note:: This directive must be added after the rule it is modifying has been loaded. This does not work if you are using the redirect action.
   
   
----------

Disabling POST Inspection for a Specific URL
============================================

   * Should you want to disable inspection of a POST for a specific URL, use the format below: 
   
      .. code-block:: console
	  
         For Example: You want to skip POST insepction was "upload", your exclusion would look like the following:
		 
           SecRule REQUEST_URI "^/upload" \
           "phase:1,id:1234567,t:none,t:lowercase,pass,nolog,ctl:requestBodyAccess=off"

		   
   .. note:: Install this rule before any of your other rules. For example, in the file /etc/httpd/modsecurity.d/00_custom_exclude.conf.


----------

Enabling Rules for only Specific Domains
========================================

   * If you wish to disable all the rules, except for specific domains, you need to copy in the two files from the subdirectory "special" where you have the rules installed. Then create this file:

      .. code-block:: console
	  
         /etc/asl/custom_include_domains
		 
		 
   * Include the domains and/or FQDNs you want the rules to apply to. Anything not on that list will cause those rules to skip all of our rules.

      1. File must contain exactly one domain or FQDN per line. End of line markers (both LF and CRLF) will be stripped from each phrase and any whitespace trimmed from both the beginning and the end. Empty lines and comment lines (those beginning with the # character) will be ignored.
	  
      2. This file does not support metacharacters. (For example, * is not supported)
	  
	  
   **For Example**: 
   
      .. code-block:: console
	  
         www.example.com
         .foo.com
		 
------------

Disabling Rules Using .htaccess
===============================

   * This is a new feature in modsecurity 2.7.3. This capability is available if you compile modsecurity using this option:

      .. code-block:: console
	  
         --enable-htaccess-config

		 
   * From there, you will be able to disable rules using .htaccess files. The format to disable a rule via .htaccess is:

      .. code-block:: console
	  
         SecRuleRemoveById 12345 , where rule id is 12345
		 

   * Specific Actions Available in .htaccess:
   
      * SecAction
	  
      * SecRule
      * SecRuleRemoveByMsg
      * SecRuleRemoveTag
      * SecRuleRemoveById
      * SecRuleUpdateActionById
      * SecRuleUpdateTargetById
      * SecRuleUpdateTargetByTag
	  
      * SecRuleUpdateTargetByMsg
	  
   .. note:: This capability is not enabled by default in modsecurity, and must be enabled specifically when modsecurity is compiled. If .htaccess directives do not work for you, then modsecurity is either not version 2.7.3 or higher and/or this option has not been enabled.
   
   
   .. note:: Enabling this capability will allow users to disable rules, including on compromised accounts which may cause the system to become compromised. This capability was specifically disabled by default in modsecurity to prevent this from occurring. Use this option with extreme caution!
   
   

-----------

Customizing a Rule
==================

   * If you need to customize a rule do not change the asl*conf files. These files will be overwritten by updates.

   * The use of "asl" in the filename is also reserved. Do not name custom file with "asl" in the filename, for example, 99_asl_custom.conf. This file may be overwritten or deleted by the rule management system. Do not create custom rules with "asl" in the filename.
   
   * If you need to change a rule because it is incorrectly blocking something we recommend you report it to use as a False Positive, using the Reporting_False_Positives procedure. If you simply want to modify a rule to perform different actions, then copy the entire rule into your own rule file, and make sure you tell mod_security not to enable the original Atomic Protector rule. You can do that by using the mod_security action SecRuleRemoveById. Here is a simple example:
   
      If you had an original rule like this:
	  
         .. code-block:: console
		 
             SecRule REQUEST_URI "/foo" "t:normalisePath,id:9000,rev:1,severity:2,msg:'Atomicorp.com WAF Rules: Block /foo'"

      And you want it to block "bar" instead of "foo", then you would copy the entire rule into your own custom rule file. If you are using our rules we recommend you use the filename 99_zzz_custom.conf and change the id: field to an unused ID. You will need to configure Apache to load this file. You should load this file after the asl conf rule files have been loaded.
	  
         .. code-block:: console
		 
            SecRuleRemoveById 9000000
            SecRule REQUEST_URI "/bar" "t:normalisePath,id:9999,rev:1,severity:2,msg:'Atomicorp.com WAF Rules: Block /foo'"
			
			
   .. note:: You must change id: to a number that you have not used for any other custom rules. Customer generated rules should use the range 1-99999. Numbers about 99999 are reserved and will cause conflicts and are not supported.
   
   
   * The following is a list of reserved ranges: 

      * 1-99,999; reserved for local (internal) use. Use as you see fit but do not use this range for rules that are distributed to others.
	  
      * 100,000-199,999; reserved for internal use of the engine, to assign to rules that do not have explicit IDs.
      * 200,000-299,999; reserved for rules published at modsecurity.org.
      * 300,000-399,999; reserved for rules published at gotroot.com.
      * 400,000-419,999; unused (available for reservation).
      * 420,000-429,999; reserved for ScallyWhack.
      * 430,000-699,999; unused (available for reservation).
      * 700,000-799,999; reserved for Ivan Ristic.
      * 900,000-999,999; reserved for the Core Rules project.
	  
      * 1,000,000 and above; unused (available for reservation).


----------

Customizing a Rule for a Domain
===============================

   **Apache**

      * If you just want to customize the rule, or add a supported configuration setting for a domain you will want to add your modifications within the VirtualHost definition for the domain.
	  
	  
   **Changing the Argument Separator**
   
      * If you have a web application that uses the uncommon ";" argument separator, as opposed to the widely used "&" you will want to change SecArgumentSeparator value for that application. You can do this in one of two ways:
	  
         1. Globally: If all your applications use the older delimiter, just change the SecArgumentSeparator in the tortix_waf.conf file. Do not change this if your applications use other delimiters.

            .. code-block:: console
			
               SecArgumentSeparator ","
			   
         2. Per Application: You can also configure this per application. For example, if your web applications URL is /foo/bar.php you can create a customer rule like this:

            .. code-block:: console
			
               <LocationMatch /foo/bar.php>
                SecArgumentSeparator ";"
               </LocationMatch>			

            This will only work if modsecurity is loaded before your virtual host definitions. This is the case with most control panels, but some control panels are known to load modsecurity after vhosts are defined. In which case this will fail because Apache will not know how to process this directive (it will need modsecurity loaded to understand what this means). If you get a syntax error, that means your apache configuration is loaded modsecurity after your vhosts are defined. You will need to change your apache configuration to ensure this loading occurs before vhosts are defined. Atomic Protector will automatically configure modsecurity to load first.


------------

Custom Rules in ModSecurity
===========================

**Discussion**

   * If you need to create your own custom rules, do not change the asl*conf files. These files will be overwritten by updates.

   * The use of "asl" in the filename is also reserved. Do not name custom files with "asl" in the filename, for example, 99_asl_custom.conf. This file may be overwritten or deleted by the rule management system. Do not create custom rules with "asl" in the filename.


**Rule IDs for Custom Rules**

   * For custom rules, you must create your own rule ids which must be unique. The id: fields contain the rule ids. For custom rules you should use the local (internal) use range (see below for the reserved id ranges). Do not use assigned ranges.
   
   * The following is a list of reserved ranges: 

      * 1-99,999; reserved for local (internal) use. Use as you see fit but do not use this range for rules that are distributed to others.
	  
      * 100,000-199,999; reserved for internal use of the engine, to assign to rules that do not have explicit IDs.
      * 200,000-299,999; reserved for rules published at modsecurity.org.
      * 300,000-399,999; reserved for rules published at gotroot.com.
      * 400,000-419,999; unused (available for reservation).
      * 420,000-429,999; reserved for ScallyWhack.
      * 430,000-699,999; unused (available for reservation).
      * 700,000-799,999; reserved for Ivan Ristic.
      * 900,000-999,999; reserved for the Core Rules project.
	  
      * 1,000,000 and above; unused (available for reservation). 
	  
	  
**Installing Custom Rules**

   **Linux:**
   
      * Apache

         Step 1: Create your custom rules directory by running the following command:
		 
            .. code-block:: console
			
               mkdir /etc/httpd/modsecurity.custom.d


         Step 2: Create a configuration file for your custom rules in **/etc/httpd/conf.d** directory. For example: 
		 
            Create the file 01_modsecurity.conf and add this line to it: 
			
               .. code-block:: console
			   
                  Include modsecurity.custom.d/99_zzz_custom.conf
				  
				  
            .. note:: You can download an example file `here`_ 
			
            .. _here: https://www.atomicorp.com/examples/01_modsecurity.conf
			
			
         Step 3: Install your custom rules in the **etc/httpd/modsecurity.custom.d** directory by running the following command
		 
            .. code-block:: console
			
               cd /etc/httpd/modsecurity.custom.d
			   
            Edit the file **99_zzz_custom.conf** and place your custom rules in that file. 

						
            .. note:: You can download a same file on this `page`_ 
			
            .. _page: https://www.atomicorp.com/examples/99_zzz_custom.conf
			
			
         Step 4: Test your Apache configuration, by running the following command
		 
            .. code-block:: console
			
               service httpd configtest
			   
			   
         Step 5: If your test was successful, then restart Apache by running the following command
		 
            .. code-block:: console
			
               service httpd restart 
			   
			   
   
   **Windows:**
   
      * LLS
	  
         Step 1: Modify your ModSecurity configuration file on windows and add this line to the end of the file. 
		 
            .. code-block:: console
			
               Include 99_zzz_custom.conf
			   
			   
         Step 2: Edit the file 99_zzz_custom.conf and save it in the same directory as your ModSecurity configuration file. 
		 
         Step 3: Restart LLS
		 
		 
   .. note:: Our professional services group would be happy to help you with your custom rules needs, including developing the rules for you. If your request is something that we can safely include in the rules for all our customers, we're generally able to develop these new rules for free. Please contact us to discuss your rules needs.
   
   
---------

Modifying a Rule
================

If you want to modify the internal logic of a rule, you will want to "fork" or copy that rule into a custom rule. Do not modify the actual rules provided by us, your modifications will be overwritten with the next update.

Please follow the process below for modifying a rule: 

   Step 1: Copy the rule you want to modify into your custom rules file
   
      Copy the rule in its entirety into your custom rule file. For example, if you wanted to modify rule 390707, you would copy the entire rule into your custom rules file. For example:

      .. code-block:: console
	  
         # Restrict the maximum number of arguments in a request
         SecRule &ARGS "@gt 1000"  \
         "chain,phase:2,t:none,log,auditlog,deny,status:403,msg:'Atomicorp.com WAF Rules: Too many arguments in request (max set to 1000, increase as necessary for your system)',id:'390707',severity:'4',rev:'8'"
         SecRule REQUEST_URI "!((?:^/(?:imaclean|massdelete)/)|^/cgi-bin/dada/mail\.cgi$|^/index\.php/mageworx/customoptions_options|^/za/|^/back-?office/|^/moderate\.php|^/backend/configdomains\.php|\.do$|^/admin[a-z0-9]+?/index\.php\?controller=adminmodules)"  "t:none,t:lowercase"        
		 
		 
   Step 2: Change the Rule ID
   
      This is absolutely required. No two rules can have the same ID
	  
      .. code-block:: console
	  
         # Restrict the maximum number of arguments in a request
         SecRule &ARGS "@gt 1000"  \
         "chain,phase:2,t:none,log,auditlog,deny,status:403,msg:'Atomicorp.com WAF Rules: Too many arguments in request (max set to 1000, increase as necessary for your system)',id:'12345678',severity:'4',rev:'8'"
         SecRule REQUEST_URI "!((?:^/(?:imaclean|massdelete)/)|^/cgi-bin/dada/mail\.cgi$|^/index\.php/mageworx/customoptions_options|^/za/|^/back-?office/|^/moderate\.php|^/backend/configdomains\.php|\.do$|^/admin[a-z0-9]+?/index\.php\?controller=adminmodules)"  "t:none,t:lowercase"
		 
		 
   Step 3: Disable the Original Rule
   
      * If you want your custom rule to be global, that is your modification applies to the entire system, then you will want to see Disabling a Rule for all Domains above. 
	 
      * If you want to disable the rule for a single application, then please see the disabling a rule for a web application above. 
	 
      * If you want to disable the rule for a specific IP or Network, then please see the instructions above. 

      * If you want to disable the rule for a single domain, then please the instructions above. 


   Step 4: Set the Scope for the Rule

      If you haven't disabled the original rule globally, or for one or more domains, then you will need to set the scope of your custom rule. To limit your modification to a specific application, place your custom rule inside <LocationMatch> tags. For example:

      .. code-block:: console

         <LocationMatch /url/to/your/custom/application>
          # Restrict the maximum number of arguments in a request 
          SecRule &ARGS "@gt 2048"  \
          "chain,phase:2,t:none,log,auditlog,deny,status:403,msg:'Atomicorp.com WAF Rules: Too many arguments in request (max set to 1000, increase as necessary for your system)',id:'12345678',severity:'4',rev:'8'"
          SecRule REQUEST_URI "!((?:^/(?:imaclean|massdelete)/)|^/cgi-bin/dada/mail\.cgi$|^/index\.php/mageworx/customoptions_options|^/za/|^/back-?office/|^/moderate\.php|^/backend/configdomains\.php|\.do$|^/admin[a-z0-9]+?/index\.php\?controller=adminmodules)"  "t:none,t:lowercase"
         </LocationMatch> 
		 
		 
---------

Configuring and Setting Up ModSecurity
======================================

   .. note:: If you are running Atomic Protector you do not need to do this. Atomic Protector will setup and manage ModSecurity for you. The page linked to below is only for non-Atomic Protector customers that must setup ModSecurity manually.
   
   * To setup and configure ModSecurity, please see this `wiki page`_ . 
   
   .. _wiki page: ../modSec/modSec.html
