```
detail auth_log {
- filename = ${radacctdir}/%{Net.Src.IP-Address}/auth-detail-%Y-%m-%d
+ filename = ${radacctdir}/%{Net.Src.IP}/auth-detail-%Y-%m-%d
permissions = 0600
suppress {
User-Password
The default is `yes`
+
+password_attribute:: Which attribute in the request should be used as
+the user's password when performing PAP authentication.
+
+
== Default Configuration
```
pap {
# normalise = no
+# password_attribute = &User-Password
}
```
included in your module. If the module is called for a section which
does not have a function defined, it will return `noop`.
+WARNING: The Perl module does _not_ as yet support nested attributes,
+or even flat attributes which have parents. e.g. Vendor-Specific.Cisco.AVPair.
+We hope to fix that soon.
+
## Configuration Settings
-func_start_accounting::
-func_stop_accounting::
-
-Uncomment the following lines if you wish to use separate functions
-for `Start` and `Stop` accounting packets.
-In that case, the `func_accounting` function is not called.
-
-
-
config { ... }::
You can define configuration items (and nested sub-sections) in perl `config { ... }`
# func_post_proxy = post_proxy
# func_post_auth = post_auth
# func_detach = detach
-# func_start_accounting = accounting_start
-# func_stop_accounting = accounting_stop
# config {
# name = "value"
# sub-config {
module starts pinging the home server with these packets.
-type:: You can specify any type of packet here, though
-Status-Server is recommended.
+type:: You can specify any type of request packet here,
+e.g. 'Access-Request', 'Accounting-Request' or
+'Status-Server'.
+
+Status-Server is recommended as other packet types may
+be interpreted incorrectly, or proxied to a remote
+server defeting the purpose of the status check
If you specify another type of packet, it MUST be listed
as an allowed `type`, above.
-
response_window: If we do not receive a reply within this time period, then
start `zombie_period`
# originate = no
status_check {
type = Status-Server
-# &request.User-Name := "test-user"
-# &request.User-Password := "this-is-not-a-real-password"
-# &request.NAS-Identifier := "Status check. Are you alive?"
-# &request.Event-Timestamp = 0
+# update request {
+# &User-Name := "test-user"
+# &User-Password := "this-is-not-a-real-password"
+# &NAS-Identifier := "Status check. Are you alive?"
+# &Event-Timestamp = 0
+# }
}
response_window = 15
zombie_period = 10
revive_interval = 3600
pool {
- start = 1
+ start = 0
min = 1
max = 8
connecting = 1
= SMTP Module
-The `smtp` module validates a users name and password against an SMTP server.
-It should be called from an `authenticate` section.
+The `smtp` module can perform two actions:
+
+When called in the `authenticate` section, it validates a users name
+and password from request attributes against an SMTP server without
+sending a mail.
+
+When called with the method `mail` it will send an email.
The module can optionally perform a tls handshake, enabled with require_cert
+username:: User name to use when sending emails. Can be a fixed
+string or an attribute. Leave unset if authentication is not
+required to send emails.
+
+
+
+password:: Password to use in conjunction with the above user name
+for SMTP authentication.
+
+
+
template_directory:: The source directory where all file attachments are pulled from
All file attachments should be their relative path from this location, without a leading /
Non-standard mail headers may be set. Adhere to your MTA's documentation
+
+connection { .. }:: Configure how connection handles are
+managed per thread.
+
+
+Reusable connection handles are allocated in blocks. These
+parameters allow for tuning how that is done.
+
+Since http requests are performed async, the settings here
+represent outstanding http requests per thread.
+
+
+
+min:: The minimum number of connection handles to
+keep allocated.
+
+
+
+max:: The maximum number of reusable connection handles
+to allocate.
+
+Any requests to allocate a connection handle beyond
+this number will cause a temporary handle to be allocated.
+This is less efficient than the block allocation so
+`max` should be set to reflect the number of outstanding
+requests expected at peak load.
+
+
+cleanup_interval:: How often to free un-used connection
+handles.
+
+Every `cleanup_interval` a cleanup routine runs which
+will free any blocks of handles which are not in use,
+ensuring that at least `min` handles are kept.
+
+
+
== Default Configuration
```
}
uri = "smtp://192.0.20.1/"
timeout = 5s
+# username = "user"
+# password = "secret"
template_directory = raddb/mods_config/smtp
attachments = &SMTP-Attachments[*]
envelope_address = "postmaster@localhost"
Message-ID = "950124.162336@example.com"
# X-Originating-IP = "192.0.20.1"
}
+ connection {
+ reuse {
+ min = 10
+ max = 100
+ cleanup_interval = 30s
+ }
+ }
}
```
+
If there's no State attribute, then this is the request from
the user.
# with that number.
server challenge {
namespace = radius
+ dictionary {
+ uint32 challenge-string
+ }
listen {
type = Access-Request
transport = udp
}
else {
&control.Auth-Type := Step2
- &control.Password.Cleartext := &session-state.Tmp-Integer-0
+ &control.Password.Cleartext := &session-state.challenge-string
}
}
authenticate step1 {
pap
- &session-state.Tmp-Integer-0 := "%randstr(n)"
- &reply.Reply-Message := &session-state.Tmp-Integer-0
+ &session-state.challenge-string := "%randstr(n)"
+ &reply.Reply-Message := "Please enter %{session-state.challenge-string}: "
challenge
}
authenticate step2 {
+
Receive a CoA request
-
Send an update for each session we find.
NAS-IP-Address
port = 3799
}
}
+ dictionary {
+ uint32 sent-counter
+ string user-session
+ }
recv CoA-Request {
-# &control.Tmp-String-0 := %sql("SELECT IFNULL(GROUP_CONCAT(CONCAT(nasipaddress,'#',acctsessionid) separator '|'),'') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
-# &control.Tmp-String-0 := %sql("SELECT STRING_AGG(CONCAT(nasipaddress,'#',acctsessionid),'|') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
- &control.Tmp-Integer-0 := 0
- if ("%explode(&control.Tmp-String-0, '|')") {
- foreach &control.Tmp-String-0 {
+# &control.user-session := %sql("SELECT IFNULL(GROUP_CONCAT(CONCAT(nasipaddress,'#',acctsessionid) separator '|'),'') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
+# &control.user-session := %sql("SELECT STRING_AGG(CONCAT(nasipaddress,'#',acctsessionid),'|') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
+ &control.sent-counter := 0
+ if ("%explode(&control.user-session, '|')") {
+ foreach &control.user-session {
if ("%{Foreach-Variable-0}" =~ /([^#]*)#(.*)/) {
&control.NAS-IP-Address := "%{1}"
&control.Acct-Session-Id := "%{2}"
&request -= &Proxy-State[*]
switch &parent.control.NAS-IP-Address {
case "192.0.2.1" {
- &parent.control.Tmp-Integer-0 += 1
+ &parent.control.sent-counter += 1
radius-originate-coa-192.0.2.1
}
default {
}
} # foreach session
}
- if (&control.Tmp-Integer-0) {
+ if (&control.sent-counter) {
&reply += {
- &Reply-Message = "Sent updates for %{control.Tmp-Integer-0} active sessions"
+ &Reply-Message = "Sent updates for %{control.sent-counter} active sessions"
}
ok
} else {
Whether or not the detail.work file reader
retransmits packets which have failed.
+If this configuration item is set to `no`, then
+the reader will ignore any failures, and will
+go to the next entry as soon as the current
+entry is finished, even if it failed to process
+that entry.
+
default = yes
all_dhcp_servers_and_relays = FF02::1:2
interface = en0
port = 547
- listen {
+ listen all_dhcp_servers_and_relays {
type = Solicit
type = Request
transport = udp
# src_ipaddr = ${ipaddr}
}
}
- listen {
+ listen local_network {
type = Request
type = Information-Request
transport = udp
+
namespace:: Needs to be "tacacs" for TACACS+ functionality.
+### TACACS+ Configuration
+
+All of the configuration for processing TACAC+ packets goes here.
+
+
+#### Access-Request subsection
+
+This section contains configuration which is
+specific to processing `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[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.
+
+
+log:: Logging configuration for TACACS+ authentication
+
+
+stripped_names:: Log the full
+`link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]` attribute, as it was
+found in the request.
+
+allowed values: {no, yes}
+
+
+
+auth:: Log authentication requests
+to the log file.
+
+allowed values: {no, yes}
+
+
+
+auth_goodpass:: Log "good"
+passwords with the authentication
+requests.
+
+allowed values: {no, yes}
+
+
+
+auth_badpass:: Log "bad"
+passwords with the authentication
+requests.
+
+allowed values: {no, yes}
+
+
+
+msg_goodpass::
+msg_badpass::
+
+Log additional text at the end of the "Login OK" messages.
+for these to work, the "auth" and "auth_goodpass" or "auth_badpass"
+configurations above have to be set to "yes".
+
+The strings below are dynamically expanded, which means that
+you can put anything you want in them. However, note that
+this expansion can be slow, and can negatively impact server
+performance.
+
+
+
+msg_denied::
+
+The message when the user exceeds the Simultaneous-Use limit.
+
+
+
+session:: Controls how ongoing
+(multi-round) sessions are handled
+
+This section is only useful for ASCII authentications.
+It is the only authentication type which supports
+sending challenges for further data.
+
+
+max:: The maximum number of concurrent ongoing sessions
+
+
+
+max_rounds: The maximum number of round trips which are allowed
+
+This is only enforced for `Authentication-Type = ASCII`, when
+the server replies with `GetUser` or `GetPass` or `GetData`.
+
+Some broken clients will send packets in a loop, forever.
+This configuration helps to catch and prevent that.
+
+
+
+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.
+
+
+
+There is currently no configuration for other packet types.
+
+
+
type:: The type of packet to accept.
Multiple types can be accepted by using multiple
lines of `type = ...`.
-As described in RFC https://tools.ietf.org/id/draft-ietf-opsawg-07.html#rfc.section.5,
-the packet types are:
+As described in https://tools.ietf.org/html/rfc8907[RFC 8907], the packet types are:
+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.
+
+
+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.
+
+
+
+idle_timeout:: Time after which idle
+connections are deleted.
+
+Useful range of values: 5 to 600
+
+
+
+## Clients
+
+A virtual server can have multiple `client` definitions. These clients take priority
+over the global `client` definitions.
+
+See the main `clients.conf` file for documentation on the `client` section.
+
+
+
+This has to be specified for all TACACS+ clients.
+
+There is no standard for TACACS+ over UDP.
+
+
+
+The TACACS+ key, or secret. If a secret is defined, then
+it will be used. All packets coming from this client MUST be
+encrypted with the shared secret.
+
+The `secret` configuration item can be omitted or deleted,
+in which case all of the information (including passwords)
+are sent over the network in the clear. This practice is
+not recommended.
+
+
+
## Authentication-Start
-Set _our_ authentication method to the _requested_ one.
+In general, it is not necessary to set `Auth-Type` here. The packet header
+contains a TACACS `Authentication-Type` with value `PAP`, `CHAP`, etc. That value will
+be used automatically.
+
+The only reason to set `Auth-Type` here is when you want to use a custom
+authentication method, such as `ldap`.
+
+The automatic state machine will ensure that both User-Name
+and User-Password have been provided by this point making
+ASCII authentication equivalent to PAP.
-Do challenge-response here.
+Alternatively, if extra data is required, set
+&reply.Authentication-Status := Getdata
+to request the extra data, which will be in &User-Message in
+the next packet (if the client provides it)
+
+With ASCII methods, GetUser and GetPass typically send a prompt
+for the client to present to the user.
+
+
+
+
## Authentication-Continue
This should handle ASCII methods as PAP with challenge-response.
-### Send
-
-
-
## Authorization
+
NOTE: Proxying of TACACS+ requests is NOT supported.
```
# As of version 4.0.0, the server also supports the TACACS+
# protocol.
+# https://www.rfc-editor.org/rfc/rfc8907
server tacacs {
namespace = tacacs
+ tacacs {
+ Authentication {
+ log {
+ stripped_names = no
+ auth = no
+ auth_goodpass = no
+ auth_badpass = no
+# msg_goodpass = ""
+# msg_badpass = ""
+ msg_denied = "You are already logged in - access denied"
+ }
+ session {
+# max = 4096
+ max_rounds = 4
+# timeout = 15
+ }
+ }
+ }
listen {
type = Authentication-Start
type = Authentication-Continue
# send_buff = 1048576
# src_ipaddr = ""
}
+ limit {
+ max_connections = 256
+ idle_timeout = 60.0
+ }
+ }
+ client tacacs {
+ ipaddr = 127.0.0.1
+ proto = tcp
+ secret = testing123
}
- recv Authentication-Start {
+ recv Authentication-Start {
-sql
- &control.Auth-Type := &Authentication-Type
}
authenticate PAP {
- tacacs_pap
+ pap
}
authenticate CHAP {
- tacacs_chap
+ chap
}
authenticate MSCHAP {
- tacacs_mschap
+ mschap
}
authenticate MSCHAPv2 {
- tacacs_mschap
+ mschap
}
authenticate ASCII {
- fail
+ pap
}
- send Authentication-Start-Reply {
- if (&Authentication-Status == Pass) {
- &reply.Server-Message := "Hello %{User-Name}"
- }
+ send Authentication-Pass {
+ &reply.Server-Message := "Hello %{User-Name}"
+ }
+ send Authentication-Fail {
+ &reply.Server-Message := "Failed login!"
+ }
+ send Authentication-GetUser {
+ &reply.Server-Message := "Username:"
+ }
+ send Authentication-GetPass {
+ &reply.Server-Message := "Password:"
}
recv Authentication-Continue {
"%{Authentication-Continue-Flags}"
"%{User-Message}"
"%{Data}"
}
- send Authentication-Continue-Reply {
- if (&Authentication-Status == Pass) {
- &reply.Server-Message := "Hello %{User-Name}"
- }
- }
recv Authorization-Request {
"%{Authentication-Method}"
"%{Privilege-Level}"
"%{User-Name}"
"%{Client-Port}"
"%{Remote-Address}"
- "%{ArgumentList}"
+ "%{Argument-List}"
}
- send Authorization-Reply {
+ send Authorization-Pass-Add {
&reply.Authorization-Status := Pass-Add
&reply.Server-Message := "authorization-response-server"
&reply.Data := "authorization-response-data"
- &reply.ArgumentList := "key1=var1"
+ &reply.Argument-List := "key1=var1"
}
recv Accounting-Request {
detail
}
accounting Stop {
}
- send Accounting-Reply {
- &reply.Accounting-Status := Success
+ send Accounting-Success {
&reply.Server-Message := "Success"
- &reply.Data := 0x00
+ }
+ send Accounting-Error {
+ &reply.Server-Message := "Error"
}
}
```
# In some cases, it is useful for the module to parse dates instead
# of printing them. In this mode, the format string is ignored.
# Instead, the input arguments are parsed, and the output is an
-# integer containg the requested value.
+# integer containing the requested value.
#
# The following expansions return integer numbers:
#
# program which is executed.
#
# The attributes from the list referenced in the `input_pairs`
-# configuraton item will be placed into environment variables of the executed
+# configuration item will be placed into environment variables of the executed
# program.
#
# Alternatively, by setting the `program` item of the module configuration,
#
# The xlat should be passed a list of attributes to encode. Each attribute
# (after template expansion) will be added to a list of attributes to include
-# in the JSON document. If any of the attributes given are preceeded with a `!`
+# in the JSON document. If any of the attributes given are preceded with a `!`
# then they are removed from the list. Once all attributes have been processed,
# the JSON document will be created using this list.
#
#
# This connection pool is used for LDAP queries run as the administrative user.
#
- # All LDAP operations are perfomed asynchronously, meaning that many queries
+ # All LDAP operations are performed asynchronously, meaning that many queries
# can be active on a single connection simultaneously.
#
pool {
#
# open_delay:: Open delay (in seconds).
#
- # How long must we be above the target utilisation for connections to be openned.
+ # How long must we be above the target utilisation for connections to be opened.
# open_delay = 0.2
#
#
status_check {
#
- # type:: You can specify any type of request packet here,
- # e.g. 'Access-Request', 'Accounting-Request' or
+ # type:: You can specify any type of request packet here,
+ # e.g. 'Access-Request', 'Accounting-Request' or
# 'Status-Server'.
#
# Status-Server is recommended as other packet types may
- # be interpreted incorrectly, or proxied to a remote
- # server defeting the purpose of the status checl
+ # be interpreted incorrectly, or proxied to a remote
+ # server defeting the purpose of the status check
#
# If you specify another type of packet, it MUST be listed
# as an allowed `type`, above.
# username = "user"
#
- # password:: Password to use in conjuction with the above user name
+ # password:: Password to use in conjunction with the above user name
# for SMTP authentication.
#
# password = "secret"
# Any requests to allocate a connection handle beyond
# this number will cause a temporary handle to be allocated.
# This is less efficient than the block allocation so
- # `max` should be set to reflect the number of outstanding
- # requests expected at peak load.
+ # `max` should be set to reflect the number of outstanding
+ # requests expected at peak load.
max = 100
#
#
# [NOTE]
# ====
- # If you want to have multiple SQL modules re-use the same connection pool, use `pool = name`
+ # If you want to have multiple SQL modules reuse the same connection pool, use `pool = name`
# instead of a `pool` section.
#
# e.g:
#
# data::
#
-# Either `octets` or `string` type data, litteral or expanded attributes.
-# If `string` type data contains a representaion of hex data, e.g. 0xabcdef
+# Either `octets` or `string` type data, literal or expanded attributes.
+# If `string` type data contains a representation of hex data, e.g. 0xabcdef
# that is first converted to `octets`.
#
# offset::
#
# It's recommended to only enable this config item
# for debugging, or in conjunction with
- # move_failure_message_to_parent where the upsteam
+ # move_failure_message_to_parent where the upstream
# relay is trusted and secure.
#
# send_failure_message = no
# received only contains the DN, or, if the deletion is reported as part of
# the initial refresh phase it may only be the UUID.
#
-# Active Direcory
+# Active Directory
# ---------------
# Active Directory will only provide updates from the time the query started;
-# there is no mechanism to catch up on changes which occured while the
+# there is no mechanism to catch up on changes which occurred while the
# client was not connected. In addition it is not possible to apply a
# filter to the query so that only a subset of objects are considered.
#
#
# Specify a map of LDAP attributes to FreeRADIUS dictionary attributes.
#
- # The result of this map determines how attriubtes from the LDAP
+ # The result of this map determines how attributes from the LDAP
# query are presented in the requests processed by the various
# "recv" sections below.
#
# - the right hand side is LDAP attributes which will be
# included in the query.
# - only = and += are valid operators with = setting a
- # single instance of the attriubte and += setting as
+ # single instance of the attribute and += setting as
# many as the LDAP query returns.
#
# Protocol specific attributes must be qualified e.g. &Proto.radius.User-Name
# The only extensible match filters supported are the Active
# Directory bitwise AND and OR.
#
- # A suitable filter, to only receive notificaitons regarding
+ # A suitable filter, to only receive notifications regarding
# normal user accounts could be:
#
# (userAccountControl:1.2.840.113556.1.4.803:=512)
#
#
-# Within this virual server we provide only an Autz-Type Status-Server section
+# Within this virtual server we provide only an Autz-Type Status-Server section
# whose task is to perform the resource checks and sets the status of the
# "control module"
#
chap
}
- #
- # [NOTE]
- # =====
- # In order to use MSCHAP / MSCHAPv2 with TACACS, the instance of
- # `rlm_mschap` being called must be configured correctly.
- # The default configuration referrs to the attributes relevant to
- # RADIUS. The attributes have different names in TACACS.
- #
- # If both RADIUS and TACACS virtual servers are defined and both
- # are using `rlm_mschap`, then two instances of the module will
- # need to be configured, one for each protocol.
- #
- # See the `mschap` module for more details.
- #
authenticate MSCHAP {
mschap
}
# and User-Password have been provided by this point making
# ASCII authentication equivalent to PAP.
#
- # Alternatively, if extra data is requried, set
+ # Alternatively, if extra data is required, set
# &reply.Authentication-Status := Getdata
# to request the extra data, which will be in &User-Message in
# the next packet (if the client provides it)