PortaOne Radius auth

PortaOne's Radius client for Asterisk


Overview

This GPL project brings RADIUS AAA capabilities to Asterisk PBX.
It is written entirely in Perl, so it is 100% portable and easy to understand and customize!
RADIUS attributes are used as per Cisco VSA Voice Implementation Guide, which provides compatibility with many billing platforms (i.e. PortaBilling100)


You CAN:


Authentication:
  • authenticate users via RADIUS protocol
  • use global RADIUS server settings and individual RADIUS server settings for different extensions
  • authenticate by general "account + password", which can mean anything depending on the service you are willing to implement i.e. ANI authorization, prepaid cards...
  • authenticate SIP users via RADIUS (secure, pass Digest over RADIUS)
  • if "credit time" is provided in radius reply, then call timer will be set and asterisk will disconnect call automatically, or
  • you can process RADIUS reply attribures in extensions.conf in order to create IVR responce
  • accept and decrypt routing information from PortaBilling100, then you can pass resulting string directly to Dial application using this feature you can dial multiply SIP destinations using different user/pass pairs ! (requires path to Dial application)

Accounting:
  • generate Stop RADIUS records for incoming and outgoing call legs

You CAN NOT:

Accounting:
  • generate Start or Alive records, which is doable easily for connected calls, but
  • you can not generate Start - Stop records for failed calls, so you can not monitor your asterisk configuration failures via RADIUS. For instance you may have a dozen of call attempts on some channel failed due to some configuration error. This is limitation of Asterisk architecture and needs some serious work.

Installation


0. Download tarball from PortaOne. Apply patches located in patches/ directory to your asterisk sources (patches were made against asterisk 1.4.11)

1. Install from CPAN

sudo perl -MCPAN -e shell;

install Config::IniFiles
install Crypt::CBC
install Crypt::DES
install Authen::Radius
install Asterisk::AGI


2. Include
load => res_agi.so
into Asterisk's modules.conf

3. Copy agi-rad-auth.pl into asterisk's agi directory, usually /usr/local/share/asterisk/agi-bin (defined in asterisk.conf)

4. Edit manager.conf using the example included, settings must correspond to settings in ast-rad-acc.pl

5. Include ast-rad-acc.pl into system startup sequence

6. Edit extensions.conf using example included

7. Make sure that your Asterisk includes all related bug fixes and patches, namely:
- SIPGetHeaders for chan_sip (derived from chan_sip2 )
- Outbound SIP cnannel DNID bug fix
- Outbound Zap cnannel DNID bug fix
- Manager API DNID bug fix
- Dial application patch Dial(SIP/number:secret:authid@host)
- chan_sip externalauth=yes
- Inbounnd ast_set_callerid chan_zap bug fix
- SIP remote ip for manager API



Configuration Examples


extensions.conf


[globals]
; RADIUS Client Configuration
; This is defaul configuration
;
RADIUS_Server=radius.mydomain.com
RADIUS_Secret=mytest
;
; NAS_IP_Address attribute to send in requests
;
NAS_IP_Address=192.168.0.56

; ANI authentication example
;
[outbound-analog]
; It is possible to use different RADIUS servers in different contexts
; if nothing is defined here then gloval values will be used
;
exten => _X.,1,Set(RADIUS_Server=radius.mydomain.com)
exten => _X.,n,Set(RADIUS_Secret=mytest)
exten => _X.,n,Set(NAS_IP_Address=192.168.0.56)
;
; Set account to authorize by
; It can be a prepaid calling card PIN, ANI, or SIP ID depending on your application
;
exten => _X.,n,Set(CDR(accountcode)=${CALLERID(num)})
exten => _X.,n,NoOp(${CALLERID(num)})
;
; RADIUS Authorize
; Called as:  agi-rad-auth.pl|parametr1=value1&parametr2=value2&parametr3=value3
; Possible parametrs:
; Routing=XXX will will send h323-ivr-out = 'PortaBilling_Routing:XXX' attribure (XXX is usually SIP)
; AuthorizeBy=SIP requires SIPGetHeader(SIP_Authorization=Proxy-Authorization) first + externalauth=yes in sip.conf
; AuthorizeBy=Account requires SetAccount(<username>) first
; Password=Password optional and may be used together with AuthorizeBy=Account
; IfFailed=DoNotHangup optional, used for custome authentication error processing i.e. IVR
;
;
exten => _X.,n,agi,agi-rad-auth.pl|AuthorizeBy=Account&Password=SecReT
;
exten => _X.,n,Dial(Zap/1/${EXTEN},60)
exten => _X.,n,Hangup

; Another example
;
[auth-error-processing]
exten => _X.,1,Set(CDR(accountcode)=${CALLERID(num)})
exten => _X.,n,NoOp(${CALLERID(num)})
exten => _X.,n,agi,agi-rad-auth.pl|AuthorizeBy=Account&IfFailed=DoNotHangup&Password=SecReT
exten => _X.,n,NoOp(${h323-return-code})
;
; You can add your custom IVR response here
;
exten => _X.,n,Dial(Zap/1/${EXTEN},60)
exten => _X.,n,Hangup

; Inbound SIP authentication
;
[sip-auth]
; SIP Authorization headers
;
exten => _X.,1,SIPGetHeader(SIP_Authorization=Proxy-Authorization)
;
; RADIUS Authorize
;
exten => _X.,n,agi,agi-rad-auth.pl|Routing=SIP&AuthorizeBy=SIP
;
; SIP username from Digest is returned in channel variable SIP_Username
; Set correct ACCOUNTCODE for the accounting
;
exten => _X.,n,Set(CDR(accountcode)=${SIP_Username})
;
; Routing information is returned in channel variable Dial_Info
; usually you must execute Dial(${Dial_Info})
; PortaBilling100 routing and authentication information returned as follows:
; SIP/number_to_dial:password:authuser@ip1/SIP/number_to_dial@ip2/
; This is example for two sip routes one with authorization on remote end and another is without
;
exten => _X.,n,NoOp(${Dial_Info})
;
; Number to dial is returned in channel variable DNID
;
exten => _X.,n,NoOp(${DNID})
;
exten => _X.,n,Dial(${Dial_Info})
exten => _X.,n,Hangup


See Also


Other Asterisk development by PortaOne


PortaOne's Radius client for Asterisk


Overview

This GPL project brings RADIUS AAA capabilities to Asterisk PBX.
It is written entirely in Perl, so it is 100% portable and easy to understand and customize!
RADIUS attributes are used as per Cisco VSA Voice Implementation Guide, which provides compatibility with many billing platforms (i.e. PortaBilling100)


You CAN:


Authentication:
  • authenticate users via RADIUS protocol
  • use global RADIUS server settings and individual RADIUS server settings for different extensions
  • authenticate by general "account + password", which can mean anything depending on the service you are willing to implement i.e. ANI authorization, prepaid cards...
  • authenticate SIP users via RADIUS (secure, pass Digest over RADIUS)
  • if "credit time" is provided in radius reply, then call timer will be set and asterisk will disconnect call automatically, or
  • you can process RADIUS reply attribures in extensions.conf in order to create IVR responce
  • accept and decrypt routing information from PortaBilling100, then you can pass resulting string directly to Dial application using this feature you can dial multiply SIP destinations using different user/pass pairs ! (requires path to Dial application)

Accounting:
  • generate Stop RADIUS records for incoming and outgoing call legs

You CAN NOT:

Accounting:
  • generate Start or Alive records, which is doable easily for connected calls, but
  • you can not generate Start - Stop records for failed calls, so you can not monitor your asterisk configuration failures via RADIUS. For instance you may have a dozen of call attempts on some channel failed due to some configuration error. This is limitation of Asterisk architecture and needs some serious work.

Installation


0. Download tarball from PortaOne. Apply patches located in patches/ directory to your asterisk sources (patches were made against asterisk 1.4.11)

1. Install from CPAN

sudo perl -MCPAN -e shell;

install Config::IniFiles
install Crypt::CBC
install Crypt::DES
install Authen::Radius
install Asterisk::AGI


2. Include
load => res_agi.so
into Asterisk's modules.conf

3. Copy agi-rad-auth.pl into asterisk's agi directory, usually /usr/local/share/asterisk/agi-bin (defined in asterisk.conf)

4. Edit manager.conf using the example included, settings must correspond to settings in ast-rad-acc.pl

5. Include ast-rad-acc.pl into system startup sequence

6. Edit extensions.conf using example included

7. Make sure that your Asterisk includes all related bug fixes and patches, namely:
- SIPGetHeaders for chan_sip (derived from chan_sip2 )
- Outbound SIP cnannel DNID bug fix
- Outbound Zap cnannel DNID bug fix
- Manager API DNID bug fix
- Dial application patch Dial(SIP/number:secret:authid@host)
- chan_sip externalauth=yes
- Inbounnd ast_set_callerid chan_zap bug fix
- SIP remote ip for manager API



Configuration Examples


extensions.conf


[globals]
; RADIUS Client Configuration
; This is defaul configuration
;
RADIUS_Server=radius.mydomain.com
RADIUS_Secret=mytest
;
; NAS_IP_Address attribute to send in requests
;
NAS_IP_Address=192.168.0.56

; ANI authentication example
;
[outbound-analog]
; It is possible to use different RADIUS servers in different contexts
; if nothing is defined here then gloval values will be used
;
exten => _X.,1,Set(RADIUS_Server=radius.mydomain.com)
exten => _X.,n,Set(RADIUS_Secret=mytest)
exten => _X.,n,Set(NAS_IP_Address=192.168.0.56)
;
; Set account to authorize by
; It can be a prepaid calling card PIN, ANI, or SIP ID depending on your application
;
exten => _X.,n,Set(CDR(accountcode)=${CALLERID(num)})
exten => _X.,n,NoOp(${CALLERID(num)})
;
; RADIUS Authorize
; Called as:  agi-rad-auth.pl|parametr1=value1&parametr2=value2&parametr3=value3
; Possible parametrs:
; Routing=XXX will will send h323-ivr-out = 'PortaBilling_Routing:XXX' attribure (XXX is usually SIP)
; AuthorizeBy=SIP requires SIPGetHeader(SIP_Authorization=Proxy-Authorization) first + externalauth=yes in sip.conf
; AuthorizeBy=Account requires SetAccount(<username>) first
; Password=Password optional and may be used together with AuthorizeBy=Account
; IfFailed=DoNotHangup optional, used for custome authentication error processing i.e. IVR
;
;
exten => _X.,n,agi,agi-rad-auth.pl|AuthorizeBy=Account&Password=SecReT
;
exten => _X.,n,Dial(Zap/1/${EXTEN},60)
exten => _X.,n,Hangup

; Another example
;
[auth-error-processing]
exten => _X.,1,Set(CDR(accountcode)=${CALLERID(num)})
exten => _X.,n,NoOp(${CALLERID(num)})
exten => _X.,n,agi,agi-rad-auth.pl|AuthorizeBy=Account&IfFailed=DoNotHangup&Password=SecReT
exten => _X.,n,NoOp(${h323-return-code})
;
; You can add your custom IVR response here
;
exten => _X.,n,Dial(Zap/1/${EXTEN},60)
exten => _X.,n,Hangup

; Inbound SIP authentication
;
[sip-auth]
; SIP Authorization headers
;
exten => _X.,1,SIPGetHeader(SIP_Authorization=Proxy-Authorization)
;
; RADIUS Authorize
;
exten => _X.,n,agi,agi-rad-auth.pl|Routing=SIP&AuthorizeBy=SIP
;
; SIP username from Digest is returned in channel variable SIP_Username
; Set correct ACCOUNTCODE for the accounting
;
exten => _X.,n,Set(CDR(accountcode)=${SIP_Username})
;
; Routing information is returned in channel variable Dial_Info
; usually you must execute Dial(${Dial_Info})
; PortaBilling100 routing and authentication information returned as follows:
; SIP/number_to_dial:password:authuser@ip1/SIP/number_to_dial@ip2/
; This is example for two sip routes one with authorization on remote end and another is without
;
exten => _X.,n,NoOp(${Dial_Info})
;
; Number to dial is returned in channel variable DNID
;
exten => _X.,n,NoOp(${DNID})
;
exten => _X.,n,Dial(${Dial_Info})
exten => _X.,n,Hangup


See Also


Other Asterisk development by PortaOne


Created by: gonzo, Last modification: Thu 04 of Nov, 2010 (05:44 UTC) by admin
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+