New build path variable
[freeradius.git] / doc / configurable_failover.rst
1 Configurable Module Fail Over
2 =============================
3
4 Before configurable module failover, we had this kind of entry in
5 ``radiusd.conf``:
6
7 ::
8
9   #---
10   authorize {
11     preprocess
12     files
13   }
14   #---
15
16 This entry instructed the ``authorize`` section to first process the
17 request through the ``preprocess`` module, and if that returned success,
18 to process it through ``files`` module.  If that sequence returned
19 success, then the ``authorize`` stage itself would then return success.
20 Processing was strictly linear and if one module failed, the whole
21 section would fail immediately.
22
23 Configurable failover provides more flexibility. It takes advantage
24 of the tree structure of radiusd.conf to support a configuration
25 language that allows you to ``group`` modules that should work together
26 in ways other than simple lists.  You can control the flow of any
27 stage (e.g. ``authorize``) to fit your needs, without touching C code,
28 just by altering radiusd.conf.
29
30 This configurable fail-over has a convenient short-hand, too.
31 Administrators commonly want to say things like "try SQL1, if it's
32 down, try SQL2, otherwise drop the request."
33
34 For example:
35
36 ::
37
38   #---
39   modules {
40     sql sql1 {
41       # configuration to connect to SQL database one
42     }
43     sql sql2 {
44       # configuration to connect to SQL database two
45     }
46     always handled {
47       rcode = handled
48     }
49   }
50
51   #  Handle accounting packets
52   accounting {
53       detail                    # always log to detail, stopping if it fails
54       redundant {
55         sql1                    # try module sql1
56         sql2                    # if that's down, try module sql2
57         handled                 # otherwise drop the request as
58                                 # it's been ``handled`` by the ``always``
59                                 # module (see doc/rlm_always)
60       }
61   }
62   #---
63
64 The ``redundant`` section is a configuration directive which tells the
65 server to process the second module if the first one fails.  Any
66 number of modules can be listed in a ``redundant`` section.  The server
67 will process each in turn, until one of the modules succeeds.  It will then stop processing the ``redundant`` list.
68
69 Rewriting results for single modules
70 ------------------------------------
71
72 Normally, when a module fails, the entire section (``authorize``,
73 ``accounting``, etc.) stops being processed.  In some cases, we may want
74 to permit  "soft failures".  That is, we may want to tell the server
75 that it is "ok" for a module to fail, and that the failure should not
76 be treated as a fatal error.
77
78 In this case, the module is treated as a "section", rather than just
79 as a single lne in ``radiusd.conf``.  The configuration entries for
80 that section are taken from the ``configurable fail-over`` code, and not
81 from the configuration information for that module.
82
83 For example, the ``detail`` module normally returns ``fail`` if it is
84 unable to write its information to the ``detail`` file.  As a test, we
85 can configure the server so that it continues processing the request,
86 even if the ``detail`` module fails.  The following example shows how:
87
88 ::
89
90   #--
91   #  Handle accounting packets
92   accounting {
93       detail {
94         fail = 1
95       }
96       redundant {
97         sql1
98         sql2
99         handled
100       }
101   }
102   #--
103
104 The ``fail = 1`` entry tells the server to remember the ``fail`` code,
105 with priority ``1``.  The normal configuration is ``fail = return``, which
106 means ``if the detail module fails, stop processing the accounting
107 section``.
108
109 Fail-over configuration entries
110 -------------------------------
111
112 Modules normally return on of the following codes as their result:
113
114 +-----------+-----------------------------------------------------+
115 |Code       | Meaning                                             |
116 +===========+=====================================================+
117 |notfound   | the user was not found                              |
118 +-----------+-----------------------------------------------------+
119 |noop       | the module did nothing                              |
120 +-----------+-----------------------------------------------------+
121 |ok         | the module succeeded                                |
122 +-----------+-----------------------------------------------------+
123 |updated    | the module updated information in the request       |
124 +-----------+-----------------------------------------------------+
125 |fail       | the module failed                                   |
126 +-----------+-----------------------------------------------------+
127 |reject     | the module rejected the user                        |
128 +-----------+-----------------------------------------------------+
129 |userlock   | the user was locked out                             |
130 +-----------+-----------------------------------------------------+
131 |invalid    | the user's configuration entry was invalid          |
132 +-----------+-----------------------------------------------------+
133 |handled    | the module has done everything to handle the request|
134 +-----------+-----------------------------------------------------+
135         
136 In a configurable fail-over section, each of these codes may be
137 listed, with a value.  If the code is not listed, or a configurable
138 fail-over section is not defined, then values that make sense for the
139 requested ``group`` (group, redundant, load-balance, etc) are used.
140
141 The special code ``default`` can be used to set all return codes to
142 the specified value.  This value will be used with a lower priority
143 than ones that are explicitly set.
144
145 The values for each code may be one of two things:
146
147 +---------+---------------------------------------------------------------+
148 |Value    | Meaning                                                       |
149 +=========+===============================================================+
150 |<number> | Priority for this return code.                                |
151 +---------+---------------------------------------------------------------+
152 |return   | Stop processing this configurable fail-over list.             |
153 +---------+---------------------------------------------------------------+
154 |reject   | Stop processing this configurable fail-over list and          |
155 |         | immediately return a reject.                                  |
156 +---------+---------------------------------------------------------------+
157
158 The ``<number>`` used for a value may be any decimal number between 1
159 and 99999.  The number is used when processing a list of modules, to
160 determine which code is returned from the list.  For example, if
161 ``module1`` returns ``fail`` with priority ``1``, and a later ``module2``
162 returns ``ok`` with priority ``3``, the return code from the list of
163 modules will be ``ok``, because it has higher priority than ``fail``.
164
165 This configurability allows the administrator to permit some modules
166 to fail, so long as a later module succeeds.
167
168
169 More Complex Configurations
170 ---------------------------
171
172 The ``authorize`` section is normally a list of module names.  We can
173 create sub-lists by using the section name ``group``.  The ``redundant``
174 section above is just a short-hand for ``group``, with a set of default
175 return codes, which are different than the normal ``stop processing the
176 list on failure``.
177
178 For example, we can configure two detail modules, and allow either
179 to fail, so long as one of them succeeds.
180
181 ::
182
183   #--
184   #  Handle accounting packets
185   accounting {
186       group {
187         detail1 {
188           fail = 1              # remember ``fail`` with priority 1
189           ok = return           # if we succeed, don't do ``detail2``
190         }
191         detail2 {
192           fail = 1              # remember ``fail`` with priority 1
193           ok = return           # if we succeed, return ``ok``
194                                 # if ``detail1`` returned ``fail``
195         }
196       }                 # returns ``fail`` only if BOTH modules returned ``fail``
197       redundant {
198         sql1
199         sql2
200         handled
201       }
202   }
203   #--
204
205 This configuration says:
206
207         - log to ``detail1``, and stop processing the ``group`` list if ``detail1`` returned OK.
208
209         - If ``detail1`` returned ``fail``, then continue, but remember the ``fail`` code, with priority 1.
210
211         - If ``detail2`` fails, then remember ``fail`` with priority 1.
212
213         - If ``detail2`` returned ``ok``, return ``ok`` from the ``group``.
214
215 The return code from the ``group`` is the return code which was either
216 forced to return (e.g. ``ok`` for ``detail1``), or the highest priority
217 return code found by processing the list.
218
219 This process can be extended to any number of modules listed in a
220 ``group`` section.
221
222
223 Virtual Modules
224 ---------------
225
226 Some configurations may require using the same list of modules, in
227 the same order, in multiple sections.  For those systems, the
228 configuration can be simplified through the use of ``virtual`` modules.
229 These modules are configured as named sub-sections of the
230 ``instantiate`` section, as follows:
231
232 ::
233
234         instantiate {
235                 ...
236
237                 redundant sql1_or_2 {
238                         sql1
239                         sql2
240                 }
241         }
242
243 The name ``sql1_or_2`` can then be used in any other section, such as
244 ``authorize`` or ``accounting``.  The result will be *exactly* as if that
245 section was placed at the location of the ``sql1_or_2`` reference.
246
247 These virtual modules are full-fledged objects in and of themselves.
248 One virtual module can refer to another virtual module, and they can
249 contain ``if`` conditions, or any other configuration permitted in a
250 section.
251
252
253 Redundancy and Load-Balancing
254 -----------------------------
255
256 See ``man unlang`` or ``doc/load-balance`` for information on simple
257 redundancy (fail-over) and load balancing.
258
259
260 The Gory Details
261 -----------------
262
263 The fundamental object is called a MODCALLABLE, because it is something that
264 can be passed a specific radius request and returns one of the RLM_MODULE_*
265 results. It is a function - if you can accept the fact that pieces of
266 radiusd.conf are functions. There are two kinds of MODCALLABLEs: GROUPs and
267 SINGLEs.
268
269 A SINGLE is a reference to a module instance that was set up in the modules{}
270 section of radiusd.conf, like ``preprocess`` or ``sql1``. When a SINGLE is
271 called, the corresponding function in the rlm is invoked, and whichever
272 RLM_MODULE_* it returns becomes the RESULT of the SINGLE.
273
274 A GROUP is a section of radiusd.conf that includes some MODCALLABLEs.
275 Examples of GROUPs above include ``authorize{...}``, which implements the C
276 function module_authorize, and ``redundant{...}``, which contains two SINGLEs
277 that refer to a couple of redundant databases. Note that a GROUP can contain
278 other GROUPs - ``Auth-Type SQL{...}`` is also a GROUP, which implements the C
279 function module_authenticate when Auth-Type is set to SQL.
280
281 Now here's the fun part - what happens when a GROUP is called? It simply runs
282 through all of its children in order, and calls each one, whether it is
283 another GROUP or a SINGLE. It then looks at the RESULT of that child, and
284 takes some ACTION, which is basically either ``return that RESULT immediately``
285 or ``Keep going``. In the first example, any ``bad`` RESULT from the preprocess
286 module causes an immediate return, and any ``good`` RESULT causes the
287 authorize{...} GROUP to proceed to the files module.
288
289 We can see the exact rules by writing them out the long way:
290
291 ::
292
293   authorize {
294     preprocess {
295       notfound = 1
296       noop     = 2
297       ok       = 3
298       updated  = 4
299       fail     = return
300       reject   = return
301       userlock = return
302       invalid  = return
303       handled  = return
304     }
305     files {
306       notfound = 1
307       noop     = 2
308       ok       = 3
309       updated  = 4
310       fail     = return
311       reject   = return
312       userlock = return
313       invalid  = return
314       handled  = return
315     }
316   }
317
318 This is the same as the first example, with the behavior explicitly
319 spelled out. Each SINGLE becomes its own section, containing a list of
320 RESULTs that it may return and what ACTION should follow from them. So
321 preprocess is called, and if it returns for example RLM_MODULE_REJECT,
322 then the reject=return rule is applied, and the authorize{...} GROUP
323 itself immediately returns RLM_MODULE_REJECT.
324
325 If preprocess returns RLM_MODULE_NOOP, the corresponding ACTION is ``2``. An
326 integer ACTION serves two purposes - first, it tells the parent GROUP to go
327 on to the next module. Second, it is a hint as to how desirable this RESULT
328 is as a candidate for the GROUP's own RESULT. So files is called... suppose
329 it returns RLM_MODULE_NOTFOUND. The ACTION for notfound inside the files{...}
330 block is ``1``. We have now reached the end of the authorize{...} GROUP and we
331 look at the RESULTs we accumulated along the way - there is a noop with
332 preference level 2, and a notfound with preference level 1, so the
333 authorize{...} GROUP as a whole returns RLM_MODULE_NOOP, which makes sense
334 because to say the user was not found at all would be a lie, since preprocess
335 apparently found him, or else it would have returned RLM_MODULE_NOTFOUND too.
336
337 We could use the ``default`` code to simplify the above example a
338 little.  The following two configurations are identical:
339
340 ::
341
342   files {
343     notfound = 1
344     noop     = 2
345     ok       = 3
346     updated  = 4
347     default  = return
348   }
349
350
351 When putting the ``default`` first, later definitions over-ride it's
352 return code:
353
354 ::
355
356   files {
357     default  = return
358     notfound = 1
359     noop     = 2
360     ok       = 3
361     updated  = 4
362   }
363
364 [Take a deep breath - the worst is over]
365
366 That RESULT preference/desirability stuff is pretty complex, but my hope is
367 that it will be complex enough to handle the needs of everyone's real-world
368 imperfect systems, while staying out of sight most of the time since the
369 defaults will be right for the most common configurations.
370
371 So where does redundant{...} fit in with all that? Well, redundant{...} is
372 simply a group that changes the default ACTIONs to something like
373
374 ::
375
376   fail = 1
377   everythingelse = return
378
379 so that when one module fails, we keep trying until we find one that doesn't
380 fail, then return whatever it returned. And at the end, if they all failed,
381 the redundant GROUP as a whole returns RLM_MODULE_FAIL, just as you'd want it
382 to (I hope).
383
384 There are two other kinds of grouping: ``group{...}`` which does not have any
385 specialized default ACTIONs, and ``append{...}``, which should be used when you
386 have separate but similarly structured databases that are guaranteed not to
387 overlap.
388
389 That's all that really needs to be said. But now a few random notes:
390
391 GROUPs may have RESULT=ACTION
392 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
393
394 It would look like this:
395
396 ::
397
398   authorize {
399     preprocess
400     redundant {
401       sql1
402       sql2
403       notfound = return
404     }
405     files
406   }
407
408 which would prevent ``files`` from being called if neither of the SQL
409 instances could find the user.
410
411 redundant{...} and append{...} are just shortcuts
412 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
413
414 You could write:
415
416 ::
417
418     group {
419       sql1 {
420         fail     = 1
421         notfound = 2
422         noop     = return
423         ok       = return
424         updated  = return
425         reject   = return
426         userlock = return
427         invalid  = return
428         handled  = return
429       }
430       sql2 {
431         fail     = 1
432         notfound = 2
433         noop     = return
434         ok       = return
435         updated  = return
436         reject   = return
437         userlock = return
438         invalid  = return
439         handled  = return
440       }
441     }
442   instead of
443     redundant {
444       sql1
445       sql2
446     }
447
448 but the latter is just a whole lot easier to read.
449
450 ``authenticate{...}`` is not a GROUP
451 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
452
453 even though it contains a list of ``Auth-Type`` GROUPs, because its
454 semantics are totally different - it uses ``Auth-Type`` to decide which of
455 its members to call, and their order is irrelevant.
456
457 The default rules are context-sensitive
458 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
459
460 For ``authorize``, the defaults are
461 what you saw above - notfound, noop, ok, and updated are considered
462 success, and anything else has an ACTION of ``return``. For authenticate, the
463 default is to return on success *or* reject, and only try the second and
464 following items if the first one fails. You can read all the default ACTIONs
465 in modcall.c (int defaultactions[][][]), or just trust me. They do the right
466 thing.
467
468 There are some rules that can't be implemented in this language
469 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
470
471 things like ``notfound = 1-reject``, ``noop = 2-ok``, ``ok = 3-ok``, etc. But I don't feel
472 justified adding that complexity in the first draft.
473 There are already enough things here that may never see real-world usage.
474 Like append{...}
475
476 -- Pac. 9/18/2000