Monday, February 11, 2019

Configuring Freeradius against Samba 4 domain controller

An info dump on how I configured Freeradius to support WPA2 Enterprise authentication against a Samba4 domain controller, using the Ubiquiti Network's Unifi Wifi radius client support.

The formatting on this post is going to be awful, as Blogger doesn't have a code-block formatting option. It is what it is *shrug*.

Operating system: Gentoo
Package versions: Freeradius - 3.0.15, Samba 4.8.6-r2


  1. Edit /etc/raddb/certs/*.cnf to have the desired default_days and default_crl_days. I picked 3650 days to give the certificate a 10 year expiration date. I'm sure this'll cause me quite a lot of confusion in 10 years. Note that you shouldn't do it this way ;)
  2. run the bootstrap script in that same directory. Again, you should set your certificates up properly.
  3. Now, properly join the computer to your windows domain using samba/winbind, as it'll be needed by freeradius in order to authenticate requests against SambaDC/WindowsDC.
  4. Remove all the files/symlinks in the mods-enabled folder except : always  attr_filter  expiration  logintime  preprocess  realm
  5. Remote all the files in policy.d except: canonicalization  control  eap  filter
  6. Remove all of the files in sites-enabled
Drop the following data into the file mods-enabled/eap

# -*- text -*-
##
##  eap.conf -- Configuration for EAP types (PEAP, TTLS, etc.)
##
##      $Id: 2621e183c3d9eafacb03bbea57a4a1fb71bf0383 $

#######################################################################
#
#  Whatever you do, do NOT set 'Auth-Type := EAP'.  The server
#  is smart enough to figure this out on its own.  The most
#  common side effect of setting 'Auth-Type := EAP' is that the
#  users then cannot use ANY other authentication method.
#
eap {
        #  Invoke the default supported EAP type when
        #  EAP-Identity response is received.
        #
        #  The incoming EAP messages DO NOT specify which EAP
        #  type they will be using, so it MUST be set here.
        #
        #  For now, only one default EAP type may be used at a time.
        #
        #  If the EAP-Type attribute is set by another module,
        #  then that EAP type takes precedence over the
        #  default type configured here.
        #
        default_eap_type = mschapv2

        #  A list is maintained to correlate EAP-Response
        #  packets with EAP-Request packets.  After a
        #  configurable length of time, entries in the list
        #  expire, and are deleted.
        #
        timer_expire     = 60

        #  There are many EAP types, but the server has support
        #  for only a limited subset.  If the server receives
        #  a request for an EAP type it does not support, then
        #  it normally rejects the request.  By setting this
        #  configuration to "yes", you can tell the server to
        #  instead keep processing the request.  Another module
        #  MUST then be configured to proxy the request to
        #  another RADIUS server which supports that EAP type.
        #
        #  If another module is NOT configured to handle the
        #  request, then the request will still end up being
        #  rejected.
        ignore_unknown_eap_types = no

        # Cisco AP1230B firmware 12.2(13)JA1 has a bug.  When given
        # a User-Name attribute in an Access-Accept, it copies one
        # more byte than it should.
        #
        # We can work around it by configurably adding an extra
        # zero byte.
        cisco_accounting_username_bug = no

        #
        #  Help prevent DoS attacks by limiting the number of
        #  sessions that the server is tracking.  For simplicity,
        #  this is taken from the "max_requests" directive in
        #  radiusd.conf.
        max_sessions = ${max_requests}

        # Supported EAP-types

        ## Common TLS configuration for TLS-based EAP types
        #
        #  See raddb/certs/README for additional comments
        #  on certificates.
        #
        #  If OpenSSL was not found at the time the server was
        #  built, the "tls", "ttls", and "peap" sections will
        #  be ignored.
        #
        #  If you do not currently have certificates signed by
        #  a trusted CA you may use the 'snakeoil' certificates.
        #  Included with the server in raddb/certs.
        #
        #  If these certificates have not been auto-generated:
        #    cd raddb/certs
        #    make
        #
        #  These test certificates SHOULD NOT be used in a normal
        #  deployment.  They are created only to make it easier
        #  to install the server, and to perform some simple
        #  tests with EAP-TLS, TTLS, or PEAP.
        #
        #  See also:
        #
        #  http://www.dslreports.com/forum/remark,9286052~mode=flat
        #
        #  Note that you should NOT use a globally known CA here!
        #  e.g. using a Verisign cert as a "known CA" means that
        #  ANYONE who has a certificate signed by them can
        #  authenticate via EAP-TLS!  This is likely not what you want.
        tls-config tls-common {
                private_key_password = whatever
                private_key_file = ${certdir}/server.pem

                #  If Private key & Certificate are located in
                #  the same file, then private_key_file &
                #  certificate_file must contain the same file
                #  name.
                #
                #  If ca_file (below) is not used, then the
                #  certificate_file below MUST include not
                #  only the server certificate, but ALSO all
                #  of the CA certificates used to sign the
                #  server certificate.
                certificate_file = ${certdir}/server.pem

                #  Trusted Root CA list
                #
                #  ALL of the CA's in this list will be trusted
                #  to issue client certificates for authentication.
                #
                #  In general, you should use self-signed
                #  certificates for 802.1x (EAP) authentication.
                #  In that case, this CA file should contain
                #  *one* CA certificate.
                #
                ca_file = ${cadir}/ca.pem

                #  OpenSSL will automatically create certificate chains,
                #  unless we tell it to not do that.  The problem is that
                #  it sometimes gets the chains right from a certificate
                #  signature view, but wrong from the clients view.
                #
                #  When setting "auto_chain = no", the server certificate
                #  file MUST include the full certificate chain.
        #       auto_chain = yes

                #
                #  If OpenSSL supports TLS-PSK, then we can use
                #  a PSK identity and (hex) password.  When the
                #  following two configuration items are specified,
                #  then certificate-based configuration items are
                #  not allowed.  e.g.:
                #
                #       private_key_password
                #       private_key_file
                #       certificate_file
                #       ca_file
                #       ca_path
                #
                #  For now, the identity is fixed, and must be the
                #  same on the client.  The passphrase must be a hex
                #  value, and can be up to 256 hex digits.
                #
                #  Future versions of the server may be able to
                #  look up the shared key (hexphrase) based on the
                #  identity.
                #
        #       psk_identity = "test"
        #       psk_hexphrase = "036363823"

                #
                #  For DH cipher suites to work, you have to
                #  run OpenSSL to create the DH file first:
                #
                #       openssl dhparam -out certs/dh 2048
                #
                dh_file = ${certdir}/dh

                #
                #  If your system doesn't have /dev/urandom,
                #  you will need to create this file, and
                #  periodically change its contents.
                #
                #  For security reasons, FreeRADIUS doesn't
                #  write to files in its configuration
                #  directory.
                #
        #       random_file = /dev/urandom

                #
                #  This can never exceed the size of a RADIUS
                #  packet (4096 bytes), and is preferably half
                #  that, to accommodate other attributes in
                #  RADIUS packet.  On most APs the MAX packet
                #  length is configured between 1500 - 1600
                #  In these cases, fragment size should be
                #  1024 or less.
                #
        #       fragment_size = 1024

                #  include_length is a flag which is
                #  by default set to yes If set to
                #  yes, Total Length of the message is
                #  included in EVERY packet we send.
                #  If set to no, Total Length of the
                #  message is included ONLY in the
                #  First packet of a fragment series.
                #
        #       include_length = yes


                #  Check the Certificate Revocation List
                #
                #  1) Copy CA certificates and CRLs to same directory.
                #  2) Execute 'c_rehash <CA certs&CRLs Directory>'.
                #    'c_rehash' is OpenSSL's command.
                #  3) uncomment the lines below.
                #  5) Restart radiusd
        #       check_crl = yes

                # Check if intermediate CAs have been revoked.
        #       check_all_crl = yes

                ca_path = ${cadir}

                #
                #  If check_cert_issuer is set, the value will
                #  be checked against the DN of the issuer in
                #  the client certificate.  If the values do not
                #  match, the certificate verification will fail,
                #  rejecting the user.
                #
                #  In 2.1.10 and later, this check can be done
                #  more generally by checking the value of the
                #  TLS-Client-Cert-Issuer attribute.  This check
                #  can be done via any mechanism you choose.
                #
        #       check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"

                #
                #  If check_cert_cn is set, the value will
                #  be xlat'ed and checked against the CN
                #  in the client certificate.  If the values
                #  do not match, the certificate verification
                #  will fail rejecting the user.
                #
                #  This check is done only if the previous
                #  "check_cert_issuer" is not set, or if
                #  the check succeeds.
                #
                #  In 2.1.10 and later, this check can be done
                #  more generally by checking the value of the
                #  TLS-Client-Cert-CN attribute.  This check
                #  can be done via any mechanism you choose.
                #
        #       check_cert_cn = %{User-Name}
                #
                # Set this option to specify the allowed
                # TLS cipher suites.  The format is listed
                # in "man 1 ciphers".
                #
                # For EAP-FAST, use "ALL:!EXPORT:!eNULL:!SSLv2"
                #
                cipher_list = "DEFAULT"

                # If enabled, OpenSSL will use server cipher list
                # (possibly defined by cipher_list option above)
                # for choosing right cipher suite rather than
                # using client-specified list which is OpenSSl default
                # behavior. Having it set to yes is a current best practice
                # for TLS
                cipher_server_preference = no

                # Work-arounds for OpenSSL nonsense
                # OpenSSL 1.0.1f and 1.0.1g do not calculate
                # the EAP keys correctly.  The fix is to upgrade
                # OpenSSL, or disable TLS 1.2 here.
                #
                #  For EAP-FAST, this MUST be set to "yes".
                #
#               disable_tlsv1_2 = no

                #

                #
                #  Elliptical cryptography configuration
                #
                #  Only for OpenSSL >= 0.9.8.f
                #
                ecdh_curve = "prime256v1"

                #
                #  Session resumption / fast reauthentication
                #  cache.
                #
                #  The cache contains the following information:
                #
                #  session Id - unique identifier, managed by SSL
                #  User-Name  - from the Access-Accept
                #  Stripped-User-Name - from the Access-Request
                #  Cached-Session-Policy - from the Access-Accept
                #
                #  The "Cached-Session-Policy" is the name of a
                #  policy which should be applied to the cached
                #  session.  This policy can be used to assign
                #  VLANs, IP addresses, etc.  It serves as a useful
                #  way to re-apply the policy from the original
                #  Access-Accept to the subsequent Access-Accept
                #  for the cached session.
                #
                #  On session resumption, these attributes are
                #  copied from the cache, and placed into the
                #  reply list.
                #
                #  You probably also want "use_tunneled_reply = yes"
                #  when using fast session resumption.
                #
                cache {
                        #
                        #  Enable it.  The default is "no". Deleting the entire "cache"
                        #  subsection also disables caching.
                        #
                        #  As of version 3.0.14, the session cache requires the use
                        #  of the "name" and "persist_dir" configuration items, below.
                        #
                        #  The internal OpenSSL session cache has been permanently
                        #  disabled.
                        #
                        #  You can disallow resumption for a particular user by adding the
                        #  following attribute to the control item list:
                        #
                        #    Allow-Session-Resumption = No
                        #
                        #  If "enable = no" below, you CANNOT enable resumption for just one
                        #  user by setting the above attribute to "yes".
                        #
                        enable = no

                        #
                        #  Lifetime of the cached entries, in hours. The sessions will be
                        #  deleted/invalidated after this time.
                        #
                        lifetime = 24 # hours

                        #
                        #  Internal "name" of the session cache. Used to
                        #  distinguish which TLS context sessions belong to.
                        #
                        #  The server will generate a random value if unset.
                        #  This will change across server restart so you MUST
                        #  set the "name" if you want to persist sessions (see
                        #  below).
                        #
                        #name = "EAP module"

                        #
                        #  Simple directory-based storage of sessions.
                        #  Two files per session will be written, the SSL
                        #  state and the cached VPs. This will persist session
                        #  across server restarts.
                        #
                        #  The default directory is ${logdir}, for historical
                        #  reasons.  You should ${db_dir} instead.  And check
                        #  the value of db_dir in the main radiusd.conf file.
                        #  It should not point to ${raddb}
                        #
                        #  The server will need write perms, and the directory
                        #  should be secured from anyone else. You might want
                        #  a script to remove old files from here periodically:
                        #
                        #    find ${logdir}/tlscache -mtime +2 -exec rm -f {} \;
                        #
                        #  This feature REQUIRES "name" option be set above.
                        #
                        #persist_dir = "${logdir}/tlscache"
                }

                #
                #  As of version 2.1.10, client certificates can be
                #  validated via an external command.  This allows
                #  dynamic CRLs or OCSP to be used.
                #
                #  This configuration is commented out in the
                #  default configuration.  Uncomment it, and configure
                #  the correct paths below to enable it.
                #
                #  If OCSP checking is enabled, and the OCSP checks fail,
                #  the verify section is not run.
                #
                #  If OCSP checking is disabled, the verify section is
                #  run on successful certificate validation.
                #
                verify {
                        #  If the OCSP checks succeed, the verify section
                        #  is run to allow additional checks.
                        #
                        #  If you want to skip verify on OCSP success,
                        #  uncomment this configuration item, and set it
                        #  to "yes".
        #               skip_if_ocsp_ok = no

                        #  A temporary directory where the client
                        #  certificates are stored.  This directory
                        #  MUST be owned by the UID of the server,
                        #  and MUST not be accessible by any other
                        #  users.  When the server starts, it will do
                        #  "chmod go-rwx" on the directory, for
                        #  security reasons.  The directory MUST
                        #  exist when the server starts.
                        #
                        #  You should also delete all of the files
                        #  in the directory when the server starts.
        #               tmpdir = /tmp/radiusd

                        #  The command used to verify the client cert.
                        #  We recommend using the OpenSSL command-line
                        #  tool.
                        #
                        #  The ${..ca_path} text is a reference to
                        #  the ca_path variable defined above.
                        #
                        #  The %{TLS-Client-Cert-Filename} is the name
                        #  of the temporary file containing the cert
                        #  in PEM format.  This file is automatically
                        #  deleted by the server when the command
                        #  returns.
        #               client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
                }

                #
                #  OCSP Configuration
                #  Certificates can be verified against an OCSP
                #  Responder. This makes it possible to immediately
                #  revoke certificates without the distribution of
                #  new Certificate Revocation Lists (CRLs).
                #
                ocsp {
                        #
                        #  Enable it.  The default is "no".
                        #  Deleting the entire "ocsp" subsection
                        #  also disables ocsp checking
                        #
                        enable = no

                        #
                        #  The OCSP Responder URL can be automatically
                        #  extracted from the certificate in question.
                        #  To override the OCSP Responder URL set
                        #  "override_cert_url = yes".
                        #
                        override_cert_url = yes

                        #
                        #  If the OCSP Responder address is not extracted from
                        #  the certificate, the URL can be defined here.
                        #
                        url = "http://127.0.0.1/ocsp/"

                        #
                        # If the OCSP Responder can not cope with nonce
                        # in the request, then it can be disabled here.
                        #
                        # For security reasons, disabling this option
                        # is not recommended as nonce protects against
                        # replay attacks.
                        #
                        # Note that Microsoft AD Certificate Services OCSP
                        # Responder does not enable nonce by default. It is
                        # more secure to enable nonce on the responder than
                        # to disable it in the query here.
                        # See http://technet.microsoft.com/en-us/library/cc770413%28WS.10%29.aspx
                        #
                        # use_nonce = yes

                        #
                        # Number of seconds before giving up waiting
                        # for OCSP response. 0 uses system default.
                        #
                        # timeout = 0

                        #
                        # Normally an error in querying the OCSP
                        # responder (no response from server, server did
                        # not understand the request, etc) will result in
                        # a validation failure.
                        #
                        # To treat these errors as 'soft' failures and
                        # still accept the certificate, enable this
                        # option.
                        #
                        # Warning: this may enable clients with revoked
                        # certificates to connect if the OCSP responder
                        # is not available. Use with caution.
                        #
                        # softfail = no
                }
        }

        ## EAP-TLS
        #
        #  As of Version 3.0, the TLS configuration for TLS-based
        #  EAP types is above in the "tls-config" section.
        #
        tls {
                # Point to the common TLS configuration
                tls = tls-common

                #
                # As part of checking a client certificate, the EAP-TLS
                # sets some attributes such as TLS-Client-Cert-CN. This
                # virtual server has access to these attributes, and can
                # be used to accept or reject the request.
                #
        #       virtual_server = check-eap-tls
        }


        ## EAP-TTLS
        #
        #  The TTLS module implements the EAP-TTLS protocol,
        #  which can be described as EAP inside of Diameter,
        #  inside of TLS, inside of EAP, inside of RADIUS...
        #
        #  Surprisingly, it works quite well.
        #
        ttls {
                #  Which tls-config section the TLS negotiation parameters
                #  are in - see EAP-TLS above for an explanation.
                #
                #  In the case that an old configuration from FreeRADIUS
                #  v2.x is being used, all the options of the tls-config
                #  section may also appear instead in the 'tls' section
                #  above. If that is done, the tls= option here (and in
                #  tls above) MUST be commented out.
                #
                tls = tls-common

                #  The tunneled EAP session needs a default EAP type
                #  which is separate from the one for the non-tunneled
                #  EAP module.  Inside of the TTLS tunnel, we recommend
                #  using EAP-MD5.  If the request does not contain an
                #  EAP conversation, then this configuration entry is
                #  ignored.
                #
                default_eap_type = md5

                #  The tunneled authentication request does not usually
                #  contain useful attributes like 'Calling-Station-Id',
                #  etc.  These attributes are outside of the tunnel,
                #  and normally unavailable to the tunneled
                #  authentication request.
                #
                #  By setting this configuration entry to 'yes',
                #  any attribute which is NOT in the tunneled
                #  authentication request, but which IS available
                #  outside of the tunnel, is copied to the tunneled
                #  request.
                #
                #  allowed values: {no, yes}
                #
                copy_request_to_tunnel = no

                #
                #  As of version 3.0.5, this configuration item
                #  is deprecated.  Instead, you should use
                #
                #       update outer.session-state {
                #               ...
                #
                #       }
                #
                #  This will cache attributes for the final Access-Accept.
                #
                #  The reply attributes sent to the NAS are usually
                #  based on the name of the user 'outside' of the
                #  tunnel (usually 'anonymous').  If you want to send
                #  the reply attributes based on the user name inside
                #  of the tunnel, then set this configuration entry to
                #  'yes', and the reply to the NAS will be taken from
                #  the reply to the tunneled request.
                #
                #  allowed values: {no, yes}
                #
                use_tunneled_reply = no

                #
                #  The inner tunneled request can be sent
                #  through a virtual server constructed
                #  specifically for this purpose.
                #
                #  If this entry is commented out, the inner
                #  tunneled request will be sent through
                #  the virtual server that processed the
                #  outer requests.
                #
                virtual_server = "inner-tunnel"

                #  This has the same meaning, and overwrites, the
                #  same field in the "tls" configuration, above.
                #  The default value here is "yes".
                #
        #       include_length = yes

                #
                # Unlike EAP-TLS, EAP-TTLS does not require a client
                # certificate. However, you can require one by setting the
                # following option. You can also override this option by
                # setting
                #
                #       EAP-TLS-Require-Client-Cert = Yes
                #
                # in the control items for a request.
                #
        #       require_client_cert = yes
        }


        ## EAP-PEAP
        #

        ##################################################
        #
        #  !!!!! WARNINGS for Windows compatibility  !!!!!
        #
        ##################################################
        #
        #  If you see the server send an Access-Challenge,
        #  and the client never sends another Access-Request,
        #  then
        #
        #               STOP!
        #
        #  The server certificate has to have special OID's
        #  in it, or else the Microsoft clients will silently
        #  fail.  See the "scripts/xpextensions" file for
        #  details, and the following page:
        #
        #       http://support.microsoft.com/kb/814394/en-us
        #
        #  For additional Windows XP SP2 issues, see:
        #
        #       http://support.microsoft.com/kb/885453/en-us
        #
        #
        #  If is still doesn't work, and you're using Samba,
        #  you may be encountering a Samba bug.  See:
        #
        #       https://bugzilla.samba.org/show_bug.cgi?id=6563
        #
        #  Note that we do not necessarily agree with their
        #  explanation... but the fix does appear to work.
        #
        ##################################################

        #
        #  The tunneled EAP session needs a default EAP type
        #  which is separate from the one for the non-tunneled
        #  EAP module.  Inside of the TLS/PEAP tunnel, we
        #  recommend using EAP-MS-CHAPv2.
        #
        peap {
                #  Which tls-config section the TLS negotiation parameters
                #  are in - see EAP-TLS above for an explanation.
                #
                #  In the case that an old configuration from FreeRADIUS
                #  v2.x is being used, all the options of the tls-config
                #  section may also appear instead in the 'tls' section
                #  above. If that is done, the tls= option here (and in
                #  tls above) MUST be commented out.
                #
                tls = tls-common

                #  The tunneled EAP session needs a default
                #  EAP type which is separate from the one for
                #  the non-tunneled EAP module.  Inside of the
                #  PEAP tunnel, we recommend using MS-CHAPv2,
                #  as that is the default type supported by
                #  Windows clients.
                #
                default_eap_type = mschapv2

                #  The PEAP module also has these configuration
                #  items, which are the same as for TTLS.
                #
                copy_request_to_tunnel = no

                #
                #  As of version 3.0.5, this configuration item
                #  is deprecated.  Instead, you should use
                #
                #       update outer.session-state {
                #               ...
                #
                #       }
                #
                #  This will cache attributes for the final Access-Accept.
                #
                use_tunneled_reply = no

                #  When the tunneled session is proxied, the
                #  home server may not understand EAP-MSCHAP-V2.
                #  Set this entry to "no" to proxy the tunneled
                #  EAP-MSCHAP-V2 as normal MSCHAPv2.
                #
        #       proxy_tunneled_request_as_eap = yes

                #
                #  The inner tunneled request can be sent
                #  through a virtual server constructed
                #  specifically for this purpose.
                #
                #  If this entry is commented out, the inner
                #  tunneled request will be sent through
                #  the virtual server that processed the
                #  outer requests.
                #
                virtual_server = "inner-tunnel"

                # This option enables support for MS-SoH
                # see doc/SoH.txt for more info.
                # It is disabled by default.
                #
        #       soh = yes

                #
                # The SoH reply will be turned into a request which
                # can be sent to a specific virtual server:
                #
        #       soh_virtual_server = "soh-server"

                #
                # Unlike EAP-TLS, PEAP does not require a client certificate.
                # However, you can require one by setting the following
                # option. You can also override this option by setting
                #
                #       EAP-TLS-Require-Client-Cert = Yes
                #
                # in the control items for a request.
                #
        #       require_client_cert = yes
        }

        #
        #  This takes no configuration.
        #
        #  Note that it is the EAP MS-CHAPv2 sub-module, not
        #  the main 'mschap' module.
        #
        #  Note also that in order for this sub-module to work,
        #  the main 'mschap' module MUST ALSO be configured.
        #
        #  This module is the *Microsoft* implementation of MS-CHAPv2
        #  in EAP.  There is another (incompatible) implementation
        #  of MS-CHAPv2 in EAP by Cisco, which FreeRADIUS does not
        #  currently support.
        #
        mschapv2 {
                #  Prior to version 2.1.11, the module never
                #  sent the MS-CHAP-Error message to the
                #  client.  This worked, but it had issues
                #  when the cached password was wrong.  The
                #  server *should* send "E=691 R=0" to the
                #  client, which tells it to prompt the user
                #  for a new password.
                #
                #  The default is to behave as in 2.1.10 and
                #  earlier, which is known to work.  If you
                #  set "send_error = yes", then the error
                #  message will be sent back to the client.
                #  This *may* help some clients work better,
                #  but *may* also cause other clients to stop
                #  working.
                #
                send_error = yes

                #  Server identifier to send back in the challenge.
                #  This should generally be the host name of the
                #  RADIUS server.  Or, some information to uniquely
                #  identify it.
#               identity = "FreeRADIUS"
        }

}



The following file in mods-enabled/mschap

# -*- text -*-
#
#  $Id: 18f600589b67177679b9521feb65b7fbb0200ac2 $

# Microsoft CHAP authentication
#
#  This module supports MS-CHAP and MS-CHAPv2 authentication.
#  It also enforces the SMB-Account-Ctrl attribute.
#
mschap {
        # An alternative to using ntlm_auth is to connect to the
        # winbind daemon directly for authentication. This option
        # is likely to be faster and may be useful on busy systems,
        # but is less well tested.
        #
        # Using this option requires libwbclient from Samba 4.2.1
        # or later to be installed. Make sure that ntlm_auth above is
        # commented out.
        #
        winbind_username = "%{mschap:User-Name}"
#       winbind_domain = "NETWORK-1"
        winbind_domain = "%{mschap:NT-Domain}"

        #
        #  Information for the winbind connection pool.  The configuration
        #  items below are the same for all modules which use the new
        #  connection pool.
        #
        pool {
                #  Connections to create during module instantiation.
                #  If the server cannot create specified number of
                #  connections during instantiation it will exit.
                #  Set to 0 to allow the server to start without the
                #  winbind daemon being available.
                start = ${thread[pool].start_servers}

                #  Minimum number of connections to keep open
                min = ${thread[pool].min_spare_servers}

                #  Maximum number of connections
                #
                #  If these connections are all in use and a new one
                #  is requested, the request will NOT get a connection.
                #
                #  Setting 'max' to LESS than the number of threads means
                #  that some threads may starve, and you will see errors
                #  like 'No connections available and at max connection limit'
                #
                #  Setting 'max' to MORE than the number of threads means
                #  that there are more connections than necessary.
                max = ${thread[pool].max_servers}

                #  Spare connections to be left idle
                #
                #  NOTE: Idle connections WILL be closed if "idle_timeout"
                #  is set.  This should be less than or equal to "max" above.
                spare = ${thread[pool].max_spare_servers}

                #  Number of uses before the connection is closed
                #
                #  0 means "infinite"
                uses = 0

                #  The number of seconds to wait after the server tries
                #  to open a connection, and fails.  During this time,
                #  no new connections will be opened.
                retry_delay = 30

                #  The lifetime (in seconds) of the connection
                #
                #  NOTE: A setting of 0 means infinite (no limit).
                lifetime = 86400

                #  The pool is checked for free connections every
                #  "cleanup_interval".  If there are free connections,
                #  then one of them is closed.
                cleanup_interval = 300

                #  The idle timeout (in seconds).  A connection which is
                #  unused for this length of time will be closed.
                #
                #  NOTE: A setting of 0 means infinite (no timeout).
                idle_timeout = 600

                #  NOTE: All configuration settings are enforced.  If a
                #  connection is closed because of "idle_timeout",
                #  "uses", or "lifetime", then the total number of
                #  connections MAY fall below "min".  When that
                #  happens, it will open a new connection.  It will
                #  also log a WARNING message.
                #
                #  The solution is to either lower the "min" connections,
                #  or increase lifetime/idle_timeout.
        }
}


This goes in  sites-enabled/default

######################################################################
#
#       As of 2.0.0, FreeRADIUS supports virtual hosts using the
#       "server" section, and configuration directives.
#
#       Virtual hosts should be put into the "sites-available"
#       directory.  Soft links should be created in the "sites-enabled"
#       directory to these files.  This is done in a normal installation.
#
#       If you are using 802.1X (EAP) authentication, please see also
#       the "inner-tunnel" virtual server.  You will likely have to edit
#       that, too, for authentication to work.
#
#       $Id: 3616050e7625eb6b5e2ba44782fcb737b2ae6136 $
#
######################################################################
#
#       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.
#
#       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 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.  (e.g. as a "tar" file).  Then,
#       make more edits, and test, as above.
#
#       There are many "commented out" references to modules such
#       as ldap, sql, etc.  These references serve as place-holders.
#       If you need the functionality of that module, then configure
#       it in radiusd.conf, and un-comment the references to it in
#       this file.  In most cases, those small changes will result
#       in the server being able to connect to the DB, and to
#       authenticate users.
#
######################################################################

server default {
#
#  If you want the server to listen on additional addresses, or on
#  additional ports, you can use multiple "listen" sections.
#
#  Each section make the server listen for only one type of packet,
#  therefore authentication and accounting have to be configured in
#  different sections.
#
#  The server ignore all "listen" section if you are using '-i' and '-p'
#  on the command line.
#
listen {
        #  Type of packets to listen for.
        #  Allowed values are:
        #       auth    listen for authentication packets
        #       acct    listen for accounting packets
        #       proxy   IP to use for sending proxied packets
        #       detail  Read from the detail file.  For examples, see
        #               raddb/sites-available/copy-acct-to-home-server
        #       status  listen for Status-Server packets.  For examples,
        #               see raddb/sites-available/status
        #       coa     listen for CoA-Request and Disconnect-Request
        #               packets.  For examples, see the file
        #               raddb/sites-available/coa
        #
        type = auth

        #  ipaddr/ipv4addr/ipv6addr - IP address on which to listen.
        #  If multiple ones are listed, only the first one will
        #  be used, and the others will be ignored.
        #
        #  The configuration options accept the following syntax:
        #
        #  ipv4addr - IPv4 address (e.g.192.0.2.3)
        #           - wildcard (i.e. *)
        #           - hostname (radius.example.com)
        #             Only the A record for the host name is used.
        #             If there is no A record, an error is returned,
        #             and the server fails to start.
        #
        #  ipv6addr - IPv6 address (e.g. 2001:db8::1)
        #           - wildcard (i.e. *)
        #           - hostname (radius.example.com)
        #             Only the AAAA record for the host name is used.
        #             If there is no AAAA record, an error is returned,
        #             and the server fails to start.
        #
        #  ipaddr   - IPv4 address as above
        #           - IPv6 address as above
        #           - wildcard (i.e. *), which means IPv4 wildcard.
        #           - hostname
        #             If there is only one A or AAAA record returned
        #             for the host name, it is used.
        #             If multiple A or AAAA records are returned
        #             for the host name, only the first one is used.
        #             If both A and AAAA records are returned
        #             for the host name, only the A record is used.
        #
        # ipv4addr = *
        # ipv6addr = *
        ipaddr = *

        #  Port on which to listen.
        #  Allowed values are:
        #       integer port number (1812)
        #       0 means "use /etc/services for the proper port"
        port = 0

        #  Some systems support binding to an interface, in addition
        #  to the IP address.  This feature isn't strictly necessary,
        #  but for sites with many IP addresses on one interface,
        #  it's useful to say "listen on all addresses for eth0".
        #
        #  If your system does not support this feature, you will
        #  get an error if you try to use it.
        #
#       interface = eth0

        #  Per-socket lists of clients.  This is a very useful feature.
        #
        #  The name here is a reference to a section elsewhere in
        #  radiusd.conf, or clients.conf.  Having the name as
        #  a reference allows multiple sockets to use the same
        #  set of clients.
        #
        #  If this configuration is used, then the global list of clients
        #  is IGNORED for this "listen" section.  Take care configuring
        #  this feature, to ensure you don't accidentally disable a
        #  client you need.
        #
        #  See clients.conf for the configuration of "per_socket_clients".
        #
#       clients = per_socket_clients

        #
        #  Connection limiting for sockets with "proto = tcp".
        #
        #  This section is ignored for other kinds of sockets.
        #
        limit {
              #
              #  Limit the number of simultaneous TCP connections to the socket
              #
              #  The default is 16.
              #  Setting this to 0 means "no limit"
              max_connections = 16

              #  The per-socket "max_requests" option does not exist.

              #
              #  The lifetime, in seconds, of a TCP connection.  After
              #  this lifetime, the connection will be closed.
              #
              #  Setting this to 0 means "forever".
              lifetime = 0

              #
              #  The idle timeout, in seconds, of a TCP connection.
              #  If no packets have been received over the connection for
              #  this time, the connection will be closed.
              #
              #  Setting this to 0 means "no timeout".
              #
              #  We STRONGLY RECOMMEND that you set an idle timeout.
              #
              idle_timeout = 30
        }
}

#  Authorization. First preprocess (hints and huntgroups files),
#  then realms, and finally look in the "users" file.
#
#  Any changes made here should also be made to the "inner-tunnel"
#  virtual server.
#
#  The order of the realm modules will determine the order that
#  we try to find a matching realm.
#
#  Make *sure* that 'preprocess' comes before any realm if you
#  need to setup hints for the remote radius server
authorize {
        #
        #  Take a User-Name, and perform some checks on it, for spaces and other
        #  invalid characters.  If the User-Name appears invalid, reject the
        #  request.
        #
        #  See policy.d/filter for the definition of the filter_username policy.
        #
        filter_username

        #
        #  If the users are logging in with an MS-CHAP-Challenge
        #  attribute for authentication, the mschap module will find
        #  the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP'
        #  to the request, which will cause the server to then use
        #  the mschap module for authentication.
        mschap

        #
        #  The preprocess module takes care of sanitizing some bizarre
        #  attributes in the request, and turning them into attributes
        #  which are more standard.
        #
        #  It takes care of processing the 'raddb/mods-config/preprocess/hints'
        #  and the 'raddb/mods-config/preprocess/huntgroups' files.
        preprocess

        #
        #  If you are using multiple kinds of realms, you probably
        #  want to set "ignore_null = yes" for all of them.
        #  Otherwise, when the first style of realm doesn't match,
        #  the other styles won't be checked.
        #
        suffix
        ntdomain

        #
        #  This module takes care of EAP-MD5, EAP-TLS, and EAP-LEAP
        #  authentication.
        #
        #  It also sets the EAP-Type attribute in the request
        #  attribute list to the EAP type from the packet.
        #
        #  The EAP module returns "ok" or "updated" if it is not yet ready
        #  to authenticate the user.  The configuration below checks for
        #  "ok", and stops processing the "authorize" section if so.
        #
        #  Any LDAP and/or SQL servers will not be queried for the
        #  initial set of packets that go back and forth to set up
        #  TTLS or PEAP.
        #
        #  The "updated" check is commented out for compatibility with
        #  previous versions of this configuration, but you may wish to
        #  uncomment it as well; this will further reduce the number of
        #  LDAP and/or SQL queries for TTLS or PEAP.
        #
        eap {
                ok = return
                updated = return
        }

        #
        expiration
        logintime
}


#  Authentication.
#
#
#  This section lists which modules are available for authentication.
#  Note that it does NOT mean 'try each module in order'.  It means
#  that a module from the 'authorize' section adds a configuration
#  attribute 'Auth-Type := FOO'.  That authentication type is then
#  used to pick the appropriate module from the list below.
#

#  In general, you SHOULD NOT set the Auth-Type attribute.  The server
#  will figure it out on its own, 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 the
#  others will not.
#
#  The common reasons to set the Auth-Type attribute by hand
#  is to either forcibly reject the user (Auth-Type := Reject),
#  or to or forcibly accept the user (Auth-Type := Accept).
#
#  Note that Auth-Type := Accept will NOT work with EAP.
#
#  Please do not put "unlang" configurations into the "authenticate"
#  section.  Put them in the "post-auth" section instead.  That's what
#  the post-auth section is for.
#
authenticate {
        #
        #  MSCHAP authentication.
        Auth-Type MS-CHAP {
                mschap
        }

        #
        #  Allow EAP authentication.
        eap
}


#
#  Pre-accounting.  Decide which accounting type to use.
#
preacct {
        preprocess

        #
        #  Look for IPASS-style 'realm/', and if not found, look for
        #  '@realm', and decide whether or not to proxy, based on
        #  that.
        #
        #  Accounting requests are generally proxied to the same
        #  home server as authentication requests.
        suffix
        ntdomain
}

#  Post-Authentication
#  Once we KNOW that the user has been authenticated, there are
#  additional steps we can take.
post-auth {
        #
        #  For EAP-TTLS and PEAP, add the cached attributes to the reply.
        #  The "session-state" attributes are automatically cached when
        #  an Access-Challenge is sent, and automatically retrieved
        #  when an Access-Request is received.
        #
        #  The session-state attributes are automatically deleted after
        #  an Access-Reject or Access-Accept is sent.
        #
        update {
                &reply: += &session-state:
        }

        #  Remove reply message if the response contains an EAP-Message
        remove_reply_message_if_eap

        #
        #  Access-Reject packets are sent through the REJECT sub-section of the
        #  post-auth section.
        #
        #  Add the ldap module name (or instance) if you have set
        #  'edir_account_policy_check = yes' in the ldap module configuration
        #
        #  The "session-state" attributes are not available here.
        #
        Post-Auth-Type REJECT {
                attr_filter.access_reject

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

                #  Remove reply message if the response contains an EAP-Message
                remove_reply_message_if_eap
        }
}

} # default server block


This goes in sites-enabled/inner-tunnel

# -*- text -*-
######################################################################
#
#       This is a virtual server that handles *only* inner tunnel
#       requests for EAP-TTLS and PEAP types.
#
#       $Id: 70b1d8da255a740d2d1b59808393722766dc6a60 $
#
######################################################################

server inner-tunnel {

#
#  This next section is here to allow testing of the "inner-tunnel"
#  authentication methods, independently from the "default" server.
#  It is listening on "localhost", so that it can only be used from
#  the same machine.
#
#       $ radtest USER PASSWORD 127.0.0.1:18120 0 testing123
#
#  If it works, you have configured the inner tunnel correctly.  To check
#  if PEAP will work, use:
#
#       $ radtest -t mschap USER PASSWORD 127.0.0.1:18120 0 testing123
#
#  If that works, PEAP should work.  If that command doesn't work, then
#
#       FIX THE INNER TUNNEL CONFIGURATION SO THAT IT WORKS.
#
#  Do NOT do any PEAP tests.  It won't help.  Instead, concentrate
#  on fixing the inner tunnel configuration.  DO NOTHING ELSE.
#
#listen {
#       ipaddr = 127.0.0.1
#       port = 18120
#       type = auth
#}


#  Authorization. First preprocess (hints and huntgroups files),
#  then realms, and finally look in the "users" file.
#
#  The order of the realm modules will determine the order that
#  we try to find a matching realm.
#
#  Make *sure* that 'preprocess' comes before any realm if you
#  need to setup hints for the remote radius server
authorize {
        #
        #  Take a User-Name, and perform some checks on it, for spaces and other
        #  invalid characters.  If the User-Name appears invalid, reject the
        #  request.
        #
        #  See policy.d/filter for the definition of the filter_username policy.
        #
        filter_username

        #
        #  If the users are logging in with an MS-CHAP-Challenge
        #  attribute for authentication, the mschap module will find
        #  the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP'
        #  to the request, which will cause the server to then use
        #  the mschap module for authentication.
        mschap

        #
        #  If you are using multiple kinds of realms, you probably
        #  want to set "ignore_null = yes" for all of them.
        #  Otherwise, when the first style of realm doesn't match,
        #  the other styles won't be checked.
        #
        #  Note that proxying the inner tunnel authentication means
        #  that the user MAY use one identity in the outer session
        #  (e.g. "anonymous", and a different one here
        #  (e.g. "user@example.com").  The inner session will then be
        #  proxied elsewhere for authentication.  If you are not
        #  careful, this means that the user can cause you to forward
        #  the authentication to another RADIUS server, and have the
        #  accounting logs *not* sent to the other server.  This makes
        #  it difficult to bill people for their network activity.
        #
        suffix
        ntdomain

        #
        #  The "suffix" module takes care of stripping the domain
        #  (e.g. "@example.com") from the User-Name attribute, and the
        #  next few lines ensure that the request is not proxied.
        #
        #  If you want the inner tunnel request to be proxied, delete
        #  the next few lines.
        #
        update control {
                &Proxy-To-Realm := LOCAL
        }

        #
        #  This module takes care of EAP-MSCHAPv2 authentication.
        #
        #  It also sets the EAP-Type attribute in the request
        #  attribute list to the EAP type from the packet.
        #
        #  The example below uses module failover to avoid querying all
        #  of the following modules if the EAP module returns "ok".
        #  Therefore, your LDAP and/or SQL servers will not be queried
        #  for the many packets that go back and forth to set up TTLS
        #  or PEAP.  The load on those servers will therefore be reduced.
        #
        eap {
                ok = return
        }

        expiration
        logintime
}


#  Authentication.
#
#
#  This section lists which modules are available for authentication.
#  Note that it does NOT mean 'try each module in order'.  It means
#  that a module from the 'authorize' section adds a configuration
#  attribute 'Auth-Type := FOO'.  That authentication type is then
#  used to pick the appropriate module from the list below.
#

#  In general, you SHOULD NOT set the Auth-Type attribute.  The server
#  will figure it out on its own, 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 the
#  others will not.
#
#  The common reasons to set the Auth-Type attribute by hand
#  is to either forcibly reject the user, or forcibly accept him.
#
authenticate {
        #
        #  MSCHAP authentication.
        Auth-Type MS-CHAP {
                mschap
        }

        #
        #  Allow EAP authentication.
        eap
}

######################################################################
#
#       There are no accounting requests inside of EAP-TTLS or PEAP
#       tunnels.
#
######################################################################


#  Post-Authentication
#  Once we KNOW that the user has been authenticated, there are
#  additional steps we can take.
#
#  Note that the last packet of the inner-tunnel authentication
#  MAY NOT BE the last packet of the outer session.  So updating
#  the outer reply MIGHT work, and sometimes MIGHT NOT.  The
#  exact functionality depends on both the inner and outer
#  authentication methods.
#
#  If you need to send a reply attribute in the outer session,
#  the ONLY safe way is to set "use_tunneled_reply = yes", and
#  then update the inner-tunnel reply.
post-auth {
        #
        #  Access-Reject packets are sent through the REJECT sub-section of the
        #  post-auth section.
        #
        #  Add the ldap module name (or instance) if you have set
        #  'edir_account_policy_check = yes' in the ldap module configuration
        #
        Post-Auth-Type REJECT {
                attr_filter.access_reject

                #
                #  Let the outer session know which module failed, and why.
                #
                update outer.session-state {
                        &Module-Failure-Message := &request:Module-Failure-Message
                }
        }
}

} # inner-tunnel server block