Procurves

I have only messed around (recently) with a few old Procurves, so I will not promise that the following is valid for all devices. Their tacacs implementation appears to be quite poor. If you use exclusively Procurves, do not use do\_auth as procurves don't properly support authorization. Some Procurves do not have the “aaa authentication login privilege-mode “ command. Hence, do\_auth is not even called. If you have these, you will have to do all your security in tac\_plus.conf. Beware, any security defined in your do\_auth.ini is void on these.

Other (newer?) Procurves did call an after-authentication script, but did not work right. In English, you can't modify any pairs as you have to tell it to kludge a response as 0. Do\_auth will do this for you if you add the following to your Procurve group:

exit_val =
    0

This is the wrong exit value, but will make everything work with “aaa authentication login privilege-mode “ (Again, which is flat out wrong – do not send that to Cisco/Brocade/Anybody else as it voids keys changed in do\_auth) You can't modify the privilege level, but you can at least deny a person access to a switch based on user/ip/yada. If you have a mixed environment, I would highly suggest having a separate group exclusively for your Procurves. One last thing, the -fix-crs-bug also fixes the Procurves and is mandatory as it doesn't send $address.  Yes, I know it's a silly workaround, it's on my "to do" list. 

Disable account on Brocade

Brocade has a brocade-privlvl which I like. It maps priv-lvl to brocade-privlvl, but the result is an account that has some privileges. Here is an example of how to map brocade-privlvl = 5 which has no modification rights. Unfortunately, it does require you to put in the IP's of your gear. (Nexus and Cisco pairs were different enough to distinguish between them, but Brocade pairs mimic Cisco pairs) It also requires v1.91 or greater. The following group would go before other groups and assumes you define a priv-vlv (of any number) in your tac\_plus config: [brocade\_readonly]
host\_allow =
    .*
device\_permit =
    192.168.1.*
command_permit =
    .*
av\_pairs =
    priv-lvl,brocade-privlvl=5

Brute Force Protection

Mark Ellzey Thomas has written a patch to tac_plus that prevents the brute force hacking of passwords. It works quite well in all my tests. The following example would watch for 10 authentication failures within 60 seconds and, if triggered, disable user for 120 seconds. auth-fail-lock 10 60 120 More info here: https://github.com/ellzey/tac\_plus_AFL

Cisco Nexus - HowTo *Updated*

The nexus seems to asks for pap authentication. I have no clue why, but adding a simple "pap = des -hash-" to your tac_plus makes it work. (doesn't seem to be necessary if you are setting a default authentication) Tacacs on Nexus is different. However, you can still continue to use tacacs the way you always have. Example configuration is as such:

tacacs-server key -key-
tacacs-server host -host-
aaa group server tacacs+ private
    server -host, yes again-
    use-vrf management
    source-interface mgmt0
aaa authentication login default group private
aaa authorization config-commands default group private
aaa authorization commands default group private
aaa accounting default group private

Many of you may be wondering why I did not add a "local" on the end of the aaa authorization commands. In short: It wouldn't let me - Cisco says it's a bug. Hence, till that is fixed, I recommend you use roles instead of authorization or you'll be locked out when the tacacs server is down. To enable roles, simple take out the two authorization lines above. You can read more on roles than I have to time explain on cisco's website, and you can even create your own. You can even create users that can only operate inside of their own vdc. However, for my examples, we'll just focus on how to use tac_plus and do\_auth.

Nexus and Cisco just don't play well together. Or, rather the Nexus plays OK, but the Cisco gets confused when it gets a Nexus role. Without do\_auth, you are forced to do things like run two separate tac_plus servers. However, with do\_auth, you can run a single server. For instance, consider the following snippet:

    service = exec {
        priv-lvl = 15
        shell:roles="\"network-admin\""
        idletime = 3
        timeout = 15
    }

The roles will confuse your switches, and you'll end up having to use enable passwords. However, add do\_auth as an after-authentication script, and do\_auth will strip the shell:roles from the Cisco. Hence, it works like it should.

I've improved the add/replacement of tac_pairs. For example:

av_pairs =
    priv-lvl=1
    shell:roles="network-operator"

Add this to a do\_auth group, and you've created a safe little read_only group to give helpdesk operators. More information is available on key replacement – do\_auth.py | less.

In short, you need do\_auth to make roles work correctly with other Cisco gear. But, this is NOT to imply a shortcoming of tac\_plus - this kluge in do\_auth was written to fix vendor problems, NOT tac_plus problems.

Of course, these changes required changes to do\_auth.

v1.91 http://pastie.org/3284098

do_auth - av_pairs

One of the long promised features has finally been added, the ability to modify av pairs. Let's say you have a group which you simply want a user to have disable access to. Simply add this to the group: av_pairs =
    priv-lvl=1

This assumes you have priv-lvl in your tac\_plus.conf. (Like examples in other posts) Note, of course, you’ll also need to add a command\_deny for enable or they’ll just type ‘en’ if they have an enable password. Better yet, just don’t give them an enable password!

In addition, we can replace one pair with something completely different, like for a brocade device. priv-lvl,brocade-privlvl=5 will replace any priv-lvl with that brocade-privlv. Think of it as a find/replace function.
Some devices do not like to have their tac\_pairs messed with. They don’t accept AUTHOR\_STATUS\_PASS\_REPL and I’ll spare the rest of the details for lack of time. These include the procurves and the Cisco WLC. Attempts to make these devices work have resulted in much “code sprawl” in do\_auth and are the reason that any service other than shell return 0 unless you explicitly modify a tac\_pair. For these devices, you will have to do all your config in tac\_plus.conf.

One last thing, don’t use v1.6 – it had a bug. Also sorry if you’re comments don’t get approved, apparently I don’t have rights to do that.

Brocade

My first time putting tacacs on a Brocade. Pretty similar to cisco, the tac pairs that cisco use seem to work just fine. Worked great with do_auth. Keep in mind, although they honor priv-15, they map it to 0, just to be different. I used the following:

username admin password yer_password_here
ip tacacs source-interface loopback 1
tacacs-server retransmit 2
tacacs-server timeout 2
tacacs-server host yer_host_here
tacacs-server key yer_key_here
enable super-user-password again_password_here
aaa authentication login default tacacs+ enable
aaa authentication login privilege-mode
aaa authentication enable default tacacs+ enable
aaa authorization commands 0 default tacacs+ none
aaa authorization exec default tacacs+
aaa accounting commands 0 default start-stop tacacs+
aaa accounting exec default start-stop tacacs+
enable aaa console

Securing Rancid with do_auth

Rancid can be made much more secure by using do_auth. A quick example of the do_auth.ini file is as follows: [users]
rancid =
     rancid_access
[rancid_access]
host\_allow =
     10.0.0.1
device\_permit =
     .*
command_permit =
     show.*
     dir.*
     more.*
     write t.*

Now, rancid can only login from 10.0.0.1, and only type commands that match those regular expressions. Technically, you could limit the commands in tac_plus.conf without do_auth. Might take longer, but you could do it. However, you could not limit it to 10.0.0.1 without an after authorization script such as do_auth.

NOTE: This assumes you only authorize config/Level 15 commands. I never authorize level 1 commands or, heaven forbid, level 0 commands as these commands can not change anything on the router, nor allow you to see the configuration. Now, if YOU choose to do so, the above example will still probably work. A quick look at log.txt will tell you any additional commands you will need to add.

Easier Tacacs Configurations with do_auth

We've gone over how you can make your tacacs configuration really secure but complicated. Let's show how do\_auth can actually make configuration easier. It's much easier to edit the do\_auth.ini file than the tac\_plus.conf file. In fact, we can make adding a default user as easy as typing "adduser". I would post the compiled code, but it's too difficult to get a hold of John these days. (Something about a baby, I dunno) It's trivial to compile: dan@dan-desktop:~$ python
Python 2.5.2 (r252:60911, Jul 22 2009, 15:35:03)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import py\_compile
>>> py\_compile.compile("do\_auth.py")
>>> quit()

First, a starting tac\_plus.conf file. Which, we'll never have to edit again:

# My simple tac\_plus config that never needs to change
key = my\_key
accounting file = /var/log/tac\_plus.acct
default authentication = file /etc/passwd
user = DEFAULT {
     member = do\_auth\_access
}
group = do\_auth\_access {
     default service = permit
     service = exec { priv-lvl = 15
          idletime = 10 }
     enable = file /etc/passwd
     after authorization "/usr/bin/python /root/do\_auth.pyc -i $address -u $user -d $name -l /root/log.txt -f /root/do\_auth.ini" }

Most important - after authorizaion line is one line, not two. The $ means it wrapped.

Now, we add homer and give him access to some show commands. Fist, we do a adduser homer on linux to add the user. This way, when the user wants to change is password, he can any time he wants to with passwd. Next, we edit the do\_auth.ini file

[users]
homer =
     few\_commands
[few\_commands]
host\_allow =
     .*
device\_permit =
     .*
command\_permit =
     show users
     show int.*
     show ip int.*
     show controllers.*

And, you're done. Well, I'd add some tabs to each command that got stripped above(blogs/wiki's can be annoying), but that's about it.

Let's compare that to the tac\_plus.conf config:

user = homer {
     member = limited\_access
}
group = limited\_access {
     default service = deny
     acl = limited\_acl
     service = exec {
          priv-lvl = 15
          idletime = 10
     }
     cmd = show {
          permit "running-config.*"
          permit "ip int*"
          permit "inter.*"
          permit "controllers.*"
     }

In my small do\_auth python program, we have no permits, no “”, and no {}. Much easier and the no need to restart the daemon. To add an admin user is even easier. Adduser admin in linux, then add:

admin =
     admin\_user
[admin\_user]
host\_allow =
     .*
device\_permit =
     .*
command\_permit =
     .*

So, our final config is very easy:

[users]
homer =
     few\_commands
admin =
     admin\_user
[few\_commands]
host\_allow =
     .*
device\_permit =
     .*
command\_permit =
     show users
     show int.*
     show ip int.*
     show controllers.*
[admin\_user]
host\_allow =
     .*
device\_permit =
     .*
command\_permit =
     .*

As if this weren't easy enough, let's say 99% of your users are these limited access users. Wouldn't it be nice to just do an adduser and be done without any config modification? All we need is a default user. In our example above we would change to this:

[users]
default =
     few\_commands
[few\_commands]
host\_allow =
     .*
device\_permit =
     .*
command\_permit =
     show users
     show int.*
     show ip int.*
     show controllers.*

Now, whenever we do an adduser, it automatically gets this level of access.

From here, we can make it as simple or as complicated as we want. Restrict them to certain device, make them connect from connect from certain IP's, ect. We can maybe even begin to work on a web front end. (Maybe someday when I get time.....)

-Dan Schmidt

Granular Tacacs Control (Yes, you can do multiple groups)

By using an authorization script, we can make tac\_plus to do very granular authentication, having different permissions granted to different switches defined by user, source IP and device IP. However, writing/editing a script to change access can be difficult. Hard coded authorization scripts are not very flexible, hence, I decided to implement a python program to facilitate flexibility. It is now included in the tac\_plus package. Configuration is fairly simple; as an example, let's say I wanted to have user Homer have full access to 192.168.1.1 and 10.1.1.0/24, but only do show commands for everything else in 10.0.0.0/8. For the heck of it, let's say we only want Homer to connect from 192.168.1.0/24, but never 192.168.1.4, which host can only do the show commands. The config file would simply be as follows:

[users]
homer =
     simpson\_group
     television\_group
[simpson\_group]
host\_deny =
     192.168.1.4
host\_allow =
     192.168.1.*
device\_permit =
     192.168.1.1
     10.1.1.*
command\_permit =
     .*
[television\_group]
host\_allow =
     192.168.1.*
device\_permit =
     10.*
command\_permit =
     show.*

Example line to put in tac\_plus user or group: after authorization "/usr/bin/python /root/do\_auth.pyc -i $address -u $user -d $name -l /root/log.txt -f /root/do\_auth.ini" (that's all ONE line)

On my server, I set homer's password file to /etc/passwd and enable cracklib. Homer can change his password any time he wants just by logging to Linux and typing passwd – he does not need root access. Homer is also forced to pick a secure password, and has different access based on different devices. Given these abilities, combined with the quick administration, tac\_plus makes purchasing Cisco's tacacs server seem like a waste of money.

In the future, I may alter the program to have the ability to send back additional av-pairs, and/or completely new av-pairs. However, currently I simply don't need this feature as I pass these pairs back to tac\_plus. The source code is very simple and is GPL'ed for all to see at: http://pastie.org/506002 and is available in compiled/ready to use form here. For more instructions, you can download this compiled pyc and type “python do\_auth.pyc” If I ever get time, I may consider a gui or web interface.

Update: New version 1.2 Fixed pix. Also, apparently there is a bug in the pix that makes it necessary to add a 0.0.0.0 to your allowed hosts.

-Dan Schmidt