📄 extensions.texi
字号:
@c This is part of the Radius manual.@c Copyright (C) 1999,2000,2001,2002,2003 Free Software Foundation, Inc.@c Written by Sergey Poznyakoff@c See file radius.texi for copying conditions.@comment *******************************************************************@node Extensions, Utility Programs, Problem Tracking, Top@chapter Extensions@cindex ExtensionsThe use of extension language allows extending the functionality ofGNU Radius without having to modify its source code. The two extensionlanguages supported are Rewrite and Scheme. Use of Rewrite is alwaysenabled. Use of Scheme requires Guile version 1.4 or higher.@menu* Filters:: Using external filter programs.* Rewrite:: The built-in extension language.* Guile:: Using Scheme. @end menu@comment *L1****************************************************************@node Filters@section Filters@cindex FiltersThe simplest way to extend the functionality of Radius is to use filters.A filter is an external program that communicates with Radius viaits standard input and output channels.@menu* Getting Acquainted with Filters::* Declaring the Filter::* Invoking the Filter from a User Profile::* Adding Reply Attributes::* Accounting Filters::* Invoking Accounting Filter::@end menu@node Getting Acquainted with Filters@subsection Getting Acquainted with FiltersSuppose we wish to implement an authentication method based on theuser name and the user's calling station @acronym{ID}. We have adatabase of user names with valid @acronym{ID}s, and the newmethod should authenticate a user only if the combination@{@var{user_name}, @var{id}@} is found in this database.We write a filter program that reads its standard input line by line.Each input line must consist of exactly two words: the user nameand the calling station @acronym{ID}. For each input line, theprogram prints @code{0} if the @{@var{user_name}, @var{id}@} is found in thedatabase and @code{1} otherwise. Let's suppose for the sake of examplethat the database is a plaintext file and the filter is written ina shell programming language. Then it will look like@smallexample#! /bin/shDB=/var/db/userlistwhile read NAME CLIDdo if grep "$1:$2" $DB; then echo "0" else echo "1" fidone@end smallexample@node Declaring the Filter@subsection Declaring the FilterHere is how this filter is declared in the @file{raddb/config} file:@smallexamplefilters @{ filter check_clid @{ exec-path "/usr/libexec/myfilter"; error-log "myfilter.log"; auth @{ input-format "%C@{User-Name@} %C@{Calling-Station-Id@}"; wait-reply yes; @}; @}; @}; @end smallexample Let's analyze this declaration line by line:@enumerate@item @code{filters @{}This keyword opens the filters declaration block. The block maycontain several declarations.@item @code{filter check_clid @{}This line starts the declaration of this particular filter and names it@samp{check_clid}.@item @code{exec-path "/usr/libexec/myfilter";}This line tells @command{radiusd} where to find the executable image ofthis filter.@item @code{error-log "myfilter.log";}The diagnostic output from this filter must be redirected to the file@file{myfilter.log} in the current logging directory@item @code{auth @{}This filter will process authentication requests.@item @code{input-format "%C@{User-Name@} %C@{Calling-Station-Id@}";}Define the input line format for this filter. The %C@{@} expressionswill be replaced by the values of the corresponding attributes fromthe incoming request (@pxref{Macro Substitution}).@item @code{wait-reply yes;}@code{radiusd} will wait for the reply from this filter to decide whether toauthenticate the user. @end enumerate @node Invoking the Filter from a User Profile@subsection Invoking the Filter from a User ProfileTo invoke this filter from the user profile, specify its name prefixedwith @samp{|} in the value of @attr{Exec-Program-Wait} attribute,like this:@smallexampleDEFAULT Auth-Type = System, Simultaneous-Use = 1 Exec-Program-Wait = "|check_clid"@end smallexample@node Adding Reply Attributes@subsection Adding Reply AttributesApart from simply deciding whether to authenticate a user, the filtercan also modify the reply pairs. @smallexample#! /bin/shDB=/var/db/userlistwhile read NAME CLIDdo if grep "$1:$2" $DB; then echo "0 Service-Type = Login, Session-Timeout = 1200" else echo "1 Reply-Message = \"You are not authorized to log in\"" fidone@end smallexample@node Accounting Filters@subsection Accounting FiltersLet's suppose we further modify our filter to also handle accounting requests. To discern between the authentication andaccounting requests we'll prefix each authentication requestwith the word @samp{auth} and each accounting request withthe word @samp{acct}. Furthermore, the input line for accountingrequests will contain a timestamp.Now, our filter program will look as follows:@smallexample#! /bin/shAUTH_DB=/var/db/userlistACCT_DB=/var/db/acct.dbwhile read CODE NAME CLID DATEdo case CODE auth) if grep "$1:$2" $DB; then echo "0 Service-Type = Login, \ Session-Timeout = 1200" else echo "1 Reply-Message = \ \"You are not authorized to log in\"" fi acct) echo "$CODE $NAME $CLID $DATE" >> $ACCT_DBdone@end smallexampleIts declaration in the @file{raddb/config} will also change:@smallexamplefilter check_clid @{ exec-path "/usr/libexec/myfilter"; error-log "myfilter.log"; auth @{ input-format "auth %C@{User-Name@} %C@{Calling-Station-Id@}"; wait-reply yes; @}; acct @{ input-format "acct %C@{User-Name@} %C@{Calling-Station-Id@} %D"; wait-reply no; @};@}; @end smallexample@noindent(The @code{input-format} lines are split for readability. Each of themis actually one line).@emph{Notice} @code{wait-reply no} in the @code{acct} statement. Ittells @command{radiusd} that it shouldn't wait for the response onaccounting requests from the filter. @node Invoking Accounting Filter@subsection Invoking the Accounting FilterTo invoke the accounting filter, specify its name prefixed with avertical bar character as a value of @attr{Acct-Ext-Program} in our@file{raddb/hints} file. For example:@smallexampleDEFAULT NULL Acct-Ext-Program = "|check_clid:@end smallexample @comment *L1****************************************************************@node Rewrite@section Rewrite@cindex RewriteRewrite is the GNU Radius extension language. Its name reflects thefact that it was originally designed to rewrite the broken request packetsso they could be processed as usual (@pxref{Rewriting IncomingRequests}). Beside this basic use, however, Rewrite functions are usedto control various aspects of GNU Radius functionality, such asverifying the activity of user sessions, controlling the amount ofinformation displayed in log messages, etc (@pxref{Interaction with Radius}).@menu* Syntax Overview::* Quick Start::* Interaction with Radius::* Rewriting Incoming Requests::* Login Verification Functions::* Attribute Creation Functions::* Logging Hook Functions::* Full Syntax Description::@end menu@comment *L2****************************************************************@node Syntax Overview@subsection Syntax Overview@cindex Rewrite, syntax overviewThe syntax of Rewrite resembles that of C. Rewrite has two basic data types:integer and string. It does not have global variables; all variables areautomatic. The only exceptions are the @AVP{}s from the incoming request,which are accessible to Rewrite functions via the special notation@code{%[@var{attr}]}. @comment *L2****************************************************************@node Quick Start@subsection Quick Start@cindex Rewrite, quick start introductionAs an example, let's consider the following Rewrite function:@smallexample@groupstringfoo(integer i)@{ string rc; if (i % 2) rc = "odd"; else rc = "even"; return "the number is " + rc;@}@end group@end smallexample@noindentThe function takes an integer argument and returns the string@samp{the number is odd} or @samp{the number is even}, depending on thevalue of @code{i}. This illustrates the fact that in Rewrite theaddition operator is defined on the string type. The result ofsuch operation is the concatenation of operands.Another example is a function that adds a prefix to the @attr{User-Name}attribute:@smallexample@groupintegerpx_add()@{ %[User-Name] = "pfx-" + %[User-Name]; return 0;@}@end group@end smallexample@noindentThis function manipulates the contents of the incoming request; itsreturn value has no special meaning.@comment *L2****************************************************************@node Interaction with Radius@subsection Interaction with Radius@cindex Rewrite, usage@cindex Rewrite, applying functionsA Rewrite function can be invoked in several ways, depending on itspurpose. There are three major kinds of Rewrite functions:@itemize @bullet@item Functions used to rewrite the incoming requests.@item Functions designed for simultaneous login verification.@item Functions used to generate Radius attribute values.@item Logging hooks.@end itemize@comment *L3****************************************************************@node Rewriting Incoming Requests@subsection Rewriting Incoming Requests@cindex Rewriting incoming requestsThe need for rewriting the incoming requests arises from the fact thatsome @NAS{}es are very particular about the information they send withthe requests. There are cases when the information they sendis hardly usable or even completely unusable. For example, aCisco @sc{as5300} terminal server used as a voice-over IP router packsa lot of information into its @attr{Acct-Session-Id} attribute. Thoughthe information stored there is otherwise relevant, it makes properaccounting impossible, since the @attr{Acct-Session-Id} attributesin the start and stop packets of the same session become different, andthus Radius cannot determine the session start to which the givensession stop request corresponds (@pxref{Acct-Session-Id}).In order to cope with such @NAS{}es, GNU Radius is able to invokea Rewrite function upon arrival of the packet and before processing it further. This function can transform the packet so thatit obtains the form prescribed by @sc{rfc}s and its further processingbecomes possible.For example, in the case of the @sc{as5300} router, a corresponding Rewritefunction parses the @attr{Acct-Session-Id} attribute; breaks itdown into fields; stores them into proper attributes, creatingthem if necessary; and finally replaces @attr{Acct-Session-Id} withits real value, which is the same for the start and stop recordscorresponding to a single session. Thus all the information thatcame with the packet is preserved, but the packet itself is madeusable for proper accounting.A special attribute, @attr{Rewrite-Function}, is used to triggerinvocation of a Rewrite function. Its value is a name of thefunction to be invoked.When used in a @file{naslist} profile, the attribute causes the functionto be invoked when the incoming request matches the huntgroup(@pxref{Huntgroups}). For example, to have a function @code{fixup}invoked for each packet from the @NAS{} @code{10.10.10.11}, thefollowing huntgroup rule may be used:@smallexample@groupDEFAULT NAS-IP-Address = 11.10.10.11 Rewrite-Function = "fixup"@end group@end smallexampleThe @attr{Rewrite-Function} attribute may also be used in a @file{hints}rule. In this case, it will invoke the function if the request matchesthe rule (@pxref{Hints}). For example, this @file{hints} rule willcause the function to be invoked for each request containing the user namestarting with @samp{P}:@smallexample@groupDEFAULT Prefix = "P" Rewrite-Function = "fixup"@end group@end smallexample@noindentNote that in both cases the attribute can be usedeither in @LHS{} or in @RHS{} pairs of a rule.The packet rewrite function must be declared as having no argumentsand returning an integer value:@smallexample@groupinteger fixup()@{@}@end group@end smallexample@noindentThe actual return value from such a function is ignored, the integerreturn type is just a matter of convention.The following subsection present some examples of packet rewritefunctions.@menu* Example: Rewrite Examples.@end menu@comment **L3***************************************************************@node Rewrite Examples@subsubsection Examples of Various Rewrite Functions@exindex Rewrite functionsThe examples found in this chapter are working functions that can beused with various existing @NAS{} types. They are taken from the@file{rewrite} file contained in distribution of GNU Radius.@subheading 1. Port rewriting for @sc{max a}scend terminal serversSome @sc{max a}scend terminal servers pack additional informationinto the @attr{NAS-Port-Id} attribute. The port number is constructed as@var{XYYZZ}, where @var{X} = 1 for digital, @var{X} = 2 for analog,@var{YY} is the line number(1 for first PRI/T1/E1, 2 for second, and so on), and @var{ZZ} is thechannel number(on the PRI or channelized T1/E1).The following rewrite functions are intended to compute the integerport number in the range (1 .. @var{portcnt}), where @var{portcnt}represents the real number of physical ports available on the @NAS{}.Such a port number can be used, for example, to create a dynamic poolof IP addresses (@pxref{Framed-IP-Address}).@smallexample@group/* * decode MAX port number * input: P -- The value of NAS-Port-Id attribute * portcnt -- number of physical ports on the NAS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -