User in Multiple AD Group

582 views
Skip to first unread message

Rony Spitzer

unread,
Jun 7, 2022, 12:15:37 PM6/7/22
to Event-Driven Servers

Hey everybody

 

We have several admin groups, which we map accordingly to various services. The only problem is, if a user is a member of more than one group, the authentication via TACACS+ from the devices fails.

 

How can we assign a user to multiple groups and map them to services?

 

Our TACACS config:

 

 

#!/usr/local/sbin/tac_plus

id = spawnd {

    listen = { address = 0.0.0.0 port = 49 }

#Uncomment the line below for IPv6 support

#listen = { address = :: port = 49 }

    spawn = {

instances min = 1

instances max = 10

}

background = yes

}

 

id = tac_plus {

access log = /var/log/tac_plus/access/%Y/%m/access-%m-%d-%Y.txt

accounting log = /var/log/tac_plus/accounting/%Y/%m/accounting-%m-%d-%Y.txt

authentication log = /var/log/tac_plus/authentication/%Y/%m/authentication-%m-%d-%Y.txt

 

mavis module = external {

setenv LDAP_SERVER_TYPE = "microsoft"

#If you are using Microsoft Global Catalog with secure LDAP (SSL)

#setenv LDAP_HOSTS = "ldaps://LDAP1:3269 ldaps://LDAP2:3269"

#If you are using Microsoft Global Catalog with regular LDAP (non-SSL)

setenv LDAP_HOSTS = "LDAP1:3268 LDAP2:3268"

setenv LDAP_BASE = "DC=an524,DC=intern"

setenv LDAP_SCOPE = sub

setenv LDAP_FILTER = "(&(objectClass=user)(objectClass=person)(sAMAccountName=%s))"

setenv LDAP_USER = svc-t...@an524.intern

setenv LDAP_PASSWD = "READONLYPASSWORD"

#Setting UNLIMIT_AD_GROUP_MEMBERSHIP to 0 will cause a NACK response if the AD account is a member of more than one security group

setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1

#I'm not 100% sure what EXPAND_AD_GROUP_MEMBERSHIP does

setenv EXPAND_AD_GROUP_MEMBERSHIP = 0

#Clear default setting of tacplus for AD_GROUP_PREFIX

setenv AD_GROUP_PREFIX = ""

#Setting REQUIRE_TACACS_GROUP_PREFIX to 1 will cause a NACK response if the AD account is not a member of a security group with the required pref>

setenv REQUIRE_TACACS_GROUP_PREFIX = 0

setenv FLAG_USE_MEMBEROF = 1

#DO NOT SET THE USE_TLS ENVIRONMENT VARIABLE

#TLS WILL AUTOMATICALLY BE ENABLED IF NEEDED

#FORCING THIS VARIABLE TO 1 WILL BREAK MAVIS IF TLS IS NEEDED

#setenv USE_TLS = 0

exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl

}

 

login backend = mavis

user backend = mavis

pap backend = mavis

 

host = world {

#Allow any IPv4 device

address = MANAGEMENT/SUBNET

 

#Uncomment the line below for IPv6 support

#address = ::/0

 

#Uncomment the line below to inject a login prompt

#prompt = "Put your custom welcome message here.\n"

 

#Change this to your own secure TACACS+ key

key = "SOMESECUREKEY"

}

 

skip missing groups = yes

skip conflicting groups = yes

group = Company-Network-Administrators {

default service = permit

enable = login

service = shell {

default command = permit

default attribute = permit

set priv-lvl = 15

double-quote-values = yes

set shell:roles = "sysadmin"

set shell:priv-lvl=15

}

service = ppp {

protocol = ip

# default cmd = permit

default attribute = permit

set priv-lvl = 15

double-quote-values = yes

set shell:roles = "sysadmin"

set shell:priv-lvl=15

}

}

group = Company-Network-Users {

default service = permit

service = shell {

default command = permit

default attribute = permit

set priv-lvl = 3

}

}

group = Company-Firewall-Administrators {

default service = permit

service = PaloAlto {

protocol = firewall

set PaloAlto-Admin-Role = firewall-administrator

set priv-lvl = 15

}

}

group = Company-Firewall-Users {

default service = permit

service = PaloAlto {

protocol = firewall

set PaloAlto-Admin-Role = firewall-user

set priv-lvl = 3

}

}

}

 

Thank you for your help.

 

Kind Regards

Drakasch

unread,
Jun 8, 2022, 7:42:24 AM6/8/22
to Event-Driven Servers
I have the same issue... any solutions?

Aleksey Mochalin

unread,
Jun 8, 2022, 8:03:04 AM6/8/22
to Event-Driven Servers
Hello Guys,

Marc created flexible daemon, and for your question there are two solutions:

1. You can create ACL and apply then to User Groups. Based on ip address of NAC or NAS this user group will be applied (Read more). Example:
acl oncampus = { nac = ... } 
acl viavpn = { nac = ... } 
acl atwork = { nac = ... time = ... }

user = employee { 
  ... 
 member acl atwork = staff@router 
 member acl viavpn = staff 
 member acl remote = guest 
 ... 
}

2. You can create ACL and apply then to Services. Based on ip address of NAC or NAS this user group will be applied (Diagram). Example:

acl oncampus = { nac = ... } 
acl viavpn = { nac = ... } 
acl atwork = { nac = ... time = ... }

user = employee { 
 ... 
 service acl atwork = shell { ... }
 service acl viavpn = shell { ... } 
 service acl remote = shell { ... }
...
}

Please read manual. I recommend you to read it from the beginning to the bottom and you will open a lot of new features for this daemon. 

среда, 8 июня 2022 г. в 14:42:24 UTC+3, Drakasch:

Patrick Mackey

unread,
Jun 29, 2022, 1:22:51 AM6/29/22
to Event-Driven Servers
> We have several admin groups, which we map accordingly to various services. The only problem is, if a user is a member of more than one group, the authentication via TACACS+ from the devices fails.

I also have problems with users and multiple group membership in LDAP. Though in my case authentication succeeds, the assigned group seems to be random, and likely dependent on the order the groups are returned from LDAP.

I've found the best option is to simply ensure that users are only a member of one group.

It is possible to force a user into a group by creating a local user and setting their login to mavis:

user = mary {
  login = mavis
  member = admin
}

But if you're trying to keep user definitions out of the config file, that's not much help.

Ideally, It would be great if the groups returned from MAVIS were processed in the order they are placed in the configuration file.


Marc Huber

unread,
Jun 29, 2022, 2:34:05 PM6/29/22
to event-driv...@googlegroups.com

Hi,

I've a streamlined refresh in the works that will support multi-group membership. Configurations will not be compatible, the "NG" fork is rule-driven and no longer follows the previous object-based approach. There's a new object hierarchy for realms, networks and hosts, but without  IP address dependencies.

Alas, documentation is still lacking and that will take some more time to complete. As a preview, I've copy-pasted a sample configuration (actually the one I currently use for testing) below.

Cheers,

Marc



#!/usr/local/sbin/tac_plus-ng

id = spawnd {
        background = no
#       single process = yes
        listen { port = 4949 realm = heck }
        spawn {


                instances min = 1
                instances max = 10
        }
}

id = tac_plus-ng {
        #debug = PACKET AUTHEN AUTHOR

        log syslog { }
        log accesslog { destination = /tmp/access.log  }
        log authorlog { destination = /tmp/author.log }

        access log = syslog
        access log = accesslog
        authorization log = authorlog
        accounting log = syslog

#       pap password = login

        dns preload file = sample/hosts.txt

        net private {
                net rfc1918 { address = 10.0.0.0/8,172.16.0.0/12 address = 192.168.0.0/16 }
                net local { address = 127.0.0.1 }
        }

        net filetest {
                address file = sample/addre*ses.txt
        }

        net lab {
                address = 100.67.0.0/23
        }

        net sublab {
                address = 100.67.0.64/28
                parent = lab
        }

        host world {
                #address = ::/0
                prompt = "Welcome\n"
                enable 15 = clear secret
                key = demo
                host rfc {
                        address = 172.16.0.0/12
                        prompt = "Welcome private\n"
                }
                #parent = rfc
        }

        host localhost {
                address = 127.0.0.1
                prompt = "Welcome home\n"
                parent = world
        }

        acl jumpstation { if (nac == 10.255.0.85) permit deny }
        acl demo1 { if (user == demo) permit deny }

        profile admin {
                service = shell {
                        set priv-lvl = 15
                        script { permit }
                }
        }

        profile engineering {
                service shell {
                        set priv-lvl = 7
                        script {
                          if (cmd == "") permit # shell startup
                          if (cmd =~ /^ping/) { message = "not now" deny }
                          if (nas == lab) deny
                          permit
                        }
                }
        }

        profile guest {
                service shell {
                        set priv-lvl = 1
                        script { permit }
                }
        }

        profile ppp {
                service ppp { protocol ip { set addr = 1.2.3.4 } }
        }

        group admin {
                group somegroup
                group engineering { }
        }

        user demo {
                password acl jumpstation { login = permit }

                password login = clear demo
                password pap = login
                member = engineering
        }

        user readonly {
                password { pap = clear readonly login = clear readonly }
        }

        ruleset {
                rule from-localhost {
                        enabled = yes
                        script {
                                if (nas == localhost && nac == private) {
                                        if (member ==  admin) {
                                                profile = admin
                                                permit
                                        }
                                        if (member ==  engineering ) {
                                                profile = engineering
                                                permit
                                        }
                                }
                        }
                }
                rule from-rfc {
                        enabled = yes
                        script {
                                if (nas == rfc) {
                                        if (member ==  admin) {
                                                profile = admin
                                                permit
                                        }
                                        if (member ==  engineering ) {
                                                profile = engineering
                                                permit
                                        }
                                }
                        }
                }
        }


        realm heck {
                ruleset {
                        rule from-rfc {
                                enabled = yes
                                script {
                                        if (nas == rfc) {
                                                if (member ==  admin) {
                                                        profile = admin
                                                        permit
                                                }
                                                if (member ==  engineering ) {
                                                        profile = engineering
                                                        permit
                                                }
                                        }
                                }
                        }
                }

        }
}


Reply all
Reply to author
Forward
0 new messages