I was trying to utilize the LDAP (to fetch group membership) and Radius (to Authenticate with MFA) based authentication.... Both are working fine after a lot of configuration changes but unable to fulfill the specific usecase and that is to bypass radius authentication and use AD Authentication for few specific users while rest will be authenticated via radius
# ==============================================================================
# 1. DAEMON & NETWORK CONNECTION CONFIGURATION
# ==============================================================================
id = spawnd {
listen = { address = 0.0.0.0 port = 49 }
spawn = {
instances min = 1
instances max = 32 # Safely expanded to support multi-user login holds
}
background = no
}
# ==============================================================================
# 2. MAIN CORE SERVICE REGION (Unified Modern Architecture Blueprint)
# ==============================================================================
id = tac_plus-ng {
# SECURITY LOCKDOWN: Restrict inbound processing strictly to standard TACACS+ TCP.
aaa.protocol.allowed = tacacs.tcp
# ----------------------------------------------------------------------
# LOGGING ARCHITECTURE
# ----------------------------------------------------------------------
log accesslog { destination = /var/log/tacacs/access.log }
log authorlog { destination = /var/log/tacacs/authorization.log }
log acctlog { destination = /var/log/tacacs/accounting.log }
log connlog { destination = /var/log/tacacs/connection.log }
access log = accesslog
authorization log = authorlog
accounting log = acctlog
connection log = connlog
# ----------------------------------------------------------------------
# GLOBAL BACKEND ROUTING BINDINGS
# ----------------------------------------------------------------------
user backend = mavis
login backend = mavis
pap backend = mavis
# ----------------------------------------------------------------------
# THE MODERN UNIFIED MAVIS GROUPS & EXTERNAL FILTERS PIPELINE
# ----------------------------------------------------------------------
# This native optimization handles group filtering natively on execution,
# stripping long AD paths down into clean strings before hitting rulesets.
# mavis module = groups {
# groups filter = /^(MA-RW|MA-RO|F5-OP|WLC|MA-NCM_Backup)$/i
# }
mavis module = external {
# Sequential Execution: RADIUS authenticates first -> LDAP resolves groups second
# default = yes
exec = /usr/local/tacacs/lib/mavis/
mavis_tacplus_radius.pl # ======================================================================
# RADIUS PARAMETERS
# ======================================================================
setenv RADIUS_HOST = "
10.86.32.46:1812"
setenv RADIUS_SECRET = "aY9cort29rhRiyD1TbR3WbC7Vby8oOcxOT2UNPv3"
setenv RADIUS_AUTH_ONLY = "1"
setenv RADIUS_DICT = "/usr/share/freeradius/dictionary"
setenv RADIUS_TIMEOUT = "60"
# Structural flags to keep variables safe between script handoffs
setenv TACTYPE = "PAP"
setenv MAVIS_PASS = "1"
setenv MAVIS_AUTO_PASSWORD = "1"
}
# ======================================================================
# LDAP / ACTIVE DIRECTORY PARAMETERS
# ======================================================================
mavis module = external {
# Sequential Execution: RADIUS authenticates first -> LDAP resolves groups second
exec = /usr/local/tacacs/lib/mavis/
mavis_tacplus_ldap.pl setenv LDAP_SERVER_TYPE = "microsoft"
setenv LDAP_HOSTS = "redacted"
setenv LDAP_SCOPE = "sub"
setenv LDAP_BASE = "dc=test,dc=local"
# Valid positional substitution token matching your backend release version
setenv LDAP_FILTER = "(sAMAccountName=%s)"
setenv LDAP_USER = "t...@test.local"
setenv LDAP_PASSWD = "modified"
setenv USE_TLS = "0"
# setenv LDAP_GROUP_ATTR = "memberOf"
setenv FLAG_USE_MEMBER = "1"
# setenv LDAP_GROUP_REGEX = "(?i)^cn=([\s\w-]+),.*"
setenv TACACS_GROUP_PREFIX = "(MA-|F5-|WLC)"
setenv LDAP_GROUP_DEFAULT = "MA-RO"
setenv MAVIS_DEBUG = "1"
setenv MAVIS_LDAP_DEBUG = "1"
setenv MAVIS_LDAP_TRACE = "1"
}
# ----------------------------------------------------------------------
# GLOBAL DYNAMIC AUTHENTICATION ROUTING RULE
# ----------------------------------------------------------------------
user = DEFAULT {
password login = mavis
password pap = mavis
}
# ----------------------------------------------------------------------
# NETWORK ACCESS SERVER (NAS) / DEVICE DEFINITIONS
# ----------------------------------------------------------------------
device CE-TACACs-Device-Group {
key = "modified"
welcome banner = "Welcome to the Network Management Domain\n"
device network_devices {
address =
0.0.0.0/0 }
}
# ----------------------------------------------------------------------
# EXPLICIT GROUP OBJECT DECLARATIONS
# ----------------------------------------------------------------------
group "MA-RW" { }
group "MA-RO" { }
group "F5-OP" { }
group "WLC" { }
group "MA-Backup" { }
# ----------------------------------------------------------------------
# SHELL & COMMAND ACCESS PROFILES
# ----------------------------------------------------------------------
profile prof-MA-RW {
script {
if (service == shell) {
set priv-lvl = 15
set cisco-av-pair = "shell:domains = all/admin/,common// admin"
permit
}
if (service == junos-exec) { set local-user-name = remote-su; permit }
if (service == fortigate) { set memberof = FWA-MGMT-RW; set admin_prof = super_admin; permit }
if (service == ciscowlc) { set role1 = ALL; permit }
if (service == ppp && protocol == ip) {
set F5-LTM-User-Info-1 = adm; set F5-LTM-User-Console = 1; set F5-LTM-User-Role = 0; set F5-LTM-User-Partition = all; permit
}
if (service == PaloAlto) {
set PaloAlto-Admin-Role = superuser; set PaloAlto-Panorama-Admin-Role = superuser; set priv-lvl = 1; permit
}
}
}
profile prof-MA-RO {
script {
if (service == shell) {
set priv-lvl = 15
if (cmd == "" || cmd =~ /^show/ || cmd == "ping" || cmd == "exit" || cmd == "traceroute" || cmd =~ /^terminal/) {
permit
}
message = "Read-Only Access: Configuration commands are denied."
deny
}
if (service == ciscowlc) { set role1 = LOBBY; permit }
if (service == ppp && protocol == ip) {
set F5-LTM-User-Info-1 = guest; set F5-LTM-User-Console = 1; set F5-LTM-User-Role = 700; set F5-LTM-User-Partition = all; permit
}
if (service == PaloAlto) {
set PaloAlto-Admin-Role = readonly; set PaloAlto-Panorama-Admin-Role = readonly; set priv-lvl = 1; permit
}
}
}
profile prof-MA-Backup {
script {
if (service == shell) {
set priv-lvl = 15
if (cmd == "" || cmd =~ /^terminal length/ || cmd =~ /^show (running|startup)-config/ || cmd == "end" || cmd == "exit") {
permit
}
message = "Backup Access Only: Only specific show and sync commands permitted."
deny
}
if (service == ciscowlc) { set role1 = LOBBY; permit }
if (service == ppp && protocol == ip) {
set F5-LTM-User-Info-1 = guest; set F5-LTM-User-Console = 1; set d= 700; set F5-LTM-User-Partition = all; permit
}
if (service == PaloAlto) {
set PaloAlto-Admin-Role = readonly; set PaloAlto-Panorama-Admin-Role = readonly; set priv-lvl = 1; permit
}
}
}
# ----------------------------------------------------------------------
# NETWORK ASSET LISTS (NAC)
# ----------------------------------------------------------------------
net backup_nac {
address = X.X.X.X/32
}
# ----------------------------------------------------------------------
# AUTHORIZATION POLICY RULESET (Strict Production Matching)
# ----------------------------------------------------------------------
ruleset {
rule {
script {
# 1. Handle transit restricted exceptions safely using blocks
if (user == aaalee || user == pqiu || user == aarsharma) {
if (device == network_devices) { profile = prof-MA-RW permit }
deny
}
# 2. Process standard team users inside a safe 'else' container block
else {
# Validated target syntax matches clean group strings extracted by MAVIS
if (memberof =~ /^CN=MA-RW,/) { profile = prof-MA-RW permit }
if (memberof =~ /^CN=MA-RO,/) { profile = prof-MA-RO permit }
if (memberof =~ /^CN=F5-OP,/) { profile = prof-MA-RO permit }
if (memberof =~ /^CN=WLC,/) { profile = prof-MA-RO permit }
# Automated backup tools subnet restriction rule
if (memberof =~ /^CN=MA-Backup,/) {
if (nac == backup_nac) { profile = prof-MA-Backup permit }
deny
}
}
}
}
}
}