nix-config/hosts/containers/radius/freeradius/policy.conf

284 lines
6.3 KiB
Plaintext

# -*- 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}"
}
}
}
}