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.
22 # We check for this prefix to determine whether the class
23 # value was generated by this server. It should be changed
24 # so that it is globally unique.
25 class_value_prefix = 'ai:'
28 # Overload the default acct_unique module, it's not
33 # If we have a class attribute in the format
34 # 'auth_id:[0-9a-f]{32}' it'll have a local value
35 # (defined by insert_acct_class), this ensures
36 # uniqueness and suitability.
38 # We could just use the Class attribute as
39 # Acct-Unique-Session-Id, but this may cause problems
40 # with NAS that carry Class values across between
41 # multiple linked sessions. So we rehash class with
42 # Acct-Session-ID to provide a truely unique session
45 # Using a Class/Session-ID combination is more robust
46 # than using elements in the Accounting-Request,
47 # which may be subject to change, such as
48 # NAS-IP-Address, Client-IP-Address and
49 # NAS-Port-ID/NAS-Port.
51 # This policy should ensure that session data is not
52 # affected if NAS IP addresses change, or the client
53 # roams to a different 'port' whilst maintaining its
54 # initial authentication session (Common in a
55 # wireless environment).
57 if("%{string:Class}" =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
59 Acct-Unique-Session-Id := "%{md5:%{1}%{Acct-Session-ID}}"
64 # Not All devices respect RFC 2865 when dealing with
65 # the class attribute, so be prepared to use the
66 # older style of hashing scheme if a class attribute
71 Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID:}%{NAS-Port}}"
77 # Insert a (hopefully unique) value into class
81 Class = "${policy.class_value_prefix}%{md5:%t%I%{Packet-Src-Port}%{Packet-Src-IP-Address}%{NAS-IP-Address}%{Calling-Station-ID}%{User-Name}}"
86 # Forbid all EAP types. Enable this by putting "forbid_eap"
87 # into the "authorize" section.
96 # Forbid all non-EAP types outside of an EAP tunnel.
100 # We MAY be inside of a TTLS tunnel.
101 # PEAP and EAP-FAST require EAP inside of
102 # the tunnel, so this check is OK.
103 # If so, then there MUST be an outer EAP message.
104 if (!"%{outer.request:EAP-Message}") {
111 # Remove Reply-Message from response if were doing EAP
113 # Be RFC 3579 2.6.5 compliant - EAP-Message and Reply-Message should
114 # not be present in the same response.
116 remove_reply_message_if_eap {
117 if(reply:EAP-Message && reply:Reply-Message) {
128 # Split User-Name in NAI format (RFC 4282) into components
130 # This policy writes the Username and Domain portions of the
131 # NAI into the Stripped-User-Name and Stripped-User-Domain
134 # The regular expression to do this is not strictly compliant
135 # with the standard, but it is not possible to write a
136 # compliant regexp without perl style regular expressions (or
137 # at least not a legible one).
139 nai_regexp = "^([^@]*)(@([-[:alnum:]]+\\.[-[:alnum:].]+))?$"
142 if(User-Name =~ /${policy.nai_regexp}/){
144 Stripped-User-Name := "%{1}"
145 Stripped-User-Domain = "%{3}"
148 # If any of the expansions result in a null
149 # string, the update section may return
150 # something other than updated...
159 # If called in post-proxy we modify the proxy-reply message
161 split_username_nai.post-proxy {
162 if(proxy-reply:User-Name =~ /${policy.nai_regexp}/){
164 Stripped-User-Name := "%{1}"
165 Stripped-User-Domain = "%{3}"
175 # Example of forbidding all attempts to login via
179 if (User-Name =~ /@|\\/) {
185 # If you want the server to pretend that it is dead,
186 # then use the "do_not_respond" policy.
190 Response-Packet-Type := Do-Not-Respond
197 # Filter the username
199 # Force some sanity on User-Name. This helps to avoid issues
200 # issues where the back-end database is "forgiving" about
201 # what constitutes a user name.
204 # spaces at the start: reject
205 if (User-Name =~ /^ /) {
209 # spaces at the end: reject
210 if (User-Name =~ / $$/) {
215 if (User-Name != "%{tolower:%{User-Name}}") {
222 # The following policies are for the Chargeable-User-Identity
223 # (CUI) configuration.
225 # The policies below can be called as just 'cui' (not
226 # cui.authorize etc..) from the various config sections.
230 # The client indicates it can do CUI by sending a CUI attribute
231 # containing one zero byte
235 Chargeable-User-Identity:='\\000'
240 # Add a CUI attribute based on the User-Name, and a secret key
241 # known only to this server.
244 if (FreeRadius-Proxied-To == 127.0.0.1) {
245 if (outer.request:Chargeable-User-Identity) {
247 Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}"
252 if (Chargeable-User-Identity) {
254 Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}"
262 # If we had stored a CUI for the User, add it to the request.
266 # If the CUI isn't in the packet, see if we can find it
269 if (!Chargeable-User-Identity) {
271 Chargable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{Client-IP-Address}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}"
276 # If it exists now, then write out when we last saw
279 if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) {
285 # If there is a CUI attribute in the reply, add it to the DB.
288 if (reply:Chargeable-User-Identity) {
294 # Normalize the MAC Addresses in the Calling/Called-Station-Id
296 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})
299 # Add "rewrite_called_station_id" in the "authorize" and
300 # "preacct" sections.
302 rewrite_called_station_id {
303 if(Called-Station-Id =~ /^${policy.mac-addr-regexp}(:(.+))?$/i) {
305 Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
311 Called-Station-SSID := "%{8}"
322 # Add "rewrite_calling_station_id" in the "authorize" and
323 # "preacct" sections.
325 rewrite_calling_station_id {
326 if(Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i) {
328 Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"