6

How do you configure a TACACS+ tac_plus server on Ubuntu 16.04 that authenticates against Microsoft Active Directory?

9

UPDATE 01/10/2018: Added missing library to enable Perl regular expression support (libpcre3-dev)

UPDATE 11/07/2017: There is a bug in MAVIS. If you are having trouble using LDAPS on port 636 or 3269, completely remove the USE_TLS configuration variable from your tac_plus.cfg. This will fix the problem. I've emailed the author with my findings.

This guide will walk you through setting up a TACACS+ server (using the pro-bono version of tac_plus) on Ubuntu Server 16.04 that authenticates against Active Directory. The guide assumes you are familiar with installing/configuring Ubuntu Server and can deploy a new Ubuntu server on a LAN with internet access.

Start by deploying a new Ubuntu 16.04 server with only the standard system utilities and OpenSSH server packages. You'll be ready to proceed whenever the install has completed and you have verified network connectivity to the LAN and internet.

SSH to the new server and enter the commands listed below (follow the instructions when prompted):

sudo apt-get update && sudo apt-get upgrade
sudo apt-get install build-essential libnet-ldap-perl libpcre3-dev
cd ~
wget http://www.pro-bono-publico.de/projects/src/DEVEL.tar.bz2
bzip2 -dc DEVEL.tar.bz2 | tar xvfp -
cd PROJECTS
sudo make
sudo make install
sudo mkdir /var/log/tac_plus
sudo mkdir /var/log/tac_plus/access
sudo mkdir /var/log/tac_plus/accounting
sudo mkdir /var/log/tac_plus/authentication

NOTE: /var/log/tac_plus (and the sub folders) need to have chmod 755 permissions. On Ubuntu, these permissions should be inherited from /var/log whenever you create the folders for tac_plus. If tac_plus is not logging, you'll need to verify the chmod permissions of the /var/log/tac_plus folder and adjust if necessary. You can verify the chmod permissions by running the following command:

stat --format '%a' /var/log/tac_plus

At this point you've installed all the necessary packages to run tac_plus and the mavis authentication backend. To make sure everything was installed correctly, run the following command and compare your output:

/usr/local/lib/mavis/mavis_tacplus_ldap.pl < /dev/null
Default server type is 'tacacs_schema'. You *may* need to change that to 'generic' or 'microsoft'.
LDAP_HOSTS not defined at /usr/local/lib/mavis/mavis_tacplus_ldap.pl line 277, <DATA> line 755.

If there's some error message saying "Can't locate Net/LDAP.pm in @INC", you'll need to double-check the commands at the beginning of the guide. Make sure they all completed successfully without any errors. If your output matches the above, continue on and enter the following commands:

cd /usr/local/etc
sudo touch tac_plus.cfg
sudo chmod 755 tac_plus.cfg
sudo nano tac_plus.cfg

After typing in the commands listed above, you find yourself in nano editing an empty tac_plus.cfg. It's now time to configure tac_plus to talk to your Active Directory environment. My example config is shown below. Modify it to suit your needs and save it to /usr/local/etc/tac_plus.cfg (requires chmod 755)

You'll also need to create an Active Directory service account for tac_plus to use to query Active Directory. I would suggest creating an account called "svc_tacplus" and only make it a member of "Domain Users". I would also recommend disabling password expiration (pretty standard practice for AD service accounts).

#!/usr/local/sbin/tac_plus
id = spawnd {
        listen = { address = 0.0.0.0 port = 49 }
        #Uncomment the line below for IPv6 support
        #listen = { address = :: port = 49 }
        spawn = {
                instances min = 1
                instances max = 10
        }
        background = yes
}

id = tac_plus {
        access log = /var/log/tac_plus/access/%Y/%m/access-%m-%d-%Y.txt
        accounting log = /var/log/tac_plus/accounting/%Y/%m/accounting-%m-%d-%Y.txt
        authentication log = /var/log/tac_plus/authentication/%Y/%m/authentication-%m-%d-%Y.txt

        mavis module = external {
                setenv LDAP_SERVER_TYPE = "microsoft"
                #If you are using Microsoft Global Catalog with secure LDAP (SSL)
                #setenv LDAP_HOSTS = "ldaps://10.0.0.100:3269"
                #If you are using Microsoft Global Catalog with regular LDAP (non-SSL)
                setenv LDAP_HOSTS = "10.0.0.100:3268"
                setenv LDAP_BASE = "DC=domain,DC=name"
                setenv LDAP_SCOPE = sub
                setenv LDAP_FILTER = "(&(objectClass=user)(objectClass=person)(sAMAccountName=%s))"
                setenv LDAP_USER = "svc_tacplus@domain.name"
                setenv LDAP_PASSWD = "ServiceAccountPassword"
                #Setting UNLIMIT_AD_GROUP_MEMBERSHIP to 0 will cause a NACK response if the AD account is a member of more than one security group
                setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
                #I'm not 100% sure what EXPAND_AD_GROUP_MEMBERSHIP does
                setenv EXPAND_AD_GROUP_MEMBERSHIP = 0
                #Clear default setting of tacplus for AD_GROUP_PREFIX
                setenv AD_GROUP_PREFIX = ""
                #Setting REQUIRE_TACACS_GROUP_PREFIX to 1 will cause a NACK response if the AD account is not a member of a security group with the required prefix
                setenv REQUIRE_TACACS_GROUP_PREFIX = 0
                #DO NOT SET THE USE_TLS ENVIRONMENT VARIABLE
                #TLS WILL AUTOMATICALLY BE ENABLED IF NEEDED
                #FORCING THIS VARIABLE TO 1 WILL BREAK MAVIS IF TLS IS NEEDED
                #setenv USE_TLS = 0
                exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
        }

        login backend = mavis
        user backend = mavis
        pap backend = mavis

        host = world {
                #Allow any IPv4 device
                address = 0.0.0.0/0

                #Uncomment the line below for IPv6 support
                #address = ::/0

                #Uncomment the line below to inject a login prompt
                #prompt = "Put your custom welcome message here.\n"

                #Change this to your own secure TACACS+ key
                key = "cisco"
        }

        #Example group that grants admin on Cisco IOS/XE/XR and NX-OS
        group = admin {
                #Permit all services by default
                default service = permit

                #Users will need to re-enter their AD password for the enable password (feel free to customize this however you want)
                enable = login

                service = shell {
                        #Permit all commands
                        default command = permit

                        #Permit all command attributes
                        default attribute = permit

                        #Set privilege level to 15 on IOS/XE
                        set priv-lvl = 15

                        #Uncomment the line below for NX-OS support
                        #set shell:roles="\"network-admin vdc-admin\""

                        #Uncomment the line below for IOS XR support
                        #set task = "#root-system"
                }


        }

        #Example AD user mapping
        user = jsmith {
                password = mavis
                member = admin
        }
}

Cisco AAA TACACS+ NOTES: Do not uncomment the NX-OS / IOS XR custom attributes if you do not need them. This will give your tac_plus server the highest compatibility possible. Many older IOS versions (especially any version <12.2) will not work with a TACACS+ server that sends additional attributes. For example, a Cisco 2950 switch can only run IOS 12.1 and will not work with tac_plus if tac_plus is configured to send NX-OS / IOS XR attributes. If everything appears to be configured correctly and you're still having trouble, try upgrading your Cisco device to the latest IOS image it can run. Cisco's support site will provide you with the recommended version for any device that is not obsolete.

After you've saved your tac_plus.cfg file, it's now time to test it. Run the following command and make sure there are no errors:

/usr/local/sbin/tac_plus -P /usr/local/etc/tac_plus.cfg

If tac_plus reports any errors, you'll need to edit the tac_plus.cfg file again and correct the errors. Do not proceed further in the guide until you've corrected all errors. See http://www.pro-bono-publico.de/projects/tac_plus.html for a complete configuration reference. You may also want to view the file /usr/local/lib/mavis/mavis_tacplus_ldap.pl for a detailed explanation of the LDAP variables.

Once your tac_plus.cfg file is error free, you'll want to verify your Active Directory configuration is correct. Run the following command to test it (replace SomeUserName / SomeUserPassword with the username and password of the Active Directory account you want to test):

/usr/local/bin/mavistest -d -1 /usr/local/etc/tac_plus.cfg tac_plus TACPLUS SomeUserName SomeUserPassword

{mavistest debug output omitted}

Input attribute-value-pairs:
TYPE                TACPLUS
TIMESTAMP           mavistest-2501-1509172787-0
USER                SomeUserName
PASSWORD            SomeUserPassword
TACTYPE             AUTH


Output attribute-value-pairs:
TYPE                TACPLUS
TIMESTAMP           mavistest-2501-1509172787-0
USER                SomeUserName
RESULT              ACK
PASSWORD            SomeUserPassword
SERIAL              QrWVmlId0OZADDRU/hy/pw=
DBPASSWORD          SomeUserPassword
TACMEMBER           [List of Active Directory security groups]
TACTYPE             AUTH

Look specifically at the RESULT value. If you got ACK that means your Active Directory query was successful. If you got NACK, BFD, or ERR...that means something went wrong. You'll want to double-check your Active Directory environment variables in the tac_plus.cfg file. A handy tool that might help you correctly configure the environment variables is LDAP Browser: http://www.ldapbrowser.com/download.htm Do not proceed further until you can run the mavistest and get an ACK result on one or more Active Directory accounts.

The last steps are the easiest. We just need to set the tac_plus daemon to start on boot, and to start the tac_plus service itself. Run the following commands:

cd /etc/init.d
sudo cp ~/PROJECTS/tac_plus/extra/etc_init.d_tac_plus /etc/init.d/tac_plus
sudo chmod 755 /etc/init.d/tac_plus
sudo chown root:root /etc/init.d/tac_plus
sudo update-rc.d tac_plus defaults
sudo service tac_plus start

The above commands install the tac_plus init.d script so that the tac_plus service will start at boot. It also starts the tac_plus service manually so you don't have to reboot to start using your new TACACS+ server. To verify the tac_plus service started successfully, run the following command:

sudo netstat -tulpen

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 0.0.0.0:49              0.0.0.0:*               LISTEN      0          25680       1911/tac_plus: 0 co
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          16105       1023/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      0          16113       1023/sshd

If you see tac_plus listening on TPC port 49, the tac_plus service is running and you are ready to begin pointing all of your TACACS+ enabled devices at your new TACACS+ server. If you don't see output similar to what's shown above, you'll need to double-check everything and locate/correct the problem.

If you make any changes to /usr/local/etc/tac_plus.cfg, you'll need to restart the tac_plus service before they will take effect. See below for an example:

sudo nano /usr/local/etc/tac_plus.cfg
sudo service tac_plus stop
sudo service tac_plus start

If tac_plus fails to start, it means there are errors in your tac_plus.cfg file. You'll need to correct them before the service will start again. The following commands can help you identify the error(s) in your tac_plus.cfg file:

sudo systemctl status tac_plus.service
sudo journalctl -xe
/usr/local/sbin/tac_plus -P /usr/local/etc/tac_plus.cfg

Hopefully you found this guide helpful. If you find any mistakes or anything that's hard to follow, please let me know. I sat down and wrote this guide because I had to go through several other guides / blogs to find all the information I needed to configure tac_plus for my environment.

Listed below are the environment variables from mavis_tacplus_ldap.pl and some Cisco AAA configuration examples for easy reference:

Environment variables from mavis_tacplus_ldap.pl:

LDAP_SERVER_TYPE
    One of: generic tacacs_schema microsoft
    Default: tacacs_schema

LDAP_HOST
    Space-separated list of LDAP URLs or IP addresses or hostnames
    Examples: "ldap01 ldap02", "ldaps://ads01:636 ldaps://ads02:636"

LDAP_SCOPE
    LDAP search scope (base, one, sub)
    Default: sub

LDAP_BASE
    Base DN of your LDAP server
    Example: "dc=example,dc=com"

LDAP_FILTER
    LDAP search filter
    Defaults depend on LDAP_SERVER_TYPE:
    - generic:          "(uid=%s)"
    - tacacs_schema:    "(&(uid=%s)(objectClass=tacacsAccount))"
    - microsoft:        "(&(objectclass=user)(sAMAccountName=%s))"

LDAP_FILTER_CHPW
    LDAP search filter for password changes
    Defaults depend on LDAP_SERVER_TYPE:
    - generic:          "(uid=%s)"
    - tacacs_schema:    "(&(uid=%s)(objectClass=tacacsAccount)(!(tacacsFlag=staticpasswd))"
    - microsoft:        "(&(objectclass=user)(sAMAccountName=%s))"

LDAP_USER
    User to use for LDAP bind if server doesn't permit anonymous searches.
    Default: unset

LDAP_PASSWD
    Password for LDAP_USER
    Default: unset

AD_GROUP_PREFIX
    An AD group starting with this prefix will be used for tacacs group membership.
    Default: tacacs

REQUIRE_AD_GROUP_PREFIX
    If set, user needs to be in one of the AD_GROUP_PREFIX groups.
    Default: unset

UNLIMIT_AD_GROUP_MEMBERSHIP
    If unset, the number of groups a user can be member of is limited to one.
    Default: unset

EXPAND_AD_GROUP_MEMBERSHIP
    If set, AD group memberships will be expanded.
    Default: unset

USE_TLS (DO NOT SET THIS VARIABLE!!!)
    If set, the server is required to support start_tls.
    Default: unset

FLAG_CHPW
    Permit password changes via this backend.
    Default: unset

FLAG_PWPOLICY
    Enforce a simplicistic password policy.
    Default: unset

FLAG_CACHE_CONNECTION
    Keep connection to LDAP server open.
    Default: unset

FLAG_FALLTHROUGH
    If LDAP search fails, try next module (if any).
    Default: unset

FLAG_USE_MEMBEROF
    Use the memberof attribute for determining group membership.
    Default: unset

FLAG_AUTHORIZE_ONLY
    Don't attempt to authenticate users.

Example Cisco IOS TACACS+ AAA configuration:

! Example Cisco IOS TACACS+ AAA configuration
!
! Don't forget to change Vlan1 to either the VLAN or physical interface that can 
! reach your tacplus server
!
! Run "show aaa user all" to verify privilege level after you login
!
! NOTE: It is highly recommended that you turn on service password encryption!
!       Some IOS images contain bugs that prevent TACACS+ from working unless service 
!       password encryption is enabled!

aaa new-model
aaa authentication login default group tacacs+ local
aaa authentication enable default group tacacs+ enable
aaa authorization config-commands
aaa authorization commands 1 default group tacacs+ local if-authenticated
aaa authorization commands 15 default group tacacs+ local if-authenticated
aaa authorization exec default group tacacs+ local if-authenticated
aaa accounting exec default start-stop group tacacs+
aaa accounting commands 1 default start-stop group tacacs+
aaa accounting commands 15 default start-stop group tacacs+
service password-encryption
ip tacacs source-interface Vlan1
tacacs-server host IP_OF_TACPLUS_SERVER single-connection key 0 cisco
tacacs-server directed-request

Example Cisco ASA TACACS+ AAA configuration:

! Sample Cisco ASA TACACS+ AAA configuration
! Don't forget to change (inside) to the interface that can reach your tacplus server
! Run "show curpriv" to verify privilege level after you login
!
! NOTE: Please make sure the ASA IOS image you are running isn't exploitable
!
!       See Cisco Advisory ID: cisco-sa-20160210-asa-ike for more information
!       See Cisco Bug IDs: CSCux29978, CSCux42019 for more information
!
! Cisco TAC will provide a patched image to you free of charge even if you don't have a
! service contact! Open a Cisco TAC case with your ASA's serial number and include the
! advisory ID as proof of entitlement and they will provide the image file to you!

aaa-server tacplus protocol tacacs+
aaa-server tacplus (inside) host IP_OF_TACPLUS_SERVER
 key cisco
aaa authentication ssh console tacplus LOCAL
aaa authentication serial console tacplus LOCAL
aaa authentication enable console tacplus LOCAL
aaa authentication http console tacplus LOCAL
aaa accounting command tacplus
aaa accounting ssh console tacplus
aaa accounting enable console tacplus

Example Cisco NX-OS TACACS+ AAA configuration:

! Sample NX-OS aaa tac_plus configuration
! Don't forget to change the VRF to one that can reach your tacplus server
! Run "show user-account" to verify roles after you login successfully

tacacs-server directed-request
tacacs-server host IP_OF_TACPLUS_SERVER key 0 "cisco"

aaa group server tacacs+ tacplus 
    server IP_OF_TACPLUS_SERVER
    use-vrf default

aaa authentication login default group tacplus local
aaa authentication login console group tacplus local
aaa authorization config-commands default group tacplus local 
aaa authorization commands default group tacplus local 
aaa accounting default group tacplus

Example Cisco IOS XR TACACS+ AAA configuration:

! Example Cisco IOS XR TACACS+ AAA configuration (IOS XR formal syntax)
! Don't forget to change the interface/vrf to a pair that can reach your tacplus server
! Run "show user tasks" to verify task levels after you login

tacacs source-interface TenGigE0/0/2/0 vrf default
tacacs-server host IP_OF_TACPLUS_SERVER port 49 
tacacs-server host IP_OF_TACPLUS_SERVER port 49 key 0 cisco
tacacs-server host IP_OF_TACPLUS_SERVER port 49 single-connection
aaa accounting exec default start-stop group tacacs+
aaa accounting system default start-stop group tacacs+
aaa accounting commands default start-stop group tacacs+
aaa authorization exec default group tacacs+ local
aaa authorization commands default group tacacs+
aaa authentication login default group tacacs+ local
| improve this answer | |
  • 1
    Great job, very detailed and good examples. – user36472 Nov 3 '17 at 7:00
  • Thanks! I struggled with getting tac_plus working initially. I figured I would share the wealth after I figured out how to get it working. Somewhere there will be another network admin tasked with replacing the old Windows 2003 Cisco ACS server with something free...hopefully this guide gets them started. – dt1235 Nov 3 '17 at 15:14
  • Brilliant! And just when I need it :-) And yes: I do need to replace an ACS. I’m doing some volunteer work as IT guy for a local charity and I’m in the process of modernizing their ancient infrastructure. You wouldn’t believe the mess I found when I started on this... All of it comes from donations over the last 20 years and it is a complete mismatched hodgepodge. This really helps! The only part I still miss is a free wireless access controller to which I can hook up the Cisco 1141 AP’s – Tonny Nov 4 '17 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.