Problem solve Get help with specific problems with your technologies, process and projects.

Router Expert: TACACS+ tricks with scripts, part 2

Our router expert looks at some scripts for controlling the tac_plus daemon and accounting log processing.

Read about Michael

Continuing from TACACS+ tricks with scripts, part 1, last month's tribute to resourcefulness and sloth, we are going to look at some scripts for controlling the tac_plus daemon and accounting log processing.

Running tac_plus the old-fashioned way
There is not much to "starting" the tac_plus daemon. Tac_plus, like most Unix service daemons, needs to run as root. The standard build installs the daemon in /usr/local/bin. To launch the standard service from the command line, use /use/local/tac_plus –C <config file>. The only required control flag is –c, which tells the daemon the location the tac_plus configuration file (expressed as an explicit path to the configuration file). Some of the other control options include:

The –p <port> flag, to define an alternative TCP service port to the default port 49 The –L flag, to force DNS resolution of the clients sending requests
The –P flag, the daemon only parses the config file for errors and exits
The –d <value> flag, which enables debugging and the debug level

Regardless of the options, when the daemon starts, it creates a process number identification (PID) file in the /etc directory. (An alternative location can be defined by editing the makefile prior to compiling the daemon.) When started in standard mode, this file is named If an alternative TCP service port is defined, the port number is appended to the PID file name. For example, if the tac_plus service were started to listen on port 6700, then the PID file name would be

User account and profile information is loaded into RAM when the service is started. So any changes made to the configuration file will not take effect until the service is restarted. When debugging is enabled (-d), information about the tac_plus daemon's operational state and any debugging information is sent to a file named tac_plus.log, located in the /var/tmp/ directory. This is the same directory the tac_plus accounting file is stored, by default. In order to stop the tac_plus service or reload the configuration, a service signal handler must be sent to the daemon. The built-in shell command kill is used for sending signal handlers. One of the more commonly used handlers is kill –9, known as the "stop with extreme prejudice" mode. While it stops the process, it does so without any remorse, so no event record is issued. While you can stop the tac_plus daemon using this kill option, no state tracing will be sent to the tac_plus.log file. To stop the process gracefully, use the kill option TERM (kill –TERM). This will shut down the service properly, issuing a state change notice to the log file. To reload the configuration, the signal handler –USR1 or –HUP can be used to restart the process.

Checktacplus (click to download)

The checktacplus script is an uber wrapper for starting and stopping the tac_plus daemon. Its default action is to simply start the tac_plus daemon listening on the default TCP port using a configuration file that is defined in the script. To stop the tac_plus service, simply run the command followed by the control flag –k. To have the daemon reload the configuration file, run the command with the –r flag. Regardless of the exercises, the script informs you of the following:

[orion:martin/Articles/1b-TACACS-Accounting] martin# ./
tac_plus is down
Restarting tac_plus PID 623
[orion:martin/Articles/1b-TACACS-Accounting] martin#

It includes the function being performed, its status and process ID information:

[orion:martin/Articles/1b-TACACS-Accounting] martin# ./ -k
Shutting Down the tac_plus service PID 723
[orion:martin/Articles/1b-TACACS-Accounting] martin#

The script's default mode is intended to be used as a daemon status checker. Run either from the command line or have CRON run the script at a regular interval to check and see if the tac_plus service is running. If not, restart the service. Setting up the script to be run from CRON is easy. Since services like tac_plus need to be run as root, the script also needs to be run as root and/or from root's crontab file. To add a job to root's crontab file, su to root and run the command crontab –e, then add the command you want to run and when you want to run it. Commands executed by CRON are controlled by the five time and date variables that precede the command call. These values are:

Field 1 = Minutes, expressed as a number between 0 and 59
Field 2 = Hours, expressed as a number between 0 and 23
Field 3 = Day of the month, expressed as a number between 1 and 31
Field 4 = Month of the year, expressed as a number between 1 and 12
Field 5 = Day of the week, expressed as a number between 0 and 6

For example, to have the checktacplus script run every 15 minutes, the crontab entry would look like this (in this example all of the output is sent to dev null):

15 * * * * /usr/local/checktacplus 2>&1 /dev/null

If you're interested in having the status data sent to you via e-mail, you can pipe the command output to the mail program. Here's an example crontab entry:

15 * * * * /usr/local/bin /checktacplus I mail -s "`date +%T` - tac_plus running on port 49 on `hostname` is up PID `cat /etc/`"

Additionally, the checktacplus script can start the daemon to listen on a different TCP port and use an alternative configuration file. This option is intended to make it easier to manage multiple daemon instances on a single server (an approach used in large environments to segment accounting data) To assist in managing a multiple daemon environment, the script checks the process table each time it runs and prints out a list of the tac_plus processes on the server:

PID Service Config File Port
991 /usr/sbin/tac_plus /etc/tacacs.conf 4489
1384 /usr/sbin/tac_plus /etc/tacacs.conf
1405 /usr/sbin/tac_plus /etc/tacacs.conf 56674
2931 /usr/sbin/tac_plus /etc/tacacs2.conf 6638

Like most scripts, to function properly some customization is needed. The locations for the tac_plus daemon and default configuration file needs to be set in the scripts global variable section. The tac_plus daemon creates a PID file in the /etc directory called If the environment uses a TCP port other than the default, then the default PID file needs to be defined as well:

# Global Variables
# Tac_plus deamon location
# Tac_plus default config

Here is a complete list of command flags and functions:

  • Start the default service = checktacplus
  • Stop the default service = checktacplus –k
  • Reload the configuration of the default service = checktacplus -r
  • Start an instance running on a non-standard port, using the default configuration = checktacplus –p <port>
  • Start an instance running on a non-standard port, using an alternative configuration file = checktacplus –c <port> <configuration file>
  • Reload an instance running on a non-standard port = checktacplus –pr
  • Stop an instance running on a non-standard port = checktacplus –kp
  • Review the help information and command options = -h

Tacdebug (click to download)
The tacdebug script does just what the name says; it debugs tac_plus. The tac_plus daemon has extensive debugging options. Tac_plus debugging is enabled using the –d control flag (following the configuration file definition) and a base2 byte value to set the debug mode. Here is a list of the debug options and their assigned byte values:

Start service and parse the configuration file to daemon log file = 2
Start service in forked mode = 4
Start service in authorization debug mode = 8
Start service in authentication debug mode = 16
Start service in password processing debug mode = 32
Start service in accounting debug mode = 64
Start service in configuration debug mode = 128
Start service in packet debug mode = 256
Start service in hex debug mode = 512
Start service in MD5 debug mode = 1024
Start the service in XOR debug mode = 2048
Start the service in clean flag debug mode = 4096
Start the service in substitute flag debug mode = 8192
Start the service in proxy debug mode = 16384
Start the service in max sessions debug mode = 32768
Start the service in debug lock flag mode = 65536

The tacdebug script, like checktacplus, is a wrapper. The script "cleans up" the debugging interface to make it more efficient and a little more user-friendly. First, it converts the numeric mode interface to three-letter control flags that are a little easer to remember. Then, operationally, the daemon is loaded in a debug mode and the script loads the daemon log file in a text parser so that the administrator can see the output results. This provides a quick means of changing debug modes and viewing the output when troubleshooting. Here is a complete list of command flags and functions:

  • Stop the tac_plus service = -k (needs to be run after the parser is exited with ctrl-c)
  • Start the service, parse configuration file to the log file = -par
  • Start the service in fork mode = -for
  • Start the service in authorization debug mode = -adz
  • Start the service in authentication debug mode = -auto
  • Start the service in password debug mode = -pas
  • Start the service in configuration debug mode = -cfg
  • Start the service in packet debug mode = -pak
  • Start the service in MD5 debug mode = -md5
  • Start the service in Low Level Encrypt/Decrypt debug mode = -enc
  • Start the service in proxy debug mode = -pro
  • Start the service in max-session debug mode (if compiled) = -max
  • Review the help information and command options = -h

Tacreport (click to download)
The tacreport script processes tac_plus accounting and generates reports on user terminal access sessions, IOS command usage and system events. While quite useful, authentication, authorization, and accounting (AAA) logs can be cumbersome to process at times. The tac_plus account file's variable length and tab-delimited format makes generic reporting difficult, thus requiring some kind of customization of the report tool. This script processes the raw accounting file and generates some useful administration reports by parsing the number of fields down to only the relevant data. The parsing is done with AWK, so additional reports can be added easily. Each report is generated as a text file. The script can either direct the output to the terminal display or send it via e-mail to users defined within the script. The six report options are:

  • User Requested Disconnects: Reports on user terminal sessions that have been terminated, normally using the <exit> or <logout> command.
  • Idle Session Disconnects: Reports on user terminal sessions that have been terminated due to session inactivity.
  • Lost Carrier Disconnects: Reports on user terminal sessions terminated due to modem or VTY disconnect.
  • Failed logins attempts: Reports on failed user terminal sessions, due to authentication failures.
  • Command Accounting: Reports on the commands executed on network access devices (NADs) and who executed them.
  • System Event Activity: Reports on NAD system accounting events.

Of the six reports, four are about user access activity. In order to collect all of the data needed to generate the reports properly, the following AAA accounting features must be enabled on the NAD:

<aaa accounting exec default start-stop group tacacs+>
<aaa accounting send stop-record authentication failure>

The user activity reports are generated using the terminal session STOP accounting records as the search key. With START-STOP accounting enabled, when each terminal session starts (along with every other NAD event) a NAD unique task_id is assigned. (Each NAD generates and assigns its own task_ids, starting with ID 1, and the counter is reset after a reboot. So while the task_id is unique to the NAD, there is the possibility that two NADs could assign the same task_id for different events.) The same task_id is issued with the START and STOP accounting event for each terminal session. For reporting purposes, tracking and reporting in disconnect causes is more valuable from an administration standpoint and ironically easier. Terminal session START events are generic:  

Thu May 1 16:05:00 2003         martin tty6         start task_id=65         timezone=EDTservice=shell         start_time=1051819498

This provides little data, aside from the session start timestamp. However, the STOP record provides a great deal of information:

Thu May 1 16:06:30 2003         martin tty6         stop         task_id=65         timezone=EDTservice=shell         start_time=1051819498         disc-cause=1         pre-session-time=17         elapsed_time=90

Specifically, you can find out how long the session was (elapsed_time), how long it took the user to authenticate (pre-session-time) and why the session was terminated (disc-cause). There are 17 "BASE" disconnect-case attribute value codes for describing why a session was terminated. There are an additional 25 optional "EXTENDED" disconnect cause codes, used in conjunction with the BASE codes, that are used to describe the event that caused the connection to be terminated. The majority of the disconnect codes and extended descriptor codes are esoteric. The script generates reports on the three most common events: User_Request, Idle-Timeout, and Lost Carrier.

The failed user attempt report is dependent on the AAA accounting option <aaa accounting send stop-record authentication failure> being enabled. Unless the network access server (NAS) is configured, failed login attempts are not logged to the accounting server. This is done to avoid the possibility of having the server DOSed by hammering the NAD with bogus logins and the server becoming overloaded or having the accounting file overgrow its file system. Potential attacks aside, this option is a great way to detect unauthorized login attempts that could indicate "recon snooping," which often goes unnoticed in large environments.

The remaining two reports, command and system event accounting reports, are quite straightforward. They report on what is enabled on the NAD in terms of command accounting and generic system events. While ideally each of the reports should be run daily, the command and system reports are really a must if you are interested in being able to track activity on your NADs.

In order for the script to function properly, the following global variables need to be defined within the script:

# Location of the report file
# User list to mail report results to,
# Location of accounting file

The script will not run without a report definition. If no output option (Mail or Terminal) is defined, the script will just generate the report and exit. The report files are deleted prior to each report run. If you want to save the reports, use the mail option. Here is a complete list of command flags and functions:

  • User Requested Disconnects = -ur
  • Idle Session Disconnects = -ut
  • Lost Carrier Disconnects = -lc
  • Failed logins attempts = -lf
  • Command Activity = -a
  • System Event Activity = -e
  • To display the report data to the terminal, use the -c flag following the report definition = taccreport <report flag> -c
  • To send the report via e-mail, use the -m flag following the report definition = taccreport <report flag> -m
  • Search the account file by task_id to see the entire accounting record use the -s in combination with the task id following the report flag = taccreport <report flag> -s <task_id>
  • Review the help information and command options = -h

AAA accounting file format

The taccreport script is a great tool for quick reporting. However, if you want to create your own reports, extend the tool, or simply make sense of the data, you will need to know a little something about the accounting attribute values. For starters, every AAA accounting record contains ten logical informational fields, along with a variable number of optional fields. A single record is sent for each event. A single record is made up of both the static and optional AV values sent as a tab-delimited string and written to the accounting file. The logical "static" event fields are:

  • Timestamp = Day, month, time, and year
  • NAS name = Network access server, the router or device IP address
  • Username = The user name associated with the action
  • TTY port = The VTY or TTY port the user was connected to on the NAS
  • SRC host address = The IP address that the connection was opened from
  • Record type = Describes the state change on the NAS expressed as a Start and/or Stop record
  • Task_id = Unique ID associated with an event or action. The start and stop records will both have the same task id
  • Timezone = The time zone the timestamp was generated in (configured on the NAD)
  • Service = The user service used (typically "shell"); PPP, connection, system, and tty-daemon are also available.
  • Start_time = When the action started, in seconds since the epoch (12:00AM Jan 1 1970)

The "optional" descriptors fields available for the NAS to report with are:

  • Unknown = Used when the user is unknown
  • Elapsed_time = Time in seconds taken for the action
  • Priv_level = The privilege level associated with the action
  • Protocol = The protocol associated with the event
  • Cmd = The command associated with the event
  • Bytes_in = The number of input bytes associated with session
  • Bytes_out = The number of output bytes associated with session
  • Paks_in = The number of input packets associated with session
  • Paks_out = The number of output packets associated with session
  • Pre-session-time = The length of time from the start of the session to when authentication has been completed
  • Disc-cause = The reason a session was terminated, used with start and stop records
  • Disc-cause-ext = The specific action that resulted in the session termination (optional)
  • Stop_time= When the action started, in seconds since the epoch (12:00AM Jan 1 1970)

Here ends the advanced TACACS+ series. I hope you have found this series helpful and informative. Next month we'll take a look at IOS methods for authenticating network access using lock and key ACLs and the Auth-Proxy. So stay tuned.

Was this article helpful to you? Do you have suggestions for topics you'd like to see covered? Please e-mail us and let us know!

This was last published in May 2003

Dig Deeper on IP Networking

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.