Comparison

mod_firewall/README.markdown @ 1803:4d73a1a6ba68

Convert all wiki pages to Markdown
author Kim Alvefur <zash@zash.se>
date Fri, 28 Aug 2015 18:03:58 +0200
parent 1782:mod_firewall/README.wiki@29f3d6b7ad16
child 2002:ce991c678370
comparison
equal deleted inserted replaced
1802:0ab737feada6 1803:4d73a1a6ba68
1 ---
2 labels:
3 - 'Stage-Alpha'
4 summary: 'A rule-based stanza filtering module'
5 ...
6
7 ------------------------------------------------------------------------
8
9 **Note:** mod\_firewall is in its very early stages. This documentation
10 is liable to change, and some described functionality may be missing,
11 incomplete or contain bugs. Feedback is welcome in the comments section
12 at the bottom of this page.
13
14 ------------------------------------------------------------------------
15
16 Introduction
17 ============
18
19 A firewall is an invaluable tool in the sysadmin's toolbox. However
20 while low-level firewalls such as iptables and pf are incredibly good at
21 what they do, they are generally not able to handle application-layer
22 rules.
23
24 The goal of mod\_firewall is to provide similar services at the XMPP
25 layer. Based on rule scripts it can efficiently block, bounce, drop,
26 forward, copy, redirect stanzas and more! Furthermore all rules can be
27 applied and updated dynamically at runtime without restarting the
28 server.
29
30 Details
31 =======
32
33 mod\_firewall loads one or more scripts, and compiles these to Lua code
34 that reacts to stanzas flowing through Prosody. The firewall script
35 syntax is unusual, but straightforward.
36
37 A firewall script is dominated by rules. Each rule has two parts:
38 conditions, and actions. When a stanza matches all of the conditions,
39 all of the actions are executed in order.
40
41 Here is a simple example to block stanzas from spammer@example.com:
42
43 FROM: spammer@example.com
44 DROP.
45
46 FROM is a condition, and DROP is an action. This is about as simple as
47 it gets. How about heading to the other extreme? Let's demonstrate
48 something more complex that mod\_firewall can do for you:
49
50 %ZONE myorganisation: staff.myorg.example, support.myorg.example
51
52 ENTERING: myorganisation
53 KIND: message
54 TIME: 12am-9am, 5pm-12am, Saturday, Sunday
55 REPLY=Sorry, I am afraid our office is closed at the moment. If you need assistance, please call our 24-hour support line on 123-456-789.
56
57 This rule will reply with a short message whenever someone tries to send
58 a message to someone at any of the hosts defined in the 'myorganisation'
59 outside of office hours.
60
61 Firewall rules should be written to a `ruleset.pfw` file. Multiple such
62 rule files can be specified in the configuration using:
63
64 firewall_scripts = { "path/to/ruleset.pfw" }
65
66 Conditions
67 ----------
68
69 All conditions must come before any action in a rule block. The
70 condition name is followed by a colon (':'), and the value to test for.
71
72 A condition can be preceded or followed by `NOT` to negate its match.
73 For example:
74
75 NOT FROM: user@example.com
76 KIND NOT: message
77
78 ### Zones
79
80 A 'zone' is one or more hosts or JIDs. It is possible to match when a
81 stanza is entering or leaving a zone, while at the same time not
82 matching traffic passing between JIDs in the same zone.
83
84 Zones are defined at the top of a script with the following syntax (they
85 are not part of a rule block):
86
87 %ZONE myzone: host1, host2, user@host3, foo.bar.example
88
89 A host listed in a zone also matches all users on that host (but not
90 subdomains).
91
92 The following zone-matching conditions are supported:
93
94 Condition Matches
95 ------------ ------------------------------------------
96 `ENTERING` When a stanza is entering the named zone
97 `LEAVING` When a stanza is leaving the named zone
98
99 ### Stanza matching
100
101 Condition Matches
102 ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------
103 `KIND` The kind of stanza. May be 'message', 'presence' or 'iq'
104 `TYPE` The type of stanza. This varies depending on the kind of stanza. See 'Stanza types' below for more information.
105 `PAYLOAD` The stanza contains a child with the given namespace. Useful for determining the type of an iq request, or whether a message contains a certain extension.
106 `INSPECT` The node at the specified path exists or matches a given string. This allows you to look anywhere inside a stanza. See below for examples and more.
107
108 #### Stanza types
109
110 Stanza Valid types
111 ---------- ------------------------------------------------------------------------------------------
112 iq get, set, result, error
113 presence *available*, unavailable, probe, subscribe, subscribed, unsubscribe, unsubscribed, error
114 message normal, chat, groupchat, headline, error
115
116 **Note:** The type 'available' for presence does not actually appear in
117 the protocol. Available presence is signalled by the omission of a type.
118 Similarly, a message stanza with no type is equivalent to one of type
119 'normal'. mod\_firewall handles these cases for you automatically.
120
121 #### INSPECT
122
123 INSPECT takes a 'path' through the stanza to get a string (an attribute
124 value or text content). An example is the best way to explain. Let's
125 check that a user is not trying to register an account with the username
126 'admin'. This stanza comes from [XEP-0077: In-band
127 Registration](http://xmpp.org/extensions/xep-0077.html#example-4):
128
129 <iq type='set' id='reg2'>
130 <query xmlns='jabber:iq:register'>
131 <username>bill</username>
132 <password>Calliope</password>
133 <email>bard@shakespeare.lit</email>
134 </query>
135 </iq>
136
137 KIND: iq
138 TYPE: set
139 PAYLOAD: jabber:iq:register
140 INSPECT: {jabber:iq:register}query/username#=admin
141 BOUNCE=not-allowed The username 'admin' is reserved.
142
143 That weird string deserves some explanation. It is a path, divided into
144 segments by '/'. Each segment describes an element by its name,
145 optionally prefixed by its namespace in curly braces ('{...}'). If the
146 path ends with a '\#' then the text content of the last element will be
147 returned. If the path ends with '@name' then the value of the attribute
148 'name' will be returned.
149
150 INSPECT is somewhat slower than the other stanza matching conditions. To
151 minimise performance impact, always place it below other faster
152 condition checks where possible (e.g. above we first checked KIND, TYPE
153 and PAYLOAD matched before INSPECT).
154
155 ### Sender/recipient matching
156
157 Condition Matches
158 ----------- -------------------------------------------------------
159 `FROM` The JID in the 'from' attribute matches the given JID
160 `TO` The JID in the 'to' attribute matches the given JID
161
162 These conditions both accept wildcards in the JID when the wildcard
163 expression is enclosed in angle brackets ('\<...\>'). For example:
164
165 # All users at example.com
166 FROM: <*>@example.com
167
168 # The user 'admin' on any subdomain of example.com
169 FROM: admin@<*.example.com>
170
171 You can also use [Lua's pattern
172 matching](http://www.lua.org/manual/5.1/manual.html#5.4.1) for more
173 powerful matching abilities. Patterns are a lightweight
174 regular-expression alternative. Simply contain the pattern in double
175 angle brackets. The pattern is automatically anchored at the start and
176 end (so it must match the entire portion of the JID).
177
178 # Match admin@example.com, and admin1@example.com, etc.
179 FROM: <<admin%d*>>@example.com
180
181 **Note:** It is important to know that 'example.com' is a valid JID on
182 its own, and does **not** match 'user@example.com'. To perform domain
183 whitelists or blacklists, use Zones.
184
185 **Note:** Some chains execute before Prosody has performed any
186 normalisation or validity checks on the to/from JIDs on an incoming
187 stanza. It is not advisable to perform access control or similar rules
188 on JIDs in these chains (see the chain documentation for more info).
189
190 ### Time and date
191
192 #### TIME
193
194 Matches stanzas sent during certain time periods.
195
196 Condition Matches
197 ----------- -------------------------------------------------------------------------------------------
198 TIME When the current server local time is within one of the comma-separated time ranges given
199
200 TIME: 10pm-6am, 14:00-15:00
201 REPLY=Zzzz.
202
203 #### DAY
204
205 It is also possible to match only on certain days of the week.
206
207 Condition Matches
208 ----------- -----------------------------------------------------------------------------------------------------
209 DAY When the current day matches one, or falls within a rage, in the given comma-separated list of days
210
211 Example:
212
213 DAY: Sat-Sun, Wednesday
214 REPLY=Sorry, I'm out enjoying life!
215
216 ### Rate-limiting
217
218 It is possible to selectively rate-limit stanzas, and use rules to
219 decide what to do with stanzas when over the limit.
220
221 First, you must define any rate limits that you are going to use in your
222 script. Here we create a limiter called 'normal' that will allow 2
223 stanzas per second, and then we define a rule to bounce messages when
224 over this limit. Note that the `RATE` definition is not part of a rule
225 (multiple rules can share the same limiter).
226
227 %RATE normal: 2 (burst 3)
228
229 KIND: message
230 LIMIT: normal
231 BOUNCE=policy-violation (Sending too fast!)
232
233 The 'burst' parameter on the rate limit allows you to spread the limit
234 check over a given time period. For example the definition shown above
235 will allow the limit to be temporarily surpassed, as long as it is
236 within the limit after 3 seconds. You will almost always want to specify
237 a burst factor.
238
239 Both the rate and the burst can be fractional values. For example a rate
240 of 0.1 means only one event is allowed every 10 seconds.
241
242 The LIMIT condition actually does two things; first it counts against
243 the given limiter, and then it checks to see if the limiter over its
244 limit yet. If it is, the condition matches, otherwise it will not.
245
246 Condition Matches
247 ----------- --------------------------------------------------------------------------------------------------
248 `LIMIT` When the named limit is 'used up'. Using this condition automatically counts against that limit.
249
250 **Note:** Reloading mod\_firewall resets the current state of any
251 limiters.
252
253 Actions
254 -------
255
256 Actions come after all conditions in a rule block. There must be at
257 least one action, though conditions are optional.
258
259 An action without parameters ends with a full-stop/period ('.'), and one
260 with parameters uses an equals sign ('='):
261
262 # An action with no parameters:
263 DROP.
264
265 # An action with a parameter:
266 REPLY=Hello, this is a reply.
267
268 ### Route modification
269
270 The most common actions modify the stanza's route in some way. Currently
271 the first matching rule to do so will halt further processing of actions
272 and rules (this may change in the future).
273
274 Action Description
275 ----------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------
276 `PASS.` Stop executing actions and rules on this stanza, and let it through this chain.
277 `DROP.` Stop executing actions and rules on this stanza, and discard it.
278 `REDIRECT=jid` Redirect the stanza to the given JID.
279 `REPLY=text` Reply to the stanza (assumed to be a message) with the given text.
280 `BOUNCE.` Bounce the stanza with the default error (usually service-unavailable)
281 `BOUNCE=error` Bounce the stanza with the given error (MUST be a defined XMPP stanza error, see [RFC6120](http://xmpp.org/rfcs/rfc6120.html#stanzas-error-conditions).
282 `BOUNCE=error (text)` As above, but include the supplied human-readable text with a description of the error
283 `COPY=jid` Make a copy of the stanza and send the copy to the specified JID.
284
285 ### Stanza modification
286
287 These actions make it possible to modify the content and structure of a
288 stanza.
289
290 Action Description
291 ------------------------ ------------------------------------------------------------------------
292 `STRIP=name` Remove any child elements with the given name in the default namespace
293 `STRIP=name namespace` Remove any child elements with the given name and the given namespace
294 `INJECT=xml` Inject the given XML into the stanza as a child element
295
296 ### Informational
297
298 Action Description
299 --------------- ------------------------------------------------------------------------------------------------------------------------
300 `LOG=message` Logs the given message to Prosody's log file. Optionally prefix it with a log level in square brackets, e.g. `[debug]`