Granting varied levels of NAS permission based on LDAP group membership
Braden McGrath
braden at big-geek.net
Thu Apr 21 22:53:40 UTC 2022
FR users & maintainers,
I have a functional FreeRADIUS installation (3.0.20 - I know it's
slightly old, it's from the Ubuntu repo - on Ubuntu 20.04LTS), being
used for management access and authorization on varied network
equipment at an ISP (not everything supports TACACS so we're using
RADIUS).
When I first setup this system, Alan and other members of this group
gave me a bunch of help and I threw together a policy.d file (called
"group_authz") that is querying for LDAP group membership, and then
altering the replies back to the various NASes with specific
attributes to grant read-only or read-write permissions on the
devices. I was originally told by my boss that a universal read-only
and read-write group would be sufficient, so it was pretty easy to
check for membership in one of those two groups and then just send
back specific attributes depending on %{client:nas_type}.
Of course, now the goalposts have shifted. I've been told that we need
"tiered" access. Some users (tier 2 NOC team) should get R/W to most
of the network, but should *not* have any access at all to some of the
more sensitive gear (core/datacenter network stuff). Others (tier 1
NOC team) should get only R/O to the same chunk of network, but not
the sensitive stuff. We still need a "full R/W" (tier3/architects) and
"full R/O" (probably won't get used much, but just in case) as well.
I'm now trying to figure out the "best" / most elegant way to handle
this new requirement.
I'm thinking that it would be helpful to use group nesting to make
things more simple on the LDAP side, but I don't know if LDAP-Group[*]
will catch nested membership (user is a member of group X, which is a
member of group Y - does LDAP-Group show group Y)?
I'll also need to define the "sensitive" gear somehow (either via NAS
name or IP address as defined in clients.conf) and return a reject for
those cases...
Below is the entirety of my "group_authz" file from policy.d/ so you
know what I'm doing now.
I am far from a developer, so I'm open to any and all ideas to improve
this (in case I've done something stupid), as well as meet my new
"tiered" requirements.
Thanks all!
Braden McGrath
braden at big-geek.net
group_authz {
if (&LDAP-Group[*] ==
"cn=network-fulladmin,${modules.ldap.group.base_dn}") {
switch "%{client:nas_type}" {
case mikrotik {
# For Mikrotik routers
update reply {
&Mikrotik-Group := "full"
}
return
}
case dell_os10 {
# For Dell OS10 switches
update reply {
&Cisco-AVPair += 'shell:roles="sysadmin"'
}
return
}
case juniper {
# For Juniper / JunOS devices
update reply {
&Juniper-Local-User-Name := "SUPER"
}
return
}
case cisco {
update reply {
&Cisco-AVPair += "shell:priv-lvl=15"
# &Service-Type := "Administrative-User"
}
return
}
case awplus {
# AlliedWare Plus - Allied Telesis switches (and others)
#
https://www.alliedtelesis.com/sites/default/files/documents/configuration-guides/howto_aw-_config_admin_login_using_radius_tacacs_plus.pdf
# NOTE: AWPlus treats any Service-Type other than
"Administrative-User" or "NAS-Prompt-User" as ACCESS-REJECT
update reply {
&Service-Type := "Administrative-User"
}
return
}
case {
# default case - shouldn't ever match!
update reply {
&Reply-Message := "Could not find NAS_Type - check
clients.conf?"
}
reject
}
}
# debug_reply
return
}
elsif (&LDAP-Group[*] ==
"cn=network-readonly,${modules.ldap.group.base_dn}") {
switch "%{client:nas_type}" {
case mikrotik {
# Obviously, this group gets read access...
update reply {
&Mikrotik-Group := "read"
}
return
}
case dell_os10 {
# On the Dells, this allows normal "op" actions but
can't read/dump config
update reply {
&Cisco-AVPair += 'shell:roles="netoperator"'
}
return
}
case juniper {
# true read-only for now, can use "OPR" if we want to
allow clearing counters / etc
update reply {
&Juniper-Local-User-Name := "RO"
}
return
}
case cisco {
update reply {
# priv-lvl=1 is basic RO / not-enabled on Cisco,
not "7" like Allied Telesis
&Cisco-AVPair += "shell:priv-lvl=1"
#&Service-Type := "NAS-Prompt-User"
}
return
}
case awplus {
# this should be readonly/show commands for Allied Telesis
# Definitely need both of these for priv7 level, drop
the AVPair for just priv1
update reply {
&Cisco-AVPair += "shell:priv-lvl=7"
&Service-Type := "NAS-Prompt-User"
}
return
}
case {
# default case, shouldn't ever match
update reply {
&Reply-Message := "Could not find NAS_Type - check
clients.conf?"
}
reject
}
}
return
}
else {
update reply {
&Reply-Message := "User not authorized - check
directory/LDAP group membership"
}
reject
}
}
More information about the Freeradius-Users
mailing list