# -*- text -*- ## ## policy.conf -- FreeRADIUS server configuration file. ## ## http://www.freeradius.org/ ## $Id: 2668b29e3eee8eb9bfb9fbe33a6752314ac49632 $ ## # # Policies are virtual modules, similar to those defined in the # "instantate" section of radiusd.conf. # # Defining a policy here means that it can be referenced in multiple # places as a *name*, rather than as a series of conditions to match, # and actions to take. # # Policies are something like subroutines in a normal language, but # they cannot be called recursively. They MUST be defined in order. # If policy A calls policy B, then B MUST be defined before A. # policy { # # Forbid all EAP types. # forbid_eap { if (EAP-Message) { reject } } # # Forbid all non-EAP types outside of an EAP tunnel. # permit_only_eap { if (!EAP-Message) { # We MAY be inside of a TTLS tunnel. # PEAP and EAP-FAST require EAP inside of # the tunnel, so this check is OK. # If so, then there MUST be an outer EAP message. if (!"%{outer.request:EAP-Message}") { reject } } } # # Forbid all attempts to login via realms. # deny_realms { if (User-Name =~ /@|\\/) { reject } } # # If you want the server to pretend that it is dead, # then use the "do_not_respond" policy. # do_not_respond { update control { Response-Packet-Type := Do-Not-Respond } handled } # # Force some sanity on User-Name. This helps to avoid issues # issues where the back-end database is "forgiving" about # what constitutes a user name. # filter_username { # # reject mixed case # e.g. "UseRNaMe" # if (User-Name != "%{tolower:%{User-Name}}") { reject } # # reject all whitespace # e.g. "user@ site.com", or "us er", or " user", or "user " # if (User-Name =~ / /) { update reply { Reply-Message += "Rejected: Username contains whitespace" } reject } # # reject Multiple @'s # e.g. "user@site.com@site.com" # if(User-Name =~ /@.*@/ ) { update reply { Reply-Message += "Rejected: Multiple @ in username" } reject } # # reject double dots # e.g. "user@site..com" # if (User-Name =~ /\\.\\./ ) { update reply { Reply-Message += "Rejected: Username comtains ..s" } reject } # # must have at least 1 string-dot-string after @ # e.g. "user@site.com" # if (User-Name !~ /@(.+)\\.(.+)$/) { update reply { Reply-Message += "Rejected: Realm does not have at least one dot seperator" } reject } # # Realm ends with a dot # e.g. "user@site.com." # if (User-Name =~ /\\.$/) { update reply { Reply-Message += "Rejected: Realm ends with a dot" } reject } # # Realm begins with a dot # e.g. "user@.site.com" # if (User-Name =~ /@\\./) { update reply { Reply-Message += "Rejected: Realm begins with a dot" } reject } } # # The following policies are for the Chargeable-User-Identity # (CUI) configuration. # # # The client indicates it can do CUI by sending a CUI attribute # containing one zero byte # cui_authorize { update request { Chargeable-User-Identity:='\\000' } } # # Add a CUI attribute based on the User-Name, and a secret key # known only to this server. # cui_postauth { if (FreeRadius-Proxied-To == 127.0.0.1) { if (outer.request:Chargeable-User-Identity) { update outer.reply { Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}" } } } else { if (Chargeable-User-Identity) { update reply { Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}" } } } } # # If there is a CUI attribute in the reply, add it to the DB. # cui_updatedb { if (reply:Chargeable-User-Identity) { cui } } # # If we had stored a CUI for the User, add it to the request. # cui_accounting { # # If the CUI isn't in the packet, see if we can find it # in the DB. # if (!Chargeable-User-Identity) { update request { Chargeable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{Client-IP-Address}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}" } } # # If it exists now, then write out when we last saw # this CUI. # if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) { cui } } # # Normalize the MAC Addresses in the Calling/Called-Station-Id # mac-addr = ([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}) # Add "rewrite.called_station_id" in the "authorize" and "preacct" # sections. rewrite.called_station_id { if((Called-Station-Id) && "%{Called-Station-Id}" =~ /^%{config:policy.mac-addr}(:(.+))?$/i) { update request { Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}" } # SSID component? if ("%{8}") { update request { Called-Station-Id := "%{Called-Station-Id}:%{8}" } } updated } else { noop } } # Add "rewrite.calling_station_id" in the "authorize" and "preacct" # sections. rewrite.calling_station_id { if((Calling-Station-Id) && "%{Calling-Station-Id}" =~ /^%{config:policy.mac-addr}$/i) { update request { Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}" } updated } else { noop } } # Assign compatibility data to request for sqlippool dhcp_sqlippool.post-auth { # Do some minor hacks to the request so that it looks # like a RADIUS request to the SQL IP Pool module. update request { User-Name = "DHCP-%{DHCP-Client-Hardware-Address}" Calling-Station-Id = "%{DHCP-Client-Hardware-Address}" NAS-IP-Address = "%{%{DHCP-Gateway-IP-Address}:-127.0.0.1}" Acct-Status-Type = Start } # Call the actual module # # Uncomment this in order to really call it! # dhcp_sqlippool fail # Convert Framed-IP-Address to DHCP, but only if we # actually allocated an address. if (ok) { update reply { DHCP-Your-IP-Address = "%{reply:Framed-IP-Address}" } } } }