📄 gradient.texi
字号:
@c This is part of the Radius manual.@c Copyright (C) 2004 Free Software Foundation, Inc.@c Written by Sergey Poznyakoff@c See file radius.texi for copying conditions.@comment *******************************************************************@chapter New Configuration Approach (draft)@UNREVISED{}This document presents a draft describing new approach forprocessing @RADIUS{} requests. It is intended as a @dfn{requestfor comments}, and, in the long run, as a guide for GNU Radiusdevelopers. In its current state it is far from being complete.Please check @url{http://www.gnu.org/@/software/@/radius/@/manual} forupdated versions. Feel free to send your comments and suggestions to@email{bug-gnu-radius@@gnu.org}.@menu* Present State:: A brief description of Currently Used Approach* Deficiencies:: Deficiencies of Current Operation Model and Configuration Suite* Solution:: A Proposed Solution* New Rewrite:: Changes to Rewrite Language* Traditional Configuration:: Support for Traditional Configuration Files.* New Configuration:: New Configuration Files@end menu@node Present State@section A brief description of Currently Used ApproachWhen I started to write GNU Radius, back in 1998, I had two major aims.The first and primary aim was to create a flexible and robustsystem that would follow the principle of Jon Postel:@quotationBe liberal in what you accept and conservative in what you send.@end quotationThis, I believe, is the main principle of any good software forInternet.The second aim was to be backward compatible with the implementationsthat already existed back then. This seemed to be important (and thetime has proved it was), because it would allow users to easily switchfrom older radius daemon to GNU Radius.An important part of every complex program is its configurationfile. Traditional implementations of @RADIUS{} servers (beginning fromLivingston Radius) used a configuration suite consisting of severalfiles, usually located in @file{/etc/raddb} subdirectory. Its maincomponents were:@table @file@item dictionaryA file containing translations of symbolic names of radius attributesand attribute values to their integer numbers as specified by@RADIUS{} protocol.@item hintsThis file was intended to separate incoming requests in groups, basedon the form of their login name. Traditionally such separationwas performed basing on common @dfn{prefixes} and/or @dfn{suffixes}of login names.@item huntgroupsThe purpose of this file was to separate incoming requests dependingon their source, i.e. on the @NAS{} that sent them and the portnumber on that @NAS{}. It also served as a sort of simplified@dfn{access control list}. @item usersThis file contained a users database. It described criteria forauthentication and @dfn{reply pairs} to be sent back to requesting@NAS{}es.@end tableAmong these files, the first two were used for requests of any kind,whereas @file{users} was used only for @code{Access-Request} packets.@FIXME-xref{request types}Though this configuration system suffered from many inconsistencies,the @dfn{second aim} required GNU Radius to use this approach.To compensate for its deficiencies and to fulfill the @dfn{first aim},this configuration system was extended, while preserving its mainfunctionality. A number of additional @dfn{internal attributes} wereadded, that control @command{radiusd} behavior. A new language wascreated whose main purpose was to modify incoming requests(@pxref{Rewrite}). The support for @dfn{GNU's Ubiquitous IntelligentLanguage for Extensions} (@pxref{Guile}) was added, that allowed tofurther extend GNU Radius functionality.The present operation model@footnote{@xref{Operation}.} of GNU Radiusand its configuration file system@footnote{@xref{ConfigurationFiles}.} emerged as a result of the two development aims describedabove. Since 1998 up to present, GNU Radius users contributed a lotof ideas and code to the further development of the system.However, it became obvious that this system presentsstrong obstacles to the further development. The next sectionaddresses its deficiencies.@node Deficiencies@section Deficiencies of Current Operation Model and Configuration SuiteThe main deficiencies are inherited with the traditional configurationfile suite. The rules for processing each request are split amongthree files, each of which is processed differently, despite of theirexternal similarity. The administrator has to keep in mind a set ofexotic rules when configuring the system@footnote{@file{Hints} isprocessed for each request... Authentication requests first pass@file{hints}, then @file{huntgroups}, then @file{users}... Accountingrequests use only @file{hints} and @file{huntgroups}...@file{Huntgroups} entries may also be used (sometimes inadvertently) tocreate @acronym{ACL} rules, etc, etc...}. When matching incomingrequests with configuration file entries (@dfn{LHS}, @pxref{MatchingRule}), some attributes are taken verbatim, whereas others are usedto control @command{radiusd} behavior and to pass additional data toother rules (@pxref{Radius Internal Attributes}). The things become evenmore complicated when @RADIUS{} realms come into play (@pxref{ProxyService}). Some attributes are meaningful only if used in a certainpart of a certain configuration file rule.So, while being a lot more flexible than the approach used byother @RADIUS{} implementations, the current system is quitedifficult to maintain.Another deficiency is little control over actions executed ondifferent events. For example, it is often asked how can oneblock a user account after a predefined number of authenticationfailures? Currently this can only be done by writing an externalauthentication procedure (either in Scheme, using Guile, or asa standalone executable, using @attr{Exec-Program-Wait}). Theproper solution would be to have a set of user-defined triggersfor every @RADIUS{} event (in this case, for authentication failure).Another commonly asked question is how to make @command{radiusd}execute several @acronym{SQL} queries when processing a request.While GNU Radius is not supposed to compensate for deficienciesof some @acronym{SQL} implementations that do not allow fornested queries, such a feature could come quite handy.@node Solution@section Proposed Solution@UNREVISED{}Processing of incoming requests is controlled by@dfn{request-processing program}. Request-processing program is alist-like structure, consisting of @dfn{instructions}. @menu* Instruction:: * grad_instr_conditional::* grad_instr_call::* grad_instr_return::* grad_instr_action::* grad_instr_reply::* grad_instr_proxy::* grad_instr_forward::@end menu@node Instruction@subsection Request-processing Instruction@dfn{Request-processing program} consists of @dfn{instructions}. Thereare seven basic instruction types:@table @code@item grad_instr_conditional_tThis instruction marks a branch point within the program.@item grad_instr_call_tRepresents a @dfn{call} of a subprogram@item grad_instr_action_tInvokes a Rewrite @FIXME{or Scheme?} function@item grad_instr_proxy_tProxies a request to the remote server@item grad_instr_forward_tForwards a request to the remote server@item grad_instr_reply_tReplies back to the requesting @NAS{}.@end tableConsequently, an instruction is defined as a union of the above nodetypes:@deftp Instruction grad_instr_t@smallexample@groupenum grad_instr_type@{ grad_instr_conditional, grad_instr_call, grad_instr_return, grad_instr_action, grad_instr_reply, grad_instr_proxy, grad_instr_forward@};typedef struct grad_instr grad_instr_t;struct grad_instr@{ enum grad_instr_type type; grad_instr_t *next; union @{ grad_instr_conditional_t cond; grad_instr_call_t call; grad_instr_action_t action; grad_instr_reply_t reply; grad_instr_proxy_t proxy; grad_instr_forward_t forward; @} v; @};@end group@end smallexample@code{Type} member contains type of the instruction. The evaluatoruses @code{type} to determine which part of @code{union v}, holdsinstruction-specific data.@code{Next} points to the next instruction. The evaluator willgo to this instruction unless the present one changes the controlflow.Finally, @code{v} contains instruction-specific data. These willbe discussed in the following subsections.@end deftp@node grad_instr_conditional@subsection grad_instr_conditional@UNREVISED{}@deftp Instruction grad_instr_conditional_t cond iftrue iffalse@smallexample@groupstruct grad_instr_conditional@{ grad_entry_point_t cond; /* Entry point to the compiled Rewrite condition */ grad_instr_t *iftrue; /* Points to the ``true'' branch */ grad_instr_t *iffalse; /* Points to the ``false'' branch */@};typedef struct grad_instr_conditional grad_instr_conditional_t;@end group@end smallexampleInstructions of type @code{grad_instr_conditional_t} indicate branching.Upon encountering an @code{grad_instr_conditional_t}, theengine executes a Rewrite expression pointed to by @code{cond}.If the expression evaluates to @code{true}, execution branches toinstruction @code{iftrue}. Otherwise, if @code{iffalse} is not @code{NULL},execution branches to that instruction. Otherwise, the control flowpasses to @code{grad_instr_t.next}, as described in the previous section.@end deftp@subheading RPL representation@deffn {RPL defun} COND @var{expr} @var{if-true} [@var{if-false}]@table @var@item exprTextual representation of Rewrite conditional expression or its entrypoint.@item if-trueRPL expression executed if @var{expr} evaluates to @code{t}.@item if-trueOptional RPL expression that is executed if @var{expr} evaluates to@code{nil}.@end table@end deffn@subheading Example@code{COND} with two arguments:@smalllisp@group(COND "%[User-Name] ~= \"test-.*\"" (REPLY Access-Reject ("Reply-Message" . "Test accounts disabled")))@end group @end smalllisp@noindent@code{COND} with three arguments:@smalllisp@group(COND "%[Hint] == "PPP" && authorize(PAM)" (REPLY Access-Accept ("Service-Type" . "Framed-User") ("Framed-Protocol" . "PPP")) (REPLY Access-Reject ("Reply-Message" . "Access Denied")))@end group @end smalllisp@node grad_instr_call@subsection grad_instr_call@UNREVISED{}@deftp Instruction grad_instr_call_t entry@smallexample@groupstruct grad_instr_call @{ grad_instr_t *entry; @};typedef struct grad_instr_call grad_instr_call_t;@end group@end smallexample
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -