#  -*- text -*-
#  $Id: cb6ae15fc4c649942f8fead390ecbc1b1e463773 $

#######################################################################
#
#  = The default Virtual Server
#
#  The `default` virtual server is the first one that is enabled on a
#  default installation of FreeRADIUS.  This configuration is
#  designed to work in the widest possible set of circumstances, with
#  the widest possible number of authentication methods.  This means
#  that in general, you should need to make very few changes to this
#  file.
#
#  The usual approach is as follows:
#
#  * configure users in a database (e.g. the `files` module, or in
#    `sql`)
#  * configure the relevant module to talk to the database
#    (e.g. `sql`)
#  * If using EAP / 802.1X, configure the certificates in
#    the `certs/` directory.
#
#  Then, run the server.  This process will ensure that users can log
#  in via PAP, CHAP, MS-CHAP, etc.  You should so test the server via
#  `radtest` to verify that it works.
#
#  ## Editing this file
#
#  Please read "man radiusd" before editing this file.  See the
#  section titled DEBUGGING.  It outlines a method where you can
#  quickly obtain the configuration you want, without running into
#  trouble.  See also "man unlang", which documents the format of this
#  file.  And finally, the debug output can be complex. Please read
#  https://wiki.freeradius.org/radiusd-X to understand that output.
#
#  The best way to configure the server for your local system is to
#  *carefully* edit this file.  Most attempts to make large edits to
#  this file will *break the server*.  Any edits should be small, and
#  tested by running the server with `radiusd -X`.  Once the edits
#  have been verified to work, save a copy of these configuration
#  files somewhere.  We recommend using a revision control system such
#  as `git`, or even a "tar" file.  Then, make more edits, and test,
#  as above.
#
#  There are many "commented out" references to modules and
#  configurations These references serve as place-holders, and as
#  documentation.  If you need the functionality of that module, then:
#
#  * configure the module in `mods-available/`
#  * enable the module in `mods-enabled`.  e.g. for LDAP, do:  `cd mods-enabled;ln -s ../mods-available/ldap`
#  *  uncomment the references to it in this file.
#
#  In most cases, those small changes will result in the server being
#  able to connect to the database, and to authenticate users.
#

#
#  ## The Virtual Server
#
#  This is the `default` virtual server.
#
server default {
	#
	#  namespace:: The protocol namespace (i.e. dictionary) to use.
	#
	#  In v4, all "server" sections MUST start with a "namespace"
	#  parameter.  This tells the server which protocol is being used.
	#
	#  All of the "listen" sections in this virtual server will
	#  only accept packets for that protocol.
	#
	namespace = radius

	#
	#  log:: The name of the logging section to use.
	#
	#  The top configuration section can contain multiple section "log foo { ... }".
	#  Each of those sections is a different named logging destination.
	#
	#  This configuration item allows setting a different logging destination for an
	#  individual virtual server.
	#
	#  There are some limitations.
	#
	#  * this logging is in _addition_ to the default logging to "log { .... }".
	#  * it is not currently possible to _replace_ the default logging destination
	#  * the name given here _must_ be a fixed string, and is not dynamically expanded.
	#
#	log = some_other_logging_destination

	#
	#  ### RADIUS Configuration
	#
	#  All of the configuration for processing RADIUS packets goes here.
	#
	radius {
		#
		#  #### Access-Request subsection
		#
		#  This section contains configuration which is
		#  specific to processing `Access-Request` packets.
		#
		#  Similar sections can be added, but are not
		#  necessary for Accounting-Request (and other)
		#  packets.  At this time, there is no configuration
		#  needed for other packet types.
		#
		Access-Request {
			#
			#  session:: Controls how ongoing
			#  (multi-round) sessions are handled
			#
			#  This section is primarily useful for EAP.
			#  It controls the number of EAP
			#  authentication attempts that can occur
			#  concurrently.
			#
			session {
				#
				#  max:: The maximum number of ongoing sessions
				#
#				max = 4096

				#
				#  timeout:: How long to wait before expiring a
				#  session.
				#
				#  The timer starts when a response
				#  with a state value is sent.  The
				#  timer stops when a request
				#  containing the previously sent
				#  state value is received.
				#
#				timeout = 15
			}
		}

		#
		#  There is currently no configuration for other packet types.
		#
	}

	#
	#  ### Local Dictionaries
	#
	#  It is now possible to have dictionaries which are local to a virtual
	#  server.  The attributes defined here can be used in policies in this
	#  virtual server.
	#
	#  Any attribute defined in this section can only be used in policies in
	#  this virtual server.  The attributes are "internal", and cannot go
	#  into a packet which is sent on the network.
	#
	#  When a request is proxied internally to another virtual server, these
	#  attributes are still sent with the proxied request.  However, as the
	#  definitions do not exist in the other virtual server, they cannot be
	#  used in policies.
	#
	#  The other virtual server can even define attributes of the same name.
	#  That virtual server will use those definitions for its policies, and
	#  will never match the proxied attributes.
	#
	#  In all other aspects, the attributes defined here are just the same
	#  as if they had been assigned in a dictionary file.
	#
	dictionary {
		#
		#  The syntax is _<type>_ followed by _<name>_.
		#
		#  The _<type>_ MUST be a leaf type or a `group`.  i.e. not
		#  `struct`, `vsa`, or `vendor`.
		#
		#  The _<name>_ MUST NOT exist in the `namespace` dictionary.
		#
#		uint32 foo

		#
		#  tlv:: Define a TLV variable using _tlv <name> { ...}_.
		#
		#  The contents of the `tlv` subsection are more variable
		#  definitions, including child `tlv`s.
		#
#		tlv bar {
#		    uint32 baz
#		    string arg
#		}

		#
		#  values:: Define a set of values for attribute _<name>_.
		#
		#  The contents of the `values` section are a list of names and
		#  values.
		#
#		values foo {
			#
			#  _<name>_ = _<value>_
			#
			#  The _<name>_ must be unique.
			#
			#  The _<value>_ is parsed according to the data type of
			#  the attribute.
			#
#			bar = 1
#			baz = 2
#		}
	}


	#
	#  ### The listen section
	#
	#  The `listen` sections in v4 are very different from the
	#  `listen sections in v3.  The changes were necessary in
	#  order to make FreeRADIUS more flexible, and to make the
	#  configuration simpler and more consistent.
	#
	listen {
		#
		#  type:: The type of packet to accept.
		#
		#  Multiple types can be accepted by using multiple
		#  lines of `type = ...`.
		#
		#  This change from v3 makes it much clearer what kind
		#  of packet is being accepted.  The old `auth+acct`
		#  configuration was awkward and potentially
		#  confusing.
		#
		type = Access-Request
		type = Status-Server

		#
		#  transport:: The transport protocol.
		#
		#  The allowed transports for RADIUS are currently
		#  `udp` and `tcp`.  A `listen` section can only have
		#  one `transport` defined.  For multiple transports,
		#  use multiple `listen` sections.
		#
		#  You can have a "headless" server by commenting out
		#  the "transport" configuration.  A "headless" server
		#  will process packets from other virtual servers,
		#  but will not accept packets from the network.
		#
		#  The `inner-tunnel` server is an example of a
		#  headless server.  It accepts packets from the
		#  "inner tunnel" portion of PEAP and TTLS.  But it
		#  does not accept those packets from the network.
		#
		transport = udp

		#
		#  require_message_authenticator::Require Message-Authenticator
		#  in Access-Requests.
		#
		#  RFC 5080 suggests that all clients *should* include it in an
		#  Access-Request. The configuration item below allows the server
		#  to require it. If a client is required to include a `Message-Authenticator`
		#  and it does not, then the packet will be silently discarded.
		#
		#  If value is auto, then if any packet received from the client
		#  contains a valid Message-Authenticator attribute, then the server
		#  will require it from all future packets from that client.
		#
		#  Allowed values: yes, no, auto
		#
		#  The default is "no".
		#
		require_message_authenticator = auto

		#
		#  limit_proxy_state:: Control whether Proxy-State is allowed in
		#  packets from this client which do not have a Message-Authenticator.
		#
		#  The blastradius prefix attack allows an attacker to manipulate
		#  the contents of response packets without knowing the shared secret.
		#
		#  The attack relies on controlling a portion of the data sent back
		#  in the response by the RADIUS server. As Proxy-State is always
		#  echoed back verbatim from the request, it can be leveraged to
		#  manipulate the data sent back from the server and facilitate the
		#  attack.
		#
		#  The attack also relies on defficiencies in the original RADIUS
		#  standards that provided no integrity protection for Access-Requests.
		#
		#  The attack is mitigated by requiring the Message-Authenticator,
		#  which contains a HMAC over the entire request, preventing
		#  modification of the request by the attacker.
		#
		#  If value is auto, and the first packet received from the client
		#  does not contain a Proxy-State attribute, Proxy-State will be
		#  disallowed in any future packets which do not contain a
		#  Message-Authenticator.
		#
		#  This provides some level of protection against the blastradius
		#  attack, without requiring Message-Authenticator, or breaking
		#  existing deployments.
		#
		#  Allowed values: yes, no, auto
		#
		#  The default is "auto".
		#
		limit_proxy_state = auto

		#
		#  limit:: limits for this socket.
		#
		#  The `limit` section contains configuration items
		#  which enforce various limits on the socket.  These
		#  limits are usually transport-specific.
		#
		#  Limits are used to prevent "run-away" problems.
		#
		limit {
			#
			#  max_clients:: The maximum number of dynamic
			#  clients which can be defined for this
			#  listener.
			#
			#  If dynamic clients are not used, then this
			#  configuration item is ignored.
			#
			#  The special value of `0` means "no limit".
			#  We do not recommend using `0`, as attackers
			#  could forge packets from the entire
			#  Internet, and cause FreeRADIUS to run out
			#  of memory.
			#
			#  This configuration item should be set to
			#  the number of individual RADIUS clients
			#  (e.g. NAS, AP, etc.) which will be sending
			#  packets to FreeRADIUS.
			#
			max_clients = 256

			#
			#  max_connections:: The maximum number of
			#  connected sockets which will be accepted
			#  for this listener.
			#
			#  Each connection opens a new socket, so be
			#  aware of system file descriptor
			#  limitations.
			#
			#  If the listeners do not use connected
			#  sockets (e.g. TCP), then this configuration
			#  item is ignored.
			#
			max_connections = 256

			#
			#  idle_timeout:: Time after which idle
			#  connections or dynamic clients are deleted.
			#
			#  Useful range of values: 5 to 600
			#
			idle_timeout = 60.0

			#
			#  nak_lifetime:: Time for which blocked
			#  clients are placed into a NAK cache.
			#
			#  If a dynamic client is disallowed, it is
			#  placed onto a "NAK" list for a period
			#  of time.  This process helps to prevent
			#  DoS attacks.  When subsequent packets are
			#  received from that IP address, they hit the
			#  "NAK" cache, and are immediately discarded.
			#
			#  After `nak_timeout` seconds, the blocked
			#  entry will be removed, and the IP will be
			#  allowed to try again to define a dynamic
			#  client.
			#
			#  Useful range of values: 1 to 600
			#
			nak_lifetime = 30.0

			#
			#  cleanup_delay:: The time to wait (in
			#  seconds) before cleaning up a reply to an
			#  `Access-Request` packet.
			#
			#  The reply is normally cached internally for
			#  a short period of time, after it is sent to
			#  the NAS.  The reply packet may be lost in
			#  the network, and the NAS will not see it.
			#  The NAS will then resend the request, and
			#  the server will respond quickly with the
			#  cached reply.
			#
			#  If this value is set too low, then
			#  duplicate requests from the NAS MAY NOT be
			#  detected, and will instead be handled as
			#  separate requests.
			#
			#  If this value is set too high, then the
			#  server will use more memory for no benefit.
			#
			#  This value can include a decimal number of
			#  seconds, e.g. "4.1".
			#
			#  Useful range of values: 2 to 30
			#
			cleanup_delay = 5.0
		}

		#
		#  #### UDP Transport
		#
		#  When the `listen` section contains `transport =
		#  udp`, it looks for a "udp" subsection.  This
		#  subsection contains all of the configuration for
		#  the UDP transport.
		#
		udp {
			#
			#  ipaddr:: The IP address where FreeRADIUS
			#  accepts packets.
			#
			#  The address can be IPv4, IPv6, a numbered
			#  IP address, or a host name.  If a host name
			#  is used, the IPv4 address is preferred.
			#  When there is no IPv4 address for a host
			#  name, the IPv6 address is used.
			#
			#  As with UDP, `ipaddr`, `ipv4addr`, and `ipv6addr`
			#  are all allowed.
			#
			#  ipv4addr:: Use IPv4 addresses.
			#
			#  The same as `ipaddr`, but will only use
			#  IPv4 addresses.
			#
			#  ipv6addr:: Use IPv6 addresses.
			#
			#  The same as `ipaddr`, but will only use
			#  IPv6 addresses.
			#
			ipaddr = *

			#
			#  port:: the UDP where FreeRADIUS accepts
			#  packets.
			#
			#  The default port for Access-Accept packets
			#  is `1812`.
			#
			port = 1812

			#
			#  dynamic_clients:: Whether or not we allow
			#  dynamic clients.
			#
			#  If set to `true`, then packets from unknown
			#  clients are passed through the `new
			#  client` subsection below.  See that section
			#  for more information about how dynamic
			#  clients work.
			#
#			dynamic_clients = true

			#
			#  networks:: The list of networks which are
			#  allowed to send packets to FreeRADIUS for
			#  dynamic clients.
			#
			#  If there are no dynamic clients, then this
			#  section is ignored.
			#
			#  The purpose of the `networks` subsection is
			#  to ensure that only a small set of source
			#  IPs can trigger dynamic clients.  If anyone
			#  could trigger dynamic clients, then the
			#  server would be subject to a DoS attack.
			#
			networks {
				#
				#  allow:: Allow packets from these
				#  networks to define dynamic clients.
				#
				#  Packets from all other sources will
				#  be rejected.
				#
				#  When a packet is from an allowed
				#  network, it will be run through the
				#  `new client` subsection below.
				#  That subsection can still reject
				#  the client request.
				#
				#  There is no limit to the number of
				#  networks which can be listed here.
				#
				allow = 127/8
				allow = 192.0.2/24

				#
				#  deny:: deny some networks.
				#
				#  The default behavior is to only
				#  allow packets from the `allow`
				#  networks.  The `deny` directive
				#  allows you to carve out a subset of
				#  an `allow` network, where some
				#  packets are denied.
				#
				#  That is, a `deny` network MUST
				#  exist within a previous `allow` network.
				#
				#  The `allow` and `deny` rules apply
				#  only to networks.  The order which
				#  they appear in the configuration
				#  file does not matter.
				#
#				deny = 127.0.0/24
			}
		}

		#
		#  #### TCP Transport
		#
		#  When the configuration has `transport = tcp`, it
		#  looks for a `tcp` subsection.  That subsection
		#  contains all of the configuration for the TCP
		#  transport.
		#
		#  Since UDP and TCP are similar, the majority of the
		#  configuration items are the same for both of them.
		#
		tcp {
			#
			#  ipaddr:: The IP address where FreeRADIUS
			#  accepts packets.
			#
			#  It has the same definition and meaning as
			#  the UDP `ipaddr` configuration above.
			#
			ipaddr = *

			#
			#  NOTE: As with v3, `ipaddr`, `ipv4addr`, and `ipv6addr`
			#  are all allowed.
			#

			#
			#  port:: the TCP where FreeRADIUS accepts
			#  packets.
			#
			#  The default port for Access-Accept packets
			#  is `1812`.
			#
			port = 1812

			#
			#  dynamic_clients:: Whether or not we allow dynamic clients.
			#
			#  If set to true, then packets from unknown
			#  clients are passed through the "new client"
			#  subsection below.  See that section for
			#  more information.
			#
#			dynamic_clients = true

			#
			#  networks { ... }::
			#
			#  If dynamic clients are allowed, then limit
			#  them to only a small set of source
			#  networks.
			#
			#  If dynamic clients are not allowed, then
			#  this section is ignored.
			#
			networks {
				#
				#  allow::  Allow packets from a network.
				#
				#  deny:: Deny packets from a network.
				#
				#  Allow or deny packets from these networks
				#  to define dynamic clients.
				#
				#  Packets from all other sources will
				#  be discarded.
				#
				#  Even if a packet is from an allowed
				#  network, it still must be permitted
				#  by the "new client" subsection.
				#
				#  There is no limit to the number of
				#  networks which can be listed here.
				#
				#  The allow / deny checks are organised by
				#  address.  The order of the items given here
				#  does not matter.
				#
				allow = 127/8
				allow = 192.0.2/24
#				deny = 127.0.0/24
			}
		}
	}

	listen tcp_auth {
		type = Access-Request
		type = Status-Server

		transport = tcp

		tcp {
			#
			#  As with v3, "ipaddr", "ipv4addr", and "ipv6addr"
			#  are all allowed.
			#
			ipaddr = *
			port = 1812

			#
			#  Whether or not we allow dynamic clients.
			#
			#  If set to true, then packets from unknown
			#  clients are passed through the "new client"
			#  subsection below.  See that section for
			#  more information.
			#
#			dynamic_clients = true

			#
			#  If dynamic clients are allowed, then limit
			#  them to only a small set of source
			#  networks.
			#
			#  If dynamic clients are not allowed, then
			#  this section is ignored.
			#
			networks {
				#
				#  Allow packets from these networks
				#  to define dynamic clients.
				#
				#  Packets from all other sources will
				#  be rejected.
				#
				#  Even if a packet is from an allowed
				#  network, it still must be allowed
				#  by the "new client" subsection.
				#
				#  There is no limit to the number of
				#  networks which can be listed here.
				#
				allow = 127/8
				allow = 192.0.2/24
#				deny = 127.0.0/24
			}
		}
	}

	#
	#  ### Listen for Accounting-Request packets
	#
	listen udp_acct {
		type = Accounting-Request

		transport = udp

		udp {
			ipaddr = *
			port = 1813
		}
	}


	#
	#  ### Local Clients
	#
	#  The "client" sections can can also be placed here.  Unlike
	#  v3, they do not need to be wrapped in a "clients" section.
	#  They can just co-exist beside the "listen" sections.
	#
	#  Clients listed here will apply to *all* listeners in this
	#  virtual server.
	#
	#  The clients listed here take precedence over the global
	#  clients.
	#
	client localhost {
		shortname = sample
		ipaddr = 192.0.2.1
		secret = testing123

		#  The other "client" configuration items can be added
		#  here, too.
	}


######################################################################
#
#  ## Packet Processing sections
#
#  The sections below are called when a RADIUS packet has been
#  received.
#
#  * recv Access-Request - for authorization and authentication
#  * recv Status-Server  - for checking the server is responding
#
######################################################################

#
#  ### Receive Access-Request packets
#
recv Access-Request {
	#
	#  Take a `User-Name`, and perform some checks on it, for
	#  spaces and other invalid characters. If the `User-Name`
	#  is invalid, reject the request.
	#
	#  See policy.d/filter for the definition of the
	#  filter_username policy.
	#
	filter_username

	#
	#  Some broken equipment sends passwords with embedded
	#  zeros, i.e. the debug output will show:
	#
	#      User-Password = "password\000\000"
	#
	#  This policy will fix the password to just be "password".
	#
#	filter_password

	#
	#  If you intend to use CUI and you require that the
	#  Operator-Name be set for CUI generation and you want to
	#  generate CUI also for your local clients, then uncomment
	#  operator-name below and set the operator-name for
	#  your clients in clients.conf.
	#
#	operator-name

	#
	#  Proxying example
	#
	#  The following example will proxy the request if the
	#  username ends in example.com.
	#
#	if (&User-Name =~ /@example\.com$/) {
#		&control.Auth-Type := "proxy-example.com"
#	}

	#
	#  If you want to generate CUI for some clients that do
	#  not send proper CUI requests, then uncomment cui below
	#  and set "add_cui = yes" for these clients in
	#  clients.conf.
	#
#	cui

	#
	#  The `auth_log` module will write all `Access-Request` packets to a file.
	#
	#  Uncomment the next bit in order to have a log of
	#  authentication requests.  For more information, see
	#  `mods-available/detail.log`.
	#
#	auth_log

	#
	#  The `chap` module will set `Auth-Type := ::CHAP` if the
	#  packet contains a `CHAP-Challenge` attribute.  The module
	#  does this only if the `Auth-Type` attribute has not already
	#  been set.
	#
	chap

	#
	#  The `mschap` module will set `Auth-Type := ::mschap` if the
	#  packet contains an `MS-CHAP-Challenge` attribute.  The
	#  module does this only if the `Auth-Type` attribute has not
	#  already been set.
	#
	mschap

	#
	#  The `digest` module implements the SIP Digest
	#  authentication method.
	#
	#  Note that the module does not implement RFC 4590.  Instead,
	#  it implements an earlier draft of the specification.  Since
	#  all of the NAS equipment also implements the earlier draft,
	#  this limitation is fine.
	#
	#  If you have a Cisco SIP server authenticating against
	#  FreeRADIUS, the `digest` module will set `Auth-Type :=
	#  "Digest"` if we are handling a SIP Digest request and the
	#  `Auth-Type` has not already been set.
	#
	digest

	#
	#  The `wimax` module fixes up various WiMAX-specific stupidities.
	#
	#  The WiMAX specification says that the `Calling-Station-Id`
	#  is 6 octets of the MAC.  This definition conflicts with RFC
	#  3580, and all common RADIUS practices. Uncommenting the
	#  `wimax` module here allows the module to change the
	#  `Calling-Station-Id` attribute to the normal format as
	#  specified in RFC 3580 Section 3.21.
	#
#	wimax

	#
	#  The `eap` module takes care of all EAP authentication,
	#  including EAP-MD5, EAP-TLS, PEAP and EAP-TTLS.
	#
	#  The module also sets the EAP-Type attribute in the request
	#  list, to the incoming EAP type.
	#
	#  The `eap` module returns `ok` or `updated` if it is not yet ready to
	#  authenticate the user. The configuration below checks for
	#  that return value, and if so, stops processing the current
	#  section.
	#
	#  The result is that any LDAP and/or SQL servers will not be
	#  queried during the initial set of packets that go back and
	#  forth to set up EAP-TTLS or PEAP.
	#
	#  We also recommend doing user lookups in the `inner-tunnel`
	#  virtual server.
	#
	eap {
		ok = return
		updated = return
	}

	#
	#  The `unix` module will obtain passwords from `/etc/passwd`
	#  or `/etc/shadow`.  It does this via the system API's, which
	#  are not thread-safe.  We do not recommend using the `unix` module.
	#
#	unix

	#
	#  Read what used to be the `users` file. Since v3, this file
	#  is located in `mods-config/files/authorize`.
	#
	files

	#
	#  Look in an SQL database. The schema of the database is
	#  meant to mirror the `users` file.  For a full description
	#  of the module behavior, please see
	#  https://wiki.freeradius.org/modules/Rlm_sql
	#
	-sql

	#
	#  If you are using /etc/smbpasswd, and are also doing mschap
	#  authentication, the uncomment this line, configure the
	#  module.
	#
#	smbpasswd

	#
	#  The `ldap` module reads passwords and other attributes from
	#  an LDAP database.
	#
	#  For a full description of the module behavior, please see
	#  https://wiki.freeradius.org/modules/Rlm_ldap
	#
	-ldap

	#
	#  Enforce daily limits on time spent logged in. This module
	#  is a variant of the `counter` module.
	#
#	dailycounter

	#
	#  See if the account has expired: check the time in the
	#  `Expiration` attribute and reject if we are past it.
	#  If the account has not expired, set `Session-Timeout`.
	#
	expiration

	#
	#  The `pap` module will set `Auth-Type := ::PAP` if the
	#  packet contains a `User-Password` attribute.  The module
	#  does this only if the `Auth-Type` attribute has not already
	#  been set.
	#
	#  The `pap` module is also responsible for "normalizing" the
	#  various kinds of "known good" passwords.
	#  e.g. `Password.NT` may come as a 16 byte blob, or as a
	#  32-byte hex string, or as a base-64 encoded string.  The
	#  `pap` module will look for common variations of password
	#  encoding, and convert them all to a normal form.
	#
	#  This module should be listed last, so that the other
	#  modules get a chance to set Auth-Type for themselves.
	#
	pap
}


#
#  ### Receive Status-Server packets
#
#
#  This section is processed when the server receives a `Status-Server`
#  packet.
#
recv Status-Server {
	#
	#  We are still here and responding.
	#
	ok
}


######################################################################
#
#  ## Authentication Sections
#
#  The sub-sections below are called based on the value of the
#  `Auth-Type` attribute, which should have been set by the `recv
#  Access-Request` section, above.
#
#  Since version 4, proxying also happens in this section.  For more
#  information on how proxying has changed in version 4, please see
#  https://wiki.freeradius.org/upgrading/version4/proxy.
#
#  For authentication, you should generally NOT set the `Auth-Type`
#  attribute.  As noted above, the modules will usually figure it what
#  to do, and will do the right thing.  The most common side effect of
#  erroneously setting the `Auth-Type` attribute is that one
#  authentication method will work, but all of the others will not.
#
#  The common reasons to set the `Auth-Type` attribute by hand are
#  to forcibly reject the user (`Auth-Type := ::Reject`), to or
#  forcibly accept the user (`Auth-Type := ::Accept`), or for
#  proxying.
#
#  Note that `Auth-Type := ::Accept` will NOT work with EAP.  The EAP
#  authentication protocol uses a series of handshake messages.  All
#  of the messages must be exchanged correctly in order for EAP
#  authentication to succeed.  Bypassing that process with `Auth-Type
#  := Accept` will just result in the user being rejected.
#
#  Policy configuration should generally go in the `send ...` sections
#  below, after authentication has completed.
#
######################################################################

#
#  ### PAP Authentication
#
#  For users who are using PAP authentication. A back-end database
#  listed in the "recv Access-Request" section MUST supply a "known
#  good" password for the user.  The password can be clear-text, or
#  encrypted via `crypt`, `bcrypt`, or other hashing.
#
authenticate pap {
	pap
}

#
#  ### CHAP Authentication
#
#  For users who are using CHAP authentication. A back-end database
#  listed in the "recv Access-Request" section MUST supply a
#  Password.Cleartext attribute. Encrypted passwords won't work.
#
authenticate chap {
	chap
}

#
#  ### MS-CHAP authentication
#
#  For users who are using MS-CHAP authentication. A back-end
#  database listed in the "recv Access-Request" section MUST supply
#  either a Password.Cleartext attribute, or a Password.NT
#  attribute. Encrypted passwords won't work.
#
authenticate mschap {
	mschap
}

#
#  ### SIP Digest Authentication
#
#  For users who are using SIP Digest authentication.
#
#  The `digest` line in the `recv Access-Request` section should also
#  be uncommented.
#
authenticate digest {
	digest
}

#
#  ## PAM (Pluggable Authentication Modules) Authentication
#
#  Authenticate with PAM (Pluggable Authentication Modules).
#
#  We do not recommend using PAM.  The server has enough functionality
#  that anything that can be done in PAM can be done easier in
#  FreeRADIUS.
#
#authenticate pam {
#	pam
#}

#
#  ### LDAP Authentication
#
#  For users who are using PAP, and when you can't get the "known
#  good" password from LDAP.  The module binds to the LDAP directory
#  as the user, along with the password taken from the User-Password
#  attribute.  The "bind as user" method means that CHAP, MS-CHAP, and
#  EAP won't work, as they do not supply a plain-text password.
#
#  We do NOT recommend using this. LDAP servers are databases, not
#  authentication servers.  It is only here as a last resort for
#  databases such as Active Directory.
#
#  We strongly recommend using `ldap` in the `recv Access-Request`
#  section.  And, ensuring that the account used by FreeRADIUS has
#  read permission on all of the users, groups, and passwords.
#
authenticate ldap {
	-ldap
}

#
#  EAP Authentication
#
#  For EAP-MD5, EAP-MSCHAP, EAP-TLS, EAP-TTLS, EAP-PEAP, EAP-PWD, etc.
#
authenticate eap {
	eap
}


#
#  ### Proxying
#
#  Proxying has changed substantially from v3 to v4.  These changes
#  are complex, but were necessary in order to support new features.
#  The result is that configurations which were impossible in v3 are
#  now trivial in v4.  For example:
#
#  * sending the same packet to multiple destinations, along with retransmissions
#  * sending the same packet to multiple destinations in parallel
#  * trying to proxy, and if it fails, programmatically doing something else
#  * trying to proxy, and if it fails, authenticating the user locally
#    * note that this won't work for EAP.
#
#  For more information, see:
#  https://wiki.freeradius.org/upgrading/version4/proxy.
#

#
#  The following example shows how proxying to three remote servers
#  can be configured.
#
#  The `Auth-Type` attribute would need to be set to
#  `proxy-example.com`.  The home servers MUST be defined in
#  `mods-available/radius`.
#

#authenticate proxy-example.com {
#	#
#	#  Log the request before proxying.
#	#
#	pre_proxy_log
#
#	#
#	#  Send the request to remote RADIUS servers, with
#	#  fail-over from one to the other if there's no response.
#	#
#	redundant {
#		radius1.example.com
#		radius2.example.com
#		radius3.example.com
#	}
#
#	#
#	#  Log the reply after proxying.
#	#
#	post_proxy_log.post-proxy
#}



#
#  ## Send replies to Access-Request packets
#

#
#  ### send Access-Challenge packets
#
#
#  This section is called when sending an Access-Challenge
#  response. It is configured to filter out all attributes that should
#  not be in the packet.
#
send Access-Challenge {
	attr_filter.access_challenge
	handled
}

#
#  ### send Access-Accept packets
#
#  Once we know that the user has been authenticated successfully,
#  there are additional things that can be done.
#
send Access-Accept {
	#
	#  If you need to have a State attribute, you can add it
	#  here. e.g. for later CoA-Request with State, and
	#  Service-Type = ::Authorize-Only.
	#
#	if (!&reply.State) {
#		&reply.State := "0x%randstr(16h)"
#	}

	#
	#  For EAP-TTLS and PEAP, add any cached attributes to the
	#  reply. The "session-state" attributes are automatically
	#  cached when an Access-Challenge is sent, and retrieved
	#  when an `Access-Request` is received.
	#
	#  The `session-state` attributes are deleted after an
	#  `Access-Reject` or `Access-Accept` packet has been sent.
	#
	&reply += &session-state

	#
	#  For EAP, ensure that the Access-Accept contains a User-Name
	#  attribute.
	#
	eap

	#
	#  Get an address from the IP Pool.
	#
#	sqlippool


	#
	#  Create the CUI value and add the attribute to
	#  Access-Accept. Uncomment the line below if
	#  *returning* the CUI to the NAS.
	#
#	cui

	#
	#  If you want to have a log of authentication replies,
	#  uncomment the following line. This is defined in
	#  `mods-available/detail.log`.
	#
#	reply_log

	#
	#  After authenticating the user, do another SQL query.
	#
	-sql

	#
	#  Uncomment the following if you want to modify the
	#  user's object in LDAP after a successful login.
	#
#	ldap

	#
	#  Calculate the various WiMAX keys. In order for this to
	#  work, you will need to define the WiMAX NAI, usually
	#  via:
	#
#	&request.WiMAX-MN-NAI = "%{User-Name}"

	#  If you want various keys to be calculated, you will
	#  need to update the reply with "template" values. The
	#  module will see this, and replace the template values
	#  with the correct ones taken from the cryptographic
	#  calculations, e.g.
	#
#	&reply += {
#		&Vendor-Specific.WiMAX = {
#			&FA-RK-Key = 0x00
#			&MSK = &reply.EAP-MSK
#		}
#	}

	#  You may want to delete the `MS-MPPE-*-Keys` from the
	#  reply, as some WiMAX clients behave badly when those
	#  attributes are included. See the configuration entry
	#  `delete_mppe_keys` in `mods-available/wimax` for
	#  more information.
	#
#	wimax

	#
	#  If there is a client certificate (EAP-TLS, and very
	#  occasionally PEAP and EAP-TTLS), then some attributes
	#  are filled out after the certificate verification has
	#  been performed. These fields MAY be available during
	#  the authentication, or they may be available only in
	#  the appropriate "send" section.
	#
	#  The first set of attributes contains information about
	#  the issuing certificate which is being used. The second
	#  contains information about the client certificate (if
	#  available).
	#
#	&reply += {
#		&Reply-Message = "%{session-state.TLS-Certificate.Serial}"
#		&Reply-Message = "%{session-state.TLS-Certificate.Not-After}"
#		&Reply-Message = "%{session-state.TLS-Certificate.Subject}"
#		&Reply-Message = "%{session-state.TLS-Certificate.Issuer}"
#		&Reply-Message = "%{session-state.TLS-Certificate.Common-Name}"
#		&Reply-Message = "%{session-state.TLS-Certificate.Subject-Alt-Name-Email}"
#	}

	#
	#  Insert the `Class` attribute with a unique value into the
	#  response, which aids matching auth and acct records and
	#  protects against duplicate Acct-Session-Id.
	#
	#  Note: This only works if the NAS has implemented RFC
	#  2865 behaviour for the Class attribute, AND if the NAS
	#  supports long Class attributes. Many older or cheap
	#  NASes only support 16-octet Class attributes.
	#
#	insert_acct_class

	#
	#  MacSEC requires the use of `EAP-Key-Name`. However, we
	#  don't want to send it for all EAP sessions. Therefore, the
	#  EAP modules put required data into the `EAP-Session-Id`
	#  attribute. This attribute is never put into a request or
	#  reply packet.
	#
	#  Uncomment the next few lines to copy the required data
	#  into the EAP-Key-Name attribute.
#
#	if (&reply.EAP-Session-Id) {
#		&reply.EAP-Key-Name := &reply.EAP-Session-Id
#	}

	#
	#  Call an instance of `linelog` to log the authentication success
	#  - equivalent to the previous log `auth = yes` option in v3.
	#  See `mods-enabled/linelog` for message formats and destinations.
	#
#	log_auth_access_accept

	#
	#  Remove `Reply-Message` if the response contains an
	#  `EAP-Message` attribute.  Some NAS equipment will
	#  automatically convert the `Reply-Message` to an "EAP
	#  notification" packet, which will cause end-user machines to
	#  drop the network connection.
	#
	remove_reply_message_if_eap
}

#
#  ### send Access-Reject packets
#
#  This section processes `Access-Reject` packets before they are sent
#  to the NAS.
#
#  The `session-state` list is available while this section is being
#  processed.  But all of the attributes in that list are discarded as
#  soon as the section is finished.
#
send Access-Reject {
	#
	#  Log failed authentications in SQL, too.
	#
	-sql

	#
	#  Filter out attributes that should not be in
	#  Access-Reject packets.
	#
	attr_filter.access_reject

	#
	#  Insert an EAP-Failure message if the request was rejected by
	#  policy, instead of from an authentication failure.
	#
	eap

	#
	#  Call an instance of `linelog` to log the authentication failure
	#  - equivalent to the previous log `auth = yes` option in v3.
	#  See `mods-enabled/linelog` for message formats and destinations.
	#
#	log_auth_access_reject

	#
	#  Remove `Reply-Message` if the response contains an
	#  `EAP-Message` attribute.  Some NAS equipment will
	#  automatically convert the `Reply-Message` to an "EAP
	#  notification" packet, which will cause end-user machines to
	#  drop the network connection.
	#
	remove_reply_message_if_eap

	#
	#  Delay sending the `Access-Reject` packet. This is no
	#  longer automatic as it was in version 3.
	#
	delay_reject
}



######################################################################
#
#  Accounting
#
#
#  This section deals with receiving Accounting requests and
#  sending Accounting responses.
#
######################################################################

#
#  An Accounting-Request packet has been received. Decide which
#  accounting type to use.
#
recv Accounting-Request {
	#
	#  Merge Acct-[Input|Output]-Gigawords and
	#  Acct-[Input-Output]-Octets into a single 64-bit
	#  counter, Acct-[Input|Output]-Octets64.
	#
#	acct_counters64

	#
	#  Ensure that we have a semi-unique identifier for every
	#  request, as many NAS boxes are broken.
	#
	acct_unique

	#
	#  Read the 'accounting' file.
	#
	files_accounting
}

#
#  Version 4 allows for sections specific to Acct-Status-Type.
#
#  Once the `recv Accounting-Request` section is processed, one of the
#  `accounting ... { ... }` sections will be run, based on the
#  value of the `Acct-Status-Type` attribute.
#
#  After the `accounting ... { ... }` section has been run, it will
#  then process the `send Accounting-Response` section
#

#
#  Session start
#
accounting Start {
	#
	#  Log traffic to an SQL database.
	#
	#  See "Accounting Queries" in `mods-available/sql`.
	#
	-sql

	#
	#  Refresh leases when we see a start.
	#
	#  Ensure that &control.IP-Pool.Name is set to determine which
	#  pool of IPs are used.  Set this in `recv Accounting-Request` so
	#  it is available for all the accounting sections.
	#
#	sqlippool
}

#
#  Session stop
#
accounting Stop {
	#
	#  Log traffic to an SQL database.
	#
	-sql

	#
	#  If you receive stop packets with zero session length,
	#  they will NOT be logged in the database. The SQL
	#  module will print a message (only in debugging mode),
	#  and will return "noop".
	#
	#  You can ignore these packets by uncommenting the
	#  following three lines. Otherwise, the server will not
	#  respond to the accounting request, and the NAS will
	#  retransmit.
	#
#	if (noop) {
#		ok
#	}

	#
	#  Return an address to the IP Pool when we see a stop record.
	#
#	sqlippool
}

#
#  Session is still alive
#
accounting Interim-Update {
	#
	#  Log traffic to an SQL database.
	#
	-sql

	#
	#  Refresh leases when we see an alive.
	#
#	sqlippool
}

#
#  The NAS has just booted up.
#
accounting Accounting-On {
	#
	#  Record that the NAS has booted to an SQL database
	#
	-sql

	#
	#  Return all addresses related to this NAS to the IP Pool
	#
#	sqlippool
}

#
#  The NAS is about to go down
#
accounting Accounting-Off {
	#
	#  Record that the NAS is shutting down to an SQL database
	#
	-sql

	#
	#  Return all addresses related to this NAS to the IP Pool
	#
#	sqlippool
}

#
#  Session failed to do something
#
accounting Failed {

}

#
#  There are many other values for `Acct-Status-Type` such as:
#
#  * Tunnel-Start
#  * Tunnel-Stop
#  * Tunnel-Reject
#  * Tunnel-Link-Start
#  * Tunnel-Link-Stop
#  * Tunnel-Link-Reject
#
#  Some vendors also define their own values, which is a very bad idea.
#

#
#  Send Accounting-Response.
#
#  Log the accounting data before replying. If logging fails then
#  the reply will not be sent, which means the NAS will send the
#  request again.
#
send Accounting-Response {
	#
	#  Add the CUI attribute from the corresponding
	#  Access-Accept to the Accounting-Response.
	#
	#  Use it only if your NAS boxes do not support CUI
	#  themselves.
	#
#	cui

	#
	#  Create a 'detail'ed log of the packets. Note that
	#  accounting requests which are proxied are also logged
	#  in the detail file.
	#
	detail

	#
	#  Update counters for daily usage calculations.
	#
#	daily

	#
	#  Update the wtmp file.
	#
	#  This is only relevant if you use "radlast".
	#
#	unix

	#
	#  For Simultaneous-Use tracking.
	#
	#  Due to packet losses in the network, the data here may
	#  be incorrect. There is little we can do about it.
	#
#	radutmp
#	sradutmp

	#
	#  Cisco VoIP specific bulk accounting.
	#
#	pgsql-voip

	#
	#  Filter attributes from the accounting response.
	#
	attr_filter.accounting_response
}
}
