The tacacs Virtual Server
The tacacs virtual server processes TACACS+ packets.
# https://www.rfc-editor.org/rfc/rfc8907
The Virtual Server
This is the tacacs virtual server.
server tacacs {
- namespace
-
Needs to be "tacacs" for TACACS+ functionality.
namespace = tacacs
TACACS+ Configuration
All of the configuration for processing TACACS+ packets goes here.
tacacs {
Authentication subsection
This section contains configuration which is specific to processing
Authentication 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.
Authentication {
- 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.
session {
- max
-
The maximum number of concurrent ongoing sessions
# max = 4096
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.
max_rounds = 4
- 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.
}
listen {
- type
-
The type of packet to accept.
Multiple types can be accepted by using multiple lines of type =
….
As described in RFC 8907, the packet types are:
type = Authentication-Start type = Authentication-Continue type = Authorization-Request type = Accounting-Request
- transport
-
The transport protocol.
Only tcp is allowed. TACACS+ does not use UDP or TLS.
transport = tcp
Protocols
- tcp { … }
-
TCP is configured here.
tcp {
| Don’t change anything if you are not sure. |
- port
-
The port where we accept packets.
The port should be 49 for a production network.
port = 49
- ipaddr
-
The IP address where we accept packets.
ipaddr = *
- interface
-
Interface to bind to.
# interface = eth0
- max_packet_size
-
Our max packet size. may be different from the parent.
# max_packet_size = 4096
- recv_buff
-
How big the kernel’s receive buffer should be.
# recv_buff = 1048576
- send_buff
-
How big the kernel’s send buffer should be.
# send_buff = 1048576
- src_ipaddr
-
IP we open our socket on.
# src_ipaddr = "" }
- 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_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 are deleted.
Useful range of values: 5 to 600
idle_timeout = 60.0
- dynamic_timeout
-
Time after which idle dynamic clients are deleted.
dynamic_timeout = 600.0 } }
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.
client tacacs {
ipaddr = 127.0.0.1
This has to be specified for all TACACS+ clients.
There is no standard for TACACS+ over UDP.
proto = tcp
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.
secret = testing123 }
Authentication-Start
Recv
In general, it is not necessary to set Auth-Type in this section.
The packet header contains a TACACS Authentication-Type with value
PAP, CHAP, etc. That value will be used automatically by the
server to set Auth-Type.
The only reason to set Auth-Type here is when you want to use a
custom authentication method, such as ldap. You should ONLY set
Auth-Type := ldap when the packet contains Authentication-Type
= PAP and the passwords in LDAP are stored in "crypt" or hashed
form.
recv Authentication-Start {
-sql
}
authenticate PAP {
pap
}
authenticate CHAP {
chap
}
authenticate MSCHAP {
mschap
}
authenticate MSCHAPv2 {
mschap
}
LDAP authentication will only work with PAP authentication
authenticate ldap { if (Authentication-Type != PAP) { %log.warn("The packet is not PAP. LDAP authentication is likely to fail!") }
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.
Alternatively, if extra data is required, set reply.Packet-Type := ::Authentication-GetData to request the extra data, which will be in User-Message in the next packet (if the client provides it)
authenticate ASCII {
pap
}
Send
Note that "follow" is officially deprecated, and is not supported.
send Authentication-Pass {
reply.Server-Message := "Hello %{User-Name}"
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_authentication_pass
}
send Authentication-Fail {
reply.Server-Message := "Failed login!"
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_authentication_fail
}
With ASCII methods, GetUser and GetPass typically send a prompt for the client to present to the user.
send Authentication-GetUser {
reply.Server-Message := "Username:"
}
send Authentication-GetPass {
reply.Server-Message := "Password:"
}
Authentication-Continue
This section handles responses to challenges for Authentication-Type
= ASCII
i.e. The server receives an Authentication-Start packet with
Authentication-Type = ASCII, and replies with a challenge. The
client returns the username or password in an
Authentication-Continue packet. The server should then check the
username or password.
The TACACS+ protocol puts the response username or password into the "data" field. For simplicity, the server copies that field into the User-Name or User-Password attribute as appropriate. This automatic copyinh means that it is a lot easier to understand and configure TACACS+.
Recv
Receive Authentication-Continue packet. When this section is done
and has a User-Password, the server will run an authenticate
… { } section. It will then call one of the send sections to
send the reply.
recv Authentication-Continue {
"%{Authentication-Continue-Flags}"
"%{User-Message}"
"%{Data}"
}
Authorization
Recv
recv Authorization-Request {
"%{Authentication-Method}"
"%{Privilege-Level}"
"%{Authentication-Type}"
"%{Authentication-Service}"
"%{User-Name}"
"%{Client-Port}"
"%{Remote-Address}"
"%{Argument-List}"
}
Send
Add the arguments to whatever the user entered.
send Authorization-Pass-Add {
reply.Server-Message := "authorization-response-server"
reply.Data := "authorization-response-data"
reply.Argument-List := "key1=var1"
}
Replace whatever the user entered with the following arguments
send Authorization-Pass-Replace {
reply.Server-Message := "authorization-response-server"
reply.Data := "authorization-response-data"
reply.Argument-List := "key1=var1"
}
Reject the request
send Authorization-Fail {
}
Accounting
Accounting "type" Sections
Each type of accounting packet is run through its own section. The section MUST return "ok" to indicate that it successfully handled the accounting data.
The "ok" return code is typically set automatically when an accounting module succeeds in its work. The explicit "ok" here is just so that the default configuration will return success for all accounting packets.
First packet for a session
accounting Start {
ok
}
Updates a previous start
accounting Watchdog-Update {
ok
}
Updates a session
accounting Watchdog {
ok
}
Stops a session
accounting Stop {
ok
}