3 ## policy.conf -- FreeRADIUS server configuration file.
5 ## http://www.freeradius.org/
10 # Policies are virtual modules, similar to those defined in the
11 # "instantate" section of radiusd.conf.
13 # Defining a policy here means that it can be referenced in multiple
14 # places as a *name*, rather than as a series of conditions to match,
15 # and actions to take.
17 # Policies are something like subroutines in a normal language, but
18 # they cannot be called recursively. They MUST be defined in order.
19 # If policy A calls policy B, then B MUST be defined before A.
23 # Overload the default acct_unique module, it's not smart enough
27 # If we have a class attribute in the format 'auth_id:[0-9a-f]{32}' it'll have a local
28 # value (defined by insert_acct_class), this ensures uniquenes and suitability.
30 # We could just use the Class attribute as Acct-Unique-Session-Id, but this may cause
31 # problems with NAS that carry Class values across between multiple linked sessions.
32 # So we rehash class with Acct-Session-ID to provide a truely unique session identifier.
34 # Using a Class/Session-ID combination is more robust than using elements in the
35 # Accounting-Request, which may be subject to change, such as NAS-IP-Address,
36 # Client-IP-Address and NAS-Port-ID/NAS-Port.
38 # This policy should ensure that session data is not affected if NAS IP addresses change,
39 # or the client roams to a different 'port' whilst maintaining its initial authentication
40 # session (Common in a wireless environment).
42 if("%{string:Class}" =~ /auth_id:([0-9a-f]{32})/i) {
44 Acct-Unique-Session-Id := "%{md5:%{1}%{Acct-Session-ID}}"
48 # Not All devices respect RFC 2865 when dealing with the class attribute,
49 # so be prepared to use the older style of hashing scheme if a class attribute is not included
53 Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID:}%{NAS-Port}}"
59 # Insert a (hopefully unique) value into class
63 Class = "auth_id:%{md5:%t%{request:NAS-Identifier}%{NAS-Port-ID}%{NAS-Port}%{Calling-Station-ID}%{reply:User-Name}}"
68 # Forbid all EAP types.
77 # Forbid all non-EAP types outside of an EAP tunnel.
81 # We MAY be inside of a TTLS tunnel.
82 # PEAP and EAP-FAST require EAP inside of
83 # the tunnel, so this check is OK.
84 # If so, then there MUST be an outer EAP message.
85 if (!"%{outer.request:EAP-Message}") {
92 # Remove Reply-Message from response if were doing EAP
94 # Be RFC 3579 2.6.5 compliant - EAP-Message and Reply-Message should
95 # not be present in the same response.
97 remove_reply_message_if_eap {
98 if(reply:EAP-Message && reply:Reply-Message) {
109 # Split User-Name in NAI format (RFC 4282) into components
111 # This policy writes the Username and Domain portions of the NAI into the
112 # Stripped-User-Name and Stripped-User-Domain attributes.
114 # The regular expression to do this is not strictly compliant with the standard,
115 # but it is not possible to write a compliant regexp without perl style
116 # regular expressions (or at least not a legible one).
119 if(User-Name =~ /^([^@]*)(@([-[:alnum:]]+\\.[-[:alnum:].]+))?$/){
121 Stripped-User-Name := "%{1}"
122 Stripped-User-Domain = "%{3}"
124 # If any of the expansions result in a null string, the update
125 # section may return something other than updated...
134 # Forbid all attempts to login via realms.
137 if (User-Name =~ /@|\\/) {
143 # If you want the server to pretend that it is dead,
144 # then use the "do_not_respond" policy.
148 Response-Packet-Type := Do-Not-Respond
155 # Filter the username
157 # Force some sanity on User-Name. This helps to avoid issues
158 # issues where the back-end database is "forgiving" about
159 # what constitutes a user name.
162 # spaces at the start: reject
163 if (User-Name =~ /^ /) {
167 # spaces at the end: reject
168 if (User-Name =~ / $$/) {
173 if (User-Name != "%{tolower:%{User-Name}}") {
180 # The following policies are for the Chargeable-User-Identity
181 # (CUI) configuration.
183 # The policies below can be called as just 'cui' (not cui.authorize etc..)
184 # from the various config sections.
188 # The client indicates it can do CUI by sending a CUI attribute
189 # containing one zero byte
193 Chargeable-User-Identity:='\\000'
198 # Add a CUI attribute based on the User-Name, and a secret key
199 # known only to this server.
202 if (FreeRadius-Proxied-To == 127.0.0.1) {
203 if (outer.request:Chargeable-User-Identity) {
205 Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}"
210 if (Chargeable-User-Identity) {
212 Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}"
220 # If we had stored a CUI for the User, add it to the request.
224 # If the CUI isn't in the packet, see if we can find it
227 if (!Chargeable-User-Identity) {
229 Chargable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{Client-IP-Address}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}"
234 # If it exists now, then write out when we last saw
237 if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) {
243 # If there is a CUI attribute in the reply, add it to the DB.
246 if (reply:Chargeable-User-Identity) {
252 # Normalize the MAC Addresses in the Calling/Called-Station-Id
254 mac-addr-regexp = ([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})
257 # Add "rewrite_called_station_id" in the "authorize" and "preacct" sections.
259 rewrite_called_station_id {
260 if(Called-Station-Id =~ /^%{config:policy.mac-addr-regexp}(:(.+))?$/i) {
262 Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
268 Called-Station-SSID := "%{7}"
279 # Add "rewrite_calling_station_id" in the "authorize" and "preacct" sections.
281 rewrite_calling_station_id {
282 if(Calling-Station-Id =~ /^%{config:policy.mac-addr-regexp}$/i) {
284 Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"