Shrubbery Networks, Inc. Unix, Network, IT Consulting Service Shrubbery Networks, Inc. Unix, Network, IT Consulting Service
About Shrubbery Networks, Inc.
Services We Offer
Tools
Products
Customer Login
Tools
TACACS+ daemon

We needed a way to limit certain groups within the company from logging into or getting enable access on certain devices. Access lists (ACLs) of a sort have been added that match against the address of the device speaking with the daemon.

Being paranoid, we also wanted to limit which hosts could connect to the daemon. This can be done with tcp_wrappers via inetd, but this does not work if the daemon is running standalone. So, calls to libwrap, the tcp_wrappers library, have been added. For the source and more information about tcp_wrappers, see Wietse Venema's site at http://www.porcupine.org/.

Along the way we have also added autoconf, expanded the manual pages, cleaned-up various formatting and STD C nits, added PAM authentication support, and fixed a few LP64 problems.

Of course we have also received some enchancement requests from users. One of which was the addition of a host clause (per-host configuration). This has been added; ported from Devrim Seral's implementation. See the documentation for further information.

The base source for this TACACS+ package is Cisco's publicly available TACACS+ "developer's kit", for which we are grateful.

Download it from ftp://ftp.shrubbery.net/pub/tac_plus. CHANGES file.

John Payne offers more complex configuration information at tacacs.org. And, Adam wrote a PAM/LDAP configuration example for Linux available in PAM_guide.txt and Asif Iqbal provided his notes.

Please send problems/contributions/suggestions here. If you need a little help with building and initial configuration, Lyndon Labuschagne has written a how-to and this post to the mail list decribed an installation with PAM on Redhat 5. Check out the FAQ.

Join the announce list here.


The features that we have added are acheived via new directives in the tac_plus daemon's configuration file as described below.

Limit group foo logins to routers 192.168.0.* and 192.168.1.*, except for the device 192.168.0.13:

acl = foo_acl {
        deny = 192.168.0\.13$
        permit = 192.168.[01]\.
}
group = foo {
        acl = foo_acl
}
user = bar {
        member = foo
}

The entries in an ACL are standard regular expressions (see re_format(7) or POSIX 1003.2). So, periods (.) need to be escaped, otherwise they match any character and may produce undesired results. And, an address should be anchored (^ and $) if the first or last octet are less than 3 digits or there fewer than 4 octets. Had the deny in the example above simply been "192.168.0\.13", it would also deny 192.168.0.130-139.

The loose, or un-anchored match, can be powerful or devastating. For example:

acl = foo_acl {
	deny = 192.168.1
}  
	

Will match 10.192.168.1 (or the glob *192.168.1) and 192.168.100.1 (ie: 192.168.1*). There are subtleties to be aware of and you are probably best off being pedantic in anchoring (^'s or $'s) and escaping (\'s) in your regexes.

Also note that there is an implicit deny at the end of the ACL. So, the ACL foo_acl above is equivalent to:

acl = foo_acl {
        deny = 192.168.0\.13$
        permit = 192.168.[01]\.
        deny = .*
}

The ACL is applied to the source address that the device used to connect to the tac_plus daemon. On most routers, this can be explicitly set. For example, on a cisco router:

ip tacacs source-interface Loopback0

This sets the source interface the router uses to connect to the server, and thus the address is the primary address of that interface. 192.168.0.1/32, for exmaple.

Deny logins to certain hosts in a prefix and allow all others:

acl = foo_acl {
        deny = 192.168.0\.(1|20|50|90)$
        permit = .*
}

Limit devices on which a user or group can enable:

user = bar {
	enableacl = foo_acl
}

Define a different enable password for a specific user or group

user = bar {
        enable = des wa8N/a017BC
}
OR
user = bar {
        enable = file /etc/tac_enable_pwd
}
OR
user = bar {
        enable = cleartext "letmein"
}
     Copyright© 1996-2014 Shrubbery Networks, Inc., All rights reserved. | Contact | Home