tac_plus-ng send certain AV pairs based on NAS request args

136 views
Skip to first unread message

Carter

unread,
Jul 19, 2024, 10:53:57 AM7/19/24
to Event-Driven Servers
Hello,
I've been working on configuring a single tac_plus-ng profile that will properly authorize both IOS and IOS-XR NASes. IOS-XR uses the concept of locally defined "task groups" for authorization:

It uses the tacacs attribute "task" for this. Here is an example of an exec authorization request from an IOS device:
---<start packet>---
key used: ...
version: 192, type: 2, seq no: 1, flags: unencrypted
session id: 652f570b, data length: 51
AUTHOR, priv_lvl=1
authen_type=ascii (1)
authen_method=tacacs+ (6)
service=login (1)
user_len=6 port_len=4 rem_addr_len=14 arg_cnt=2
user (len: 6): carter
port (len: 4): tty1
rem_addr (len: 14): ...
arg[0] (len: 13): service=shell
arg[1] (len: 4): cmd*
---<end packet>---

Versus an IOS-XR device:
---<start packet>---
key used: ...
version: 192, type: 2, seq no: 1, flags: unencrypted
session id: d23101db, data length: 63
AUTHOR, priv_lvl=15
authen_type=ascii (1)
authen_method=tacacs+ (6)
service=login (1)
user_len=6 port_len=10 rem_addr_len=14 arg_cnt=3
user (len: 6): carter
port (len: 10): /dev/pts/8
rem_addr (len: 14): ...
arg[0] (len: 13): service=shell
arg[1] (len: 4): cmd*
arg[2] (len: 5): task*
---<end packet>---

If I set "task" when authorizing a non-XR device, it doesn't authorize properly, so I started looking for a way to send certain AV pairs only when the "task*" arg is present. I noticed this in the logs:

nas:service=shell (passed thru)
nas:cmd* (passed thru)
nas:task* svr:absent/deny -> delete task* (i)

I'm not sure how to act on it. I tried using "optional" or "add" instead of "set" for the task attribute, but those just didn't send the AV pair at all. Would the "default attribute = ( permit | deny )" option have an effect here? I tried a few variations of setting that to permit, and didn't see any change in behavior.

I came up with this, which seems to be working properly for both IOS and IOS-XR:

if (service == shell) {
if (cmd == "") {
set priv-lvl = 7
if (arg[task] == "") {
# IOS-XR, not sure if this is the best way to do this
set task = "rx:basic-services"
}
permit
}
if (cmd =~ /^show .*/) {
permit
}
deny
}

I haven't thoroughly tested to make sure this doesn't cause issues with devices from other vendors. Is this the best/only way to achieve what I'm after?

Thanks,
Carter

Marc Huber

unread,
Jul 22, 2024, 11:48:16 AM7/22/24
to event-driv...@googlegroups.com
Hi Carter,

I'd have guessed that "optional task = ..." would have worked, too, but
I don't have any IOS-XR systems to check this out. Your approach for
checking for "task" looks fine, too.

* *set *unconditionally returns a mandatory AV pair to the NAS (e.g.:
"set priv-lvl = 15" results in "priv-lvl=15")
* *optional *returns a NAS-requested optional AV pair to the NAS
unless the attribute was already in the mandatory list ("task*"
=>"task*whatever")
* *add *returns an optional AV pair to the NAS even if unrequested

Cheers,

Marc

Carter

unread,
Jul 22, 2024, 3:59:11 PM7/22/24
to Event-Driven Servers
Marc,
Here are logs for both configurations. The only difference is using 'if (arg[task] == "") { set task = ...', versus 'optional task = ...'. For some reason the "optional" AV pair doesn't get included in the reply. I would guess this behavior would be the same with NAS operating systems other than XR that request optional AV pairs, but I don't have any others to test on.

Thanks,
Carter
log_optional.txt
log_set.txt

Marc Huber

unread,
Jul 23, 2024, 9:40:06 AM7/23/24
to event-driv...@googlegroups.com
Hi Carter,

thanks, I could reproduce this. The issue should be fixed in
2ec14523f6a6c8d33ec0684ae24e20c6a38ed7a0, please git pull.

Thanks,

Marc

Carter

unread,
Jul 24, 2024, 11:26:14 AM7/24/24
to Event-Driven Servers
Marc,
Optional works now, thank you for getting this fixed.

Carter
Reply all
Reply to author
Forward
0 new messages