changeset 2540:d637bc0ac604

mod_firewall: Update README for latest changes
author Matthew Wild <mwild1@gmail.com>
date Tue, 21 Feb 2017 10:39:00 +0000
parents 1510b66a43fc
children 76f03d514b13
files mod_firewall/README.markdown
diffstat 1 files changed, 143 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/mod_firewall/README.markdown	Tue Feb 21 10:38:14 2017 +0000
+++ b/mod_firewall/README.markdown	Tue Feb 21 10:39:00 2017 +0000
@@ -80,6 +80,11 @@
     NOT FROM: user@example.com
     KIND NOT: message
 
+Some conditions do not take parameters, and these should end with just a
+question mark, like:
+
+    IN ROSTER?
+
 ### Zones
 
 A 'zone' is one or more hosts or JIDs. It is possible to match when a
@@ -105,6 +110,53 @@
   `ENTERING`   When a stanza is entering the named zone
   `LEAVING`    When a stanza is leaving the named zone
 
+### Lists
+
+It is possible to create or load lists of strings for use in scripts. For example, you might load a JID blacklist,
+a list of malware URLs or simple words that you want to filter messages on.
+
+  List type    Example
+  -----------  -----------------------
+  memory       %LIST spammers: memory
+  file         %LIST spammers: file:/etc/spammers.txt
+  http         %LIST spammers: http://example.com/spammers.txt
+
+#### CHECK LIST
+
+Checks whether a simple expression is found in a given list.
+
+Example:
+
+    %LIST blacklist: file:/etc/prosody/blacklist.txt
+
+    # Rule to block presence subscription requests from blacklisted JIDs
+    KIND: presence
+    TYPE: subscribe
+    CHECK LIST: blacklist contains $<@from>
+    BOUNCE=policy-violation (Your JID is blacklisted)
+
+#### SCAN
+
+SCAN allows you to search inside a stanza for a given pattern, and check each result against a list. For example,
+you could scan a message body for words and check if any of the words are found in a given list.
+
+Before using SCAN, you need to define a search location and a pattern. The search location uses the same 'path'
+format as documented under the 'INSPECT' condition. Patterns can be any valid Lua pattern.
+
+To use the above example:
+
+    # Define a search location called 'body' which fetches the text of the 'body' element
+    %SEARCH body: body#
+    # Define a pattern called 'word' which matches any sequence of letters
+    %PATTERN word: [A-Za-z]+
+    # Finally, we also need our list of "bad" words:
+    %LIST badwords: file:/etc/prosody/bad_words.txt
+    
+    # Now we can use these to SCAN incoming stanzas
+    # If it finds a match, bounce the stanza
+    SCAN: body for word in badwords
+    BOUNCE=policy-violation (This word is not allowed!)
+
 ### Stanza matching
 
   Condition   Matches
@@ -127,47 +179,6 @@
 Similarly, a message stanza with no type is equivalent to one of type
 'normal'. mod\_firewall handles these cases for you automatically.
 
-#### INSPECT
-
-INSPECT takes a 'path' through the stanza to get a string (an attribute
-value or text content). An example is the best way to explain. Let's
-check that a user is not trying to register an account with the username
-'admin'. This stanza comes from [XEP-0077: In-band
-Registration](http://xmpp.org/extensions/xep-0077.html#example-4):
-
-``` xml
-<iq type='set' id='reg2'>
-  <query xmlns='jabber:iq:register'>
-    <username>bill</username>
-    <password>Calliope</password>
-    <email>bard@shakespeare.lit</email>
-  </query>
-</iq>
-```
-
-    KIND: iq
-    TYPE: set
-    PAYLOAD: jabber:iq:register
-    INSPECT: {jabber:iq:register}query/username#=admin
-    BOUNCE=not-allowed (The username 'admin' is reserved.)
-
-That weird string deserves some explanation. It is a path, divided into
-segments by '/'. Each segment describes an element by its name,
-optionally prefixed by its namespace in curly braces ('{...}'). If the
-path ends with a '\#' then the text content of the last element will be
-returned. If the path ends with '@name' then the value of the attribute
-'name' will be returned.
-
-You can use INSPECT to test for the existence of an element or attribute,
-or you can see if it is equal to a string by appending `=STRING` (as in the
-example above). Finally,you can also test whether it matches a given Lua
-pattern by using `~=PATTERN`.
-
-INSPECT is somewhat slower than the other stanza matching conditions. To
-minimise performance impact, always place it below other faster
-condition checks where possible (e.g. above we first checked KIND, TYPE
-and PAYLOAD matched before INSPECT).
-
 ### Sender/recipient matching
 
   Condition   Matches
@@ -213,6 +224,47 @@
 stanza. It is not advisable to perform access control or similar rules
 on JIDs in these chains (see the chain documentation for more info).
 
+#### INSPECT
+
+INSPECT takes a 'path' through the stanza to get a string (an attribute
+value or text content). An example is the best way to explain. Let's
+check that a user is not trying to register an account with the username
+'admin'. This stanza comes from [XEP-0077: In-band
+Registration](http://xmpp.org/extensions/xep-0077.html#example-4):
+
+``` xml
+<iq type='set' id='reg2'>
+  <query xmlns='jabber:iq:register'>
+    <username>bill</username>
+    <password>Calliope</password>
+    <email>bard@shakespeare.lit</email>
+  </query>
+</iq>
+```
+
+    KIND: iq
+    TYPE: set
+    PAYLOAD: jabber:iq:register
+    INSPECT: {jabber:iq:register}query/username#=admin
+    BOUNCE=not-allowed (The username 'admin' is reserved.)
+
+That weird string deserves some explanation. It is a path, divided into
+segments by '/'. Each segment describes an element by its name,
+optionally prefixed by its namespace in curly braces ('{...}'). If the
+path ends with a '\#' then the text content of the last element will be
+returned. If the path ends with '@name' then the value of the attribute
+'name' will be returned.
+
+You can use INSPECT to test for the existence of an element or attribute,
+or you can see if it is equal to a string by appending `=STRING` (as in the
+example above). Finally,you can also test whether it matches a given Lua
+pattern by using `~=PATTERN`.
+
+INSPECT is somewhat slower than the other stanza matching conditions. To
+minimise performance impact, always place it below other faster
+condition checks where possible (e.g. above we first checked KIND, TYPE
+and PAYLOAD matched before INSPECT).
+
 ### Roster
 
 These functions access the roster of the recipient (only). Therefore they cannot (currently)
@@ -222,17 +274,17 @@
 is currently offline), so you may want to limit its use in high-traffic situations, and place
 it below other checks (such as a rate limiter).
 
-#### IN_ROSTER
+#### IN ROSTER
 
 Tests whether the sender is in the recipient's roster.
 
-    IN_ROSTER: yes
+    IN ROSTER?
 
-#### IN_ROSTER_GROUP
+#### IN ROSTER GROUP
 
 Tests whether the sender is in the recipient's roster, and in the named group.
 
-    IN_ROSTER_GROUP: Friends
+    IN ROSTER GROUP: Friends
 
 #### SUBSCRIBED
 
@@ -250,8 +302,20 @@
 
   Condition     Matches
   ------------- ----------------------------
-  `FROM_GROUP`  When the stanza is being sent from a member of the named group
-  `TO_GROUP`    When the stanza is being sent to a member of the named group
+  `FROM GROUP`  When the stanza is being sent from a member of the named group
+  `TO GROUP`    When the stanza is being sent to a member of the named group
+
+#### SENT DIRECTED PRESENCE TO SENDER
+
+This condition matches if the recipient of a stanza has previously sent directed presence to the sender of the stanza. This
+is often done in XMPP to exchange presence information with JIDs that are not on your roster, such as MUC rooms.
+
+This condition does not take a parameter - end the condition name with a question mark:
+
+    # Rule to bounce messages from senders not in the roster who haven't been sent directed presence
+    NOT IN ROSTER?
+    NOT SENT DIRECTED PRESENCE TO SENDER?
+    BOUNCE=service-unavailable
 
 ### Admins
 
@@ -259,8 +323,8 @@
 
   Condition      Matches
   -------------- ----------------------------------
-  FROM_ADMIN_OF  When the sender of the stanza is an admin of the named host on the current server
-  TO_ADMIN_OF    When the recipient of the stanza is an admin of the named host on the current server
+  FROM ADMIN OF  When the sender of the stanza is an admin of the named host on the current server
+  TO ADMIN OF    When the recipient of the stanza is an admin of the named host on the current server
 
 ### Time and date
 
@@ -358,19 +422,19 @@
 
   Condition                       Description
   ------------------------------- ---------------------------------------------------------------
-  ORIGIN_MARKED: markname         Matches if the origin has been marked with 'markname'.
-  ORIGIN_MARKED: markname (Xs)    Matches if the origin has been marked with 'markname' within the past X seconds.
+  ORIGIN MARKED: markname         Matches if the origin has been marked with 'markname'.
+  ORIGIN MARKED: markname (Xs)    Matches if the origin has been marked with 'markname' within the past X seconds.
 
 Example usage:
 
     # This rule drops messages from sessions that have been marked as spammers in the past hour
-    ORIGIN_MARKED: spammer (3600s)
+    ORIGIN MARKED: spammer (3600s)
     DROP.
 
     # This rule marks the origin session as a spammer if they send a message to a honeypot JID
     KIND: message
     TO: honeypot@example.com
-    MARK_ORIGIN=spammer
+    MARK ORIGIN=spammer
 
 Actions
 -------
@@ -423,8 +487,8 @@
 
   Action                   Description
   ------------------------ --------------------------------------------------------------------------
-  `MARK_ORIGIN=mark`        Marks the originating session with the given flag.
-  `UNMARK_ORIGIN=mark`      Removes the given mark from the origin session (if it is set).
+  `MARK ORIGIN=mark`        Marks the originating session with the given flag.
+  `UNMARK ORIGIN=mark`      Removes the given mark from the origin session (if it is set).
 
 **Note:** Marks apply to sessions, not JIDs. E.g. if marking in a rule that matches a stanza received
 over s2s, it is the s2s session that is marked.
@@ -493,7 +557,7 @@
 
   Action                   Description
   ------------------------ ------------------------------------------------------------------------
-  `JUMP_CHAIN=name`        Switches chains, and passes the stanza through the rules in chain 'name'. If the new chain causes the stanza to be dropped/redirected, the current chain halts further processing.
+  `JUMP CHAIN=name`        Switches chains, and passes the stanza through the rules in chain 'name'. If the new chain causes the stanza to be dropped/redirected, the current chain halts further processing.
 
 It is possible to jump to chains defined by other scripts and modules.
 
@@ -506,6 +570,8 @@
 
 There are two kinds of expression that you can use: stanza expressions, and code expressions.
 
+### Stanza expressions
+
 Stanza expressions are of the form `$<...>`, where `...` is a stanza path. For syntax of stanza paths, see the documentation for the 'INSPECT' condition
 above.
 
@@ -513,8 +579,27 @@
 
     LOG=Matched a stanza from $<@from> to $<@to>
 
-If the path does not match (e.g. the element isn't found, or the attribute doesn't exist) it will return the text `<undefined>`. You can override this
-by specifying an alternative default value, using the syntax `$<path||default>`.
+There are built in functions which can be applied to the output of a stanza expression, by appending the pipe ('|') operator, followed by the function
+name. These functions are:
+
+  Function     Description
+  ------------ ---------------------------------------
+  bare         Given a JID, strip any resource
+  node         Return the node ('user part') of a JID
+  host         Return the host ('domain') part of a JID
+  resource     Return the resource part of a JID
+
+For example, to apply a rate limit to stanzas per sender domain:
+
+    LIMIT normal on $<@from|domain>
+
+If the path does not match (e.g. the element isn't found, or the attribute doesn't exist) or any of the functions fail to produce an output (e.g. an invalid
+JID was passed to a function that only handles valid JIDs) the expression will return the text `<undefined>`. You can override this by ending the expression
+with a double pipe ('||') followed by a quoted string to use as a default instead. E.g. to default to the string "normal" when there is no 'type' attribute:
+
+    LOG=Stanza type is $<@type||"normal">
+
+### Code expressions
 
 Code expressions use `$(...)` syntax. Code expressions are powerful, and allow unconstrained access to Prosody's internal environment. Therefore
 code expressions are typically for advanced use-cases only. You may want to refer to Prosody's [developer documentation](https://prosody.im/doc/developers)