1. 程式人生 > >modsecurity系列四:規則實戰1

modsecurity系列四:規則實戰1

Introducing simple rules and operators

介紹簡單的規則和操作

The simplest possible rule will specify only a variable and a regular expression. In the example that follows, we look at the request URI, trying to match the regular expression pattern <script> against it:
SecRule REQUEST_URI <script>
This simple rule takes advantage of the fact that ModSecurity allows a rule not to specify an operator, in which case it assumes the regular expression operator. This feature is a left-over from ModSecurity 1.x, which only supported regular expressions—there were no operators at all. If you wish to you can always explicitly specify the operator. I always do. The above rule is functionally identical to this one:
SecRule REQUEST_URI "@rx <script>"
Note how I’ve had to use double quotes because the second parameter now contains a space.ModSecurity supports a  number of operators. Some are similar, but often have different performance characteristics. For example, the regular expression pattern I used for the examples (<script>) above isn’t much of a pattern. It’s just a string, because it does not contain any special characters. I might have just as well written the same rule using the @contains
operator:

SecRule REQUEST_URI "@contains <script>" 

By now you are probably aware that the operators are very straightforward. They take a piece of a transaction and analyse it, typically comparing it in some way to the parameter you provided in the rule (<script> in the above examples).

Working with variables


You can specify as many variables in a rule as you wish for as long as you separate them
using the pipe character:
SecRule REQUEST_URI|REQUEST_PROTOCOL <script>

Some variables, which we call collections, potentially contain more than one piece of information.This is the case with the ARGS variable, for example, which contains all request parametersin a transaction. You use the colon operator to specify only one member of a collection,as you can see in the following rule which only looks at the parameter named p:
SecRule ARGS:p <script>


You can use the same collection more than once within the same rule, if you wish:
SecRule ARGS:p|ARGS:q <script>


The colon operator is actually quite potent and allows you to use a regular expression tospecify the names, which is helpful when parameter names change at run-time. The followingrule will target all parameters whose names begin with the letter p, catching parameters such as password, or pea:
SecRule ARGS:/^p/ <script>


When you do not restrict a rule to only some members of a collection ModSecurity will assume you want to use all of them. This is quite handy to use in the cases where you don’t know what parameters a page uses. Not all collections can be used in this way (for example, ARGS can but ENV cannot), but when they can a reference to such collection will be expanded into individual variables just before a rule is run. You can observe in the debug log how this works. For example, for a request that has the parameters p, q and z, ARGS expands as follows:


[4] Expanded "ARGS" to "ARGS:p|ARGS:q|ARGS:z".

Now that you know how expansion work, parameter exclusion will make sense: to remove
a parameter from a rule just put an exclamation mark before it. The following rule will look
at all request parameters except at the one named z:

引數排除
SecRule ARGS|!ARGS:z <script>

Combining rules into chains

規則鏈,就是AND邏輯
When you specify more than one variable in a rule you are effectively combining them using
the OR logical operator. The rule will match if any of the variables matches. It is also possible to use a logical AND, whereby you combine several rules into one. Let’s say that you want to write a rule that matches when something is found in both the parameter p and the
parameter q. You write:
SecRule ARGS:p <script> chain
SecRule ARGS:q <script>
This is called rule chaining. The chain action constructs a chain of two or more rules and effectively creates a single rule with more than one evaluation step. The first rule in a chain will always run, but the subsequent rules will run only if all the previous rules (in the same chain) ran. Whenever a rule that belongs to a chain does not match, the execution continues with the first rule that is not part of that chain.

只有當前面的規則都運行了,才會執行下面的規則

Operator negation

操作否定
Operator result can be negated by placing an exclamation mark right before it. For example,if you wanted to write a rule that matches on a username that is not admin nor root (theopposite of the intent in the previous example), you write this:

當不等於admin並且不等於root就匹配上
SecRule ARGS:username "!@rx ^(admin|root)$"

操作否定和運算否定不是一樣的
Operator negation should not be confused with rule negation. The two are the same onlywhen a rule is used against  only one variable, but the situation changes when there are more.Observe the following rule:
SecRule ARGS:p|ARGS:q "!@eq 5"

當p或者q有一個不等於5就匹配上了
The above rule will match if any one parameter does not equal 5. If you want to write a rule that matches when both parameters do not equal 5 you’ll have to use rule chaining:
SecRule ARGS:p "!@eq 5"

Variable counting

變數統計,方法是 前面加& 可以用在任何
Here’s a question for you: how do you detect something that isn’t there? Take the common
rule that addresses all parameters in a request:
SecRule ARGS <script>
In a request without any parameters ARGS will expand to zero variables. Without any variables to work with any operator will fail and the rule (or a chain) will not match.

The answer is to use the ability of ModSecurity to count how many variables there are in a collection. With the help of the ampersand operator we can look into ARGS and detect the case when there are no parameters:

args沒有引數的情況
SecRule &ARGS "@eq 0"
The ampersand operator can be applied to any collection, including a partial one. The following rule will match whenever it sees a request with more than one parameter named
username:
SecRule &ARGS:username "!@eq 1" 請求一個含有一個以上的username會被匹配上

Using actions

新增動作
Most of the examples in this tutorial, so far, didn’t use any actions. I chose to initially focus only on the mechanics of detection. But it is practically impossible to write a rule without specifying a single action. Furthermore, it is good practice to write rules that are self-contained and do not rely on the defaults. Actions are placed in the third parameter of SecRule and the first parameter of SecAction. A rule can have zero, one or more actions. If there is more than one action, they are separated with a comma and any number of whitespace characters in between. The following rule specifies two actions:

動作可以有0個或者多個,動作之間用空格或者逗號
SecRule ARGS K1 log,deny
Some actions have parameters, in which case you will need to place a colon after the action name and follow with the parameter. To deny with status 404, you could use:

有的動作需要引數就用冒號分割
SecRule ARGS K1 log,deny,status:404
Finally, if you want to supply a parameter that uses whitespace or contains a comma, enclose the value in single quotes. This way of parameter handling is often needed with messages:
SecRule ARGS K1 "log,deny,msg:'Acme attack detected'"

In addition to using single quotes around the parameter to the msg action, I enclosed the entire third directive parameter in double quotes. This is needed for Apache to correctly parse the directive line. You shall see later that some actions take complex parameters (e.g., ctl and setvar), but the same syntax discussed here applies to them too.

Understanding action defaults

明白預設的規則
You now know how to specify rule actions, but what happens if you don’t? ModSecurity has a concept of default action list. Whenever a new rule is added to the configuration, the action list of the rule is merged with the default action list. The default action list is (in ModSecurity 2.5.11) is phase:2,log,auditlog,pass, but you can override that at any time using the SecDefaultAction directive. In the simplest case, when the rule being added has no action, the default action list is used instead. Take the following rule (and assume there are no other rules or defaults in the configuration):

在modsecurity是有預設規則的,預設規則在2.5.11是  is phase:2,log,auditlog,pass, 你可以覆蓋他們使用 SecDefaultAction 
SecRule ARGS K1 It is equivalent to:
SecRule ARGS K1 phase:2,log,auditlog,pass
In a general case, when a rule has one or more actions, merging means one of two things: Rule action replaces an action in the default action list This will typically happen with disruptive actions, of which there can only be one per
rule. If there’s a disruptive action specified in the default actions list and in the rule, the one in the rule will override the default one Rule action is appended to the ones in the default action list Some actions can appear more than once in an action list. This is the case with many non-disruptive actions, for example t, setvar, ctl and so on. In some cases it is possible for the rule actions to completely remove the default actions, but how that’s donedepends on the action in question. With transformation action, for example, specifying none as an transformation function (t:none) will clear the list and start over. The idea with SecDefaultAction was to make the job of rule writing easier by enabling youto specify the commonly used actions only once. For example, you could write something

在預設的情況下,當一條規則有多個動作有2種情況:第一種是當有破壞性的動作的時候這個時候就會替換預設規則的,還有一種是不是破壞性的規則就直接最佳到預設規則後面比如t setvar ctl等等。
like this:
SecDefaultAction phase:2,log,deny,status:404
SecRule ARGS K1
SecRule ARGS K2
...
SecRule ARGS K99
The above approach works well when you’re in complete control of your configuration, but it complicates things because the rules are no longer self contained. The configuration is perhaps easier to write one day, but more difficult to understand when you come in a couple of months’ time. Furthermore, there’s always a danger that there will be unforeseen interaction between the defaults and the rule. For example, suppose you write a rule that rely