Setting up Tacacs+ With LDAP authentication

Working with multiple network equipments is a task that every network administrator have faced, and if you are one yourself, you are probably convinced by now that using multiple or a single password isn’t the brightest idea.

Tacacs+ is a proprietary protocol developed by Cisco to ensure the AAA functions: Authentication, Authorization and Accounting. I won’t go through the details of the protocol as it’s not the purpose of this guide, but if you want to know more about it, you can find interesting links at the end of this article.

When you intend to use Tacacs+, it is probably because you want to centralize the access to your Cisco equipments and keep track of who’s doing what. You probably already have an existing LDAP server that holds users’ infos, and you want people to connect to the network equipments using their credentials. If my assumptions are true, then this guide is made for you ;)

What you need to know

Before we dive into some technical stuff, I’d like to share with you some points that you have to consider and that will save you a lot of time and headaches.

Setting up Tacacs+ as an authentication method to access your Cisco box means that you’ll push some configuration lines into it. Never save your modifications unless you make sure the new authentication method is fully functionnal !

This guide was done on a Debian 8 (Jessie) machine, so I guess you are comfortable with the CLI and the GNU/Linux environment. I also assume that you have a functional OpenLDAP server and a Cisco box (switch or router).

I tested this configuration on a Cisco 2960S on IOS 12.2(55)SE3, a Cisco 3750 on IOS 12.2(55)SE10 and a Cisco 3560 on IOS 15.0(2)SE8 and it worked like a charm. However, I encountered some issues with a Cisco 2960 on IOS 15.0(2)SE3 and others models which made the switches unavailable: When setting up Tacacs+ authentication on the switch, a process under the name of TPLUS launches and uses all the CPU available, making it impossible to log in again to the switch unless you reboot it. I suspect the version of IOS being unadapted to the hardware, but it could be something else. So be cautious and never “write mem” unless you test the new authentication method.

What we’ll be doing

Tacacs+ doesn’t support LDAP authentication by default, but it does support PAM authentication. I see you nodding there: Yes, we’ll use PAM to connect to our LDAP server 🙂 Here’s a little diagram that summarizes what we’ll be setting up (behold my designer skills):

Authentication flow

Another issue with Tacacs+ is that it can’t fetch users’ groups. The solution shown above verifies that the login-password association exists in a valid LDAP entry, but you’ll still have to manually declare groups and users in Tacacs’ configuration file. This is where the tricky part of this guide comes in: We’ll use a bash script that will periodically check for members of a certain LDAP group and update Tacacs’ configuration file accordingly. This way all you have to do is to configure Tacacs’ server and then forget it (well you still have to maintain the server, but no further Tacacs configuration is needed): Access management will be done via the LDAP server.

Let’s do it

On the LDAP

On your LDAP server, all you have to do is create a new group, let’s say “cisco-enable” and add users who should get access to the network equipments in it.

On the Tacacs+ server

Before you get started you should consider a number of security issues. Since every person with the right privileges on the Tacacs+ server can gain access to all the network equipments, you should define a strict policy regarding who is gonna have the right on which file. In my case, I limited the access to the Tacacs+ server to root with a SSH public-key authentication, and no users other than root can connect to the machine.

First thing we are going to do is install libnss-ldap and libpam-ldap packages:

root@tacacs:~$ apt-get install libnss-ldap libpam-ldap

You will be prompted to configure the libnss-ldap package. Enter the informations needed to connect and fetch data from your LDAP server. Make sure to specify a basedn from which your Tacacs+ server can get both users and groups. If you want to restart the configuration of the package:

root@tacacs:~$ dpkg-reconfigure libnss-ldap

Once the installation is complete, open up /etc/nsswitch.conf in your text editor. I personally use vim:

root@tacacs:~$ vim /etc/nsswitch.conf

Substitute compat with files ldap:

:%s/compat/files ldap/g

Your file should now contain these three lines:

passwd:         files ldap
group:          files ldap
shadow:         files ldap

Restart the nscd daemon to see the effect of your modifications:

root@tacacs:~$ /etc/init.d/nscd restart

Now you can query groups ans users from the ldap using these commands:

root@tacacs:~$ getent passwd
root@tacacs:~$ getent group

If I want the list of the users that are in the “cisco-enable” group, I will get the following result:

root@tacacs:~$ getent group cisco-enable
cisco-enable:*:1004:nisay,foo1,foo2,foo3

We will use the result of this command later in our bash script. Now we configure our PAM module:

root@tacacs:~$ cd /etc/pam.d/

4 files are to be modified: common-account, common-auth, common-password and common-session. Your files should look like this:

  • common-account
account	sufficient	pam_ldap.so
account	required	pam_unix.so
  • common-auth
auth	sufficient	pam_ldap.so
auth	required	pam_unix.so nullok_secure use_first_pass
  • common-password
password	sufficient	pam_ldap.so
password	required	pam_unix.so nullok obscure min=4 max=8 md5
  • common-session
session	sufficient	pam_ldap.so
session	required	pam_unix.so

Now we have to make sure that only authorized users can login to the machine:

root@tacacs:~$ mkdir /root/.ssh
root@tacacs:~$ vim /root/.ssh/authorized_keys

And copy-paste your ssh public-key in this file. Now we tune the ssh daemon so that only root login with public key is permitted:

root@tacacs:~$ vim /etc/ssh/sshd_config

Search for lines containing PermitRootLogin and PasswordAuthentication and set them like this:

PermitRootLogin without-password
PasswordAuthentication no

And reload the ssh deamon:

root@tacacs:~$ /etc/init.d/ssh reload

Now we install tacacs+ package:

root@tacacs:~$ apt-get install tacacs+

We won’t configure Tacacs+ as our script will do the job for us. However we need to create a template configuration file to which our script will append the list of the users:

root@tacacs:~$ vim /etc/tacacs_template.conf

Your file should look like this:

accounting file = /var/log/tacacs.log

key = testing123

group = enable {
 login = PAM
 service = exec {
 priv-lvl = 15
 }
}
  • accounting file: The file that will contain the users logs
  • key: The key that will be used to secure the communication between your Tacacs+ server and network equipments. Choose some complex key.
  • group: The group to which the users will belong. The PAM module will be used for the login, and users will connect in enable mode.

We have arrived to the exciting part: The bash script. Copy the following lines in a new file, let’s say /opt/sync_users.sh

#!/bin/sh
/etc/init.d/nscd restart

if test -d /tmp/tacacs; then
 test -e /tmp/tacacs/users.txt && rm /tmp/tacacs/users.txt
else
 mkdir /tmp/tacacs
 chmod 600 /tmp/tacacs
fi

usersNumber=$(getent group cisco-enable | cut -d':' -f4 | sed s/,/"\n"/g | wc -l)

for i in $(seq $usersNumber); do
 user=$(getent group cisco-enable | cut -d':' -f4 | cut -d',' -f$i)
 echo "user = $user {\n\tmember = enable\n}\n" >> /tmp/tacacs/users.txt
done

cat /etc/tacacs_template.conf /tmp/tacacs/users.txt > /tmp/tacacs/tac_plus.new

if diff /tmp/tacacs/tac_plus.new /etc/tacacs+/tac_plus.conf; then
 exit 0
else
 cp /tmp/tacacs/tac_plus.new /etc/tacacs+/tac_plus.conf
 /etc/init.d/tacacs_plus reload
fi

In the lines from 1 to 11 we restart the nscd daemon and check if the /tmp/tacacs folder exists. If so we remove the file users.txt if it exists. Otherwise, we create the folder and give all rights to root on it.

Remember the getent group cisco-enable command ? We use that in line 13 to count the number of users in cisco-enable group.

For each user, we add an entry in /tmp/tacacs/users.txt file (lines 15 to 19). For user nisay, we add these lines:

user = nisay {
    member = enable
}

We concatenate the users.txt files to our /etc/tacacs_template.conf and write the output in /tmp/tacacs/tac_plus.new

We overwrite the /etc/tacacs+/tac_plus.conf with the tac_plus.new file if they are different and reload the Tacacs daemon (lines 23 to 29)

Last step (hang on, we’re almost done) is to edit the crontab so that the script is launched every 5 minutes (or every whatever you want). Add this to the end of /etc/crontab :

*/5 * * * * root /opt/users_sync.sh

On the router/switch

All what is left to do is connect to your Cisco box, and type in these commands:

switch>enable
Password:
switch#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
switch(config)#aaa new-model
switch(config)#aaa authentication login default group tacacs+ local
switch(config)#aaa authorization exec default group tacacs+ if-authenticated
switch(config)#aaa accounting exec default start-stop group tacacs+
switch(config)#aaa accounting commands 1 default start-stop group tacacs+
switch(config)#aaa accounting commands 15 default start-stop group tacacs+
switch(config)#aaa accounting network default start-stop group tacacs+
switch(config)#aaa accounting system default start-stop group tacacs+
switch(config)#tacacs-server host 192.168.1.254 key testing123

I won’t explain in details the commands above, but I refer you to the links at the end where it is discussed thoroughly. To summarize, I told my switch to refer to my Tacacs+ server to do the authentication and authorization, and to use the local database if Tacacs+ is not available. The accounting is also sent to the Tacacs+ server.

The reason why I left the tacacs-server host 192.168.1.254 testing123 command for the end is because it’s a little tricky. It depends on the version of IOS you have on your Cisco box. Newer version of IOS will tell you that the command will be deprecated soon, and it will advise you to use tacacs server syntax instead. If so, negate the last command and use theses commands instead:

switch(config)#no tacacs-server host 192.168.1.254 key testing123
switch(config)#tacacs server myTacacsServerName
switch(config-tacacs)#address ipv4 192.168.1.254
switch(config-tacacs)#key 0 testing123

The 0 in the last command is just to specify that the password will be typed in clear.

With that done, you should be able to login to your Cisco box using your LDAP credentials. Don’t logout of your current session yet, fire up a new terminal and try to connect to your network equipment using the new authentication method. If something goes bad, you can still revert the changes you’ve made.

There you go, you now have a fully functional Tacacs+ server with LDAP authentication.