freeRadius mit LDAP sehr langsam

Hallo,

wir haben bei uns direkt auf dem Server den freeradius-Server laufen. Allerdings nicht wie in der Anleitung beschrieben über ntlm sondern direkt über LDAP.

Das hat zwei Gründe:

  • zum einen ist das ntlm noch viel langsamer als der direkt LDAP-Zugriff (gemessen mit radtest, für 100 Radius-Anfragen braucht’s über LDAP ca. 8 Sekunden, über NTML ca, 20 Sekunden!)
  • zum anderen habe ich keine Möglichkeit gefunden, über ntml ein VLAN zuzuweisen, wir wollen die Gruppe „teachers“ in einem anderen VLAN haben als die Schüler über die selbe SSID.

Jetzt haben wir aber das Problem, dass in Stoßzeiten es teilweise 30 bis sogar 60 Sekunden dauert, bis ein Client sich am Radius angemeldet hat. Und das ist für viele Kollegen und Schüler natürlich sehr nervig. Manchmal ist die Anmeldung aber auch recht schnell (~5-10sec) fertig…

Evtl. hängt das auch mit dem Samba-Problem zusammen, wofür wir noch immer keine Lösung haben. Ich hab auch schon ein neues LMN7.1 installiert mit nur einem einzigen Nutzer und hier mal das Radius ausprobiert, auch hier dauert die Anmeldung teilweise sehr lange.

Auch der UniFi-Controller meldet bei vielen Clients eine lange Radius-Anmeldedauer.

Meine Konfigurationen sind so:

/etc/freeradius/3.0/sites-enabled/default

  • im authorize-Block:
	ldap
	if (ok && User-Password) {
           update {
                control:Auth-Type := LDAP
            }
        }
  • im authenticate-Block: (Anmerkung: nur die Gruppen teachers, personal, p_wlandhg und p_wlanamg sollen WLAN-Zugriff haben)
	Auth-Type LDAP {
		ldap
		if (LDAP-Group == "teachers" || LDAP-Group == "personal" || LDAP-Group == "p_wlandhg" || LDAP-Group == "p_wlanamg") {
			noop
		} else {
			reject
		}
	}

/etc/freeradius/3.0/sites-enabled/inner-tunnel

  • im authenticate-Block identisch zur default-Datei

/etc/freeradius/3.0/mods-enabled/ldap

  • server, identity, password, base_dn angegeben
  • user-filter: filter = "(&(objectClass=person)(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}))"
  • group-filter: filter = '(objectClass=group)'

/etc/freeradius/3.0/mod-enabled/eap

	tls-config tls-common {
		private_key_password = whatever
		private_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
		certificate_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
		ca_file = /etc/ssl/certs/ca-certificates.crt
		dh_file = ${certdir}/dh
		ca_path = ${cadir}
		cipher_list = "DEFAULT"
		cipher_server_preference = no
		ecdh_curve = "prime256v1"
		cache {
			enable = yes
			lifetime = 24 # hours
			name = "EAP module"
			persist_dir = "${logdir}/tlscache"
			store {
				Tunnel-Private-Group-Id
			}
		}
		verify {
		}
		ocsp {
			enable = no
			override_cert_url = yes
			url = "http://127.0.0.1/ocsp/"
		}
	}
	tls {
		tls = tls-common
	}
	ttls {
		tls = tls-common
		default_eap_type = md5
		copy_request_to_tunnel = no
		use_tunneled_reply = no
		virtual_server = "inner-tunnel"
	}
	peap {
		tls = tls-common
		default_eap_type = mschapv2
		copy_request_to_tunnel = yes
		use_tunneled_reply = no
		virtual_server = "inner-tunnel"
	}

/etc/freeradius/3.0/users

# ganz am Ende:
# Lehrer-WLAN
DEFAULT Ldap-Group == teachers
        Tunnel-Type = VLAN,
        Tunnel-Medium-Type = 6,
        Tunnel-Private-Group-ID = 10

# Schüler-WLAN DHG
DEFAULT Ldap-Group == p_wlandhg
        Tunnel-Type = 13,
        Tunnel-Medium-Type = 6,
        Tunnel-Private-Group-Id = 12

# Schüler-WLAN AMG
DEFAULT Ldap-Group == p_wlanamg
        Tunnel-Type = 13,
        Tunnel-Medium-Type = 6,
        Tunnel-Private-Group-Id = 11

# Personal ebenfalls im Lehrer-WLAN
DEFAULT Ldap-Group == personal
        Tunnel-Type = VLAN,
        Tunnel-Medium-Type = 6,
        Tunnel-Private-Group-ID = 10

DEFAULT Auth-Type := Reject

ich muss zugeben, dass ich mich mit der freeradius-Konfiguration nicht so wirklich gut auskenne. Prinzipiell funktioniert ja die Konfiguration, aber teilweise halt recht langsam. Und ich kann nicht so wirklich sagen, ob das jetzt am Radius oder am Server selbst liegt.

Getestet habe ich jeweils lokal mit
time for i in {1..100}; do radtest USER PASSWORD localhost 1812 testing123 > /dev/null; done

wie gesagt kommt hier bei der ntlm-Konfiguration (nach der LMN-Anleitung) ca. 20 Sekunden raus, bei der oben stehenden LDAP-Konfiguration ca. 8 Sekunden.

Aber trotzdem scheint es noch immer nicht schnell genug für eine ordentliche Anmeldung am WLAN zu sein…

Vielleicht hat hier ja jemand einen Tipp, wo ich noch nach dem Problem suchen könnte.

Danke und Grüße
Alex

Hallo Alex,

da wir letzten Samstag ebenfalls unseren FreeRadius aufgesetzt haben:
Wir haben die VLAN-Thematik so gelöst, dass wir die Anmeldung über NTLM gemacht haben aber zusätzlich im Authorize dann eine LDAP-Abfrage abgesetzt haben, um die benötigten Nutzer-Attribute abzurufen - und dann haben wir mit diesen Daten die VLAN-Zuweisung vorgenommen. Im Prinzip ein Standard-LDAP-Setup, nur dass im Authenticate ntlm statt ldap verwendet wird. Wir haben uns für diesen Aufbau entschieden, weil FreeRadius selbst sagt, dass es selbst die Authentifizierung übernehmen möchte, statt diese an LDAP abzugeben (zumindest besagt das ein Kommentar in der Default-Config). Sollte aber am Ende - vermutlich - keinen großen Unterschied machen.

Von der Geschwindigkeit her sehen wir bei uns keine Probleme mit NTLM. Wir haben ca. 600 Geräte im WLAN, schalten jeden Nutzer in ein VLAN (also nicht in einzelne aber bei jedem Nutzer wird ein Tag ausgegeben …) und die Authentifizierung erfolgt dennoch ohne spürbare Verzögerung.
Hast du noch einen anderen Dienst über LDAP angebunden (Moodle, Nextcloud, …) - und wenn ja, siehst du dort eine ähnlich schlechte Performanz bei der Anmeldung? Gegebenenfalls könntest du diese auch mittels ldapsearch testen, dann könnte man zumindest sagen, ob es am LDAP selbst liegt?

Viele Grüße
Sebastian

Nachtrag: du authentifizierst nur im outer-tunnel über LDAP, aber nicht im inner-tunnel?

Hallo Sebastian,

ah, man kann das auch kombinieren? Wie gesagt: die Radius-Konfiguration ist für mich größtenteils noch ein Rätsel, das hab ich aus verschiedenen Anleitungen zusammengebastelt :see_no_evil:

Du hast die Gruppenzugehörigkeit über LDAP dann im post-auth?

Ich weiß nur: mache ich das nach der LMN-Anleitung mit NTLM (also ohne Abfrage der LDAP-Benutzerattribute) dauert ein
time for i in {1..100}; do radtest USER PASSWORD localhost 1812 testing123 > /dev/null; done
ungefähr doppelt so lange, wie wenn ich das über LDAP inklusive Gruppenzugehörigkeit mache…

Kannst du mal das evtl. bei dir ausprobieren, wie lange Radius hier für die 100 Anmeldungen braucht?

Ja, hängt alles dran: Moodle, Nextcloud, Untis, BBB, peerTube, Gitea, Mailcow,… Da merke ich keine Verzögerung. Deshalb schiebe ich das ja auf den Radius.

Mit outer-tunnel meinst du das default? Bei mir ist default und inner-tunnel quasi identisch.

Willst du vielleicht deine Konfigurationen mal posten, damit ich’s damit ausprobieren kann?

Grüße
Alex

Hallo Alex,

sorry für die späte Antwort. Kann ich gerne machen, allerdings ohne Garantie, dass das sinnvoll ist, was ich da gebaut habe. Ich hoffe es sind alle relevanten Dateien dabei, sonst gerne nochmal nachfragen. Wir arbeiten mit FreeRadius 3.0.26-1.

Die Config ist zudem bei uns ursprünglich für Logodidact gebaut worden, dann für die paedML angepasst worden und läuft jetzt mit LMN - es gibt also den ein oder anderen Teil, der nicht mehr nötig wäre, aber einfach nicht rausgeworfen wurde (NetworkAccess zum Beispiel oder UserPassword).

Viele Grüße
Sebastian

# sites-enabled/inner-tunnel
server inner-tunnel {
listen {
       ipaddr = 127.0.0.1
       port = 18120
       type = auth
}
authorize {
        filter_username
        chap
        mschap
        suffix
        update control {
                &Proxy-To-Realm := domain.schule
        }
        eap {
                ok = return
        }
        files
        expiration
        logintime
        pap
}
authenticate {
        ntlm_auth
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        eap
}
session {
        radutmp
}
post-auth {
        update outer.session-state {
                &User-Name = &User-Name
        }
        if (1) {
                update reply {
                        User-Name !* ANY
                        Message-Authenticator !* ANY
                        EAP-Message !* ANY
                        Proxy-State !* ANY
                        MS-MPPE-Encryption-Types !* ANY
                        MS-MPPE-Encryption-Policy !* ANY
                        MS-MPPE-Send-Key !* ANY
                        MS-MPPE-Recv-Key !* ANY
                }
                update {
                        &outer.session-state: += &reply:
                }
        }
        Post-Auth-Type REJECT {
                attr_filter.access_reject
                update outer.session-state {
                        &Module-Failure-Message := &request:Module-Failure-Message
                }
        }
}
pre-proxy {
}
post-proxy {
        eap
}
} # inner-tunnel server block
# sites-enabled/server
client domain_8021x {
        ipaddr = 0.0.0.0/0
        secret = dontlookatme
        virtual_server = schule_8021x
}
server domain_8021x {
        authorize {
                filter_username
                preprocess
                chap
                mschap
                digest
                suffix
                eap {
                        ok = return
                }
                ldap
                if (&LDAP-Group[*] == "CN=role-student,OU=Groups,OU=GLOBAL,DC=lmn,DC=domain,DC=schule") {
                        if (&LDAP-Group[*] == "CN=staff,OU=staff,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
                        }
                        elsif (&LDAP-Group[*] == "CN=airtame,OU=Airtame,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
                        }
                        elsif (&LDAP-Group[*] == "CN=technik,OU=Technik,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
                        }
                        elsif (&LDAP-Group[*] == "CN=ipad,OU=Ipad,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
                        }
                        else {
                                update control {
                                        Login-Time               = 'Wk0700-1900'
                                }
                        }
                }
                expiration
                logintime
                pap
        }
        authenticate {
                ntlm_auth
                Auth-Type PAP {
                        pap
                }
                Auth-Type CHAP {
                        chap
                }
                Auth-Type MS-CHAP {
                        mschap
                }
                mschap
                digest
                eap
        }
        preacct {
                preprocess
                acct_unique
                suffix
        }
        accounting {
                unix
                radutmp
                sradutmp
                exec
                attr_filter.accounting_response
        }
        post-auth {
                update {
                        User-Name := &session-state:User-Name
                }
                get_user_role
                if (&session-state:User-Name == "cisco-wlan-ap") {
                        update reply {
                                Tunnel-Medium-Type := IEEE-802
                                Tunnel-Private-Group-ID:= 5
                                Tunnel-Type:= VLAN
                                Egress-VLANID += "%{expr: 0x31000000 + 10}"
                                Egress-VLANID += "%{expr: 0x31000000 + 11}"
                                Egress-VLANID += "%{expr: 0x31000000 + 12}"
                                Egress-VLANID += "%{expr: 0x31000000 + 24}"
                                Egress-VLANID += "%{expr: 0x31000000 + 31}"
                                Egress-VLANID += "%{expr: 0x31000000 + 33}"
                        }
                }
                else {
                        if (UserRole == "staff") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 13
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (&reply:UserRole == "staff") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 13
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (UserRole == "airtame") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 10
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (&reply:UserRole == "airtame") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 10
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (UserRole == "technik") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 33
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (&reply:UserRole == "technik") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 33
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (UserRole == "ipad") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 13
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (&reply:UserRole == "ipad") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 13
                                        Tunnel-Type:= VLAN
                                }
                        }
                        elsif (&reply:UserRole == "student") {
                                if (&reply:UserSophomorixRole == "staff") {
                                        update reply {
                                                Tunnel-Medium-Type := IEEE-802
                                                Tunnel-Private-Group-ID:= 13
                                                Tunnel-Type:= VLAN
                                        }
                                }
                                elsif (&reply:UserSophomorixRole == "airtame") {
                                        update reply {
                                                Tunnel-Medium-Type := IEEE-802
                                                Tunnel-Private-Group-ID:= 10
                                                Tunnel-Type:= VLAN
                                        }
                                }
                                elsif (&reply:UserSophomorixRole == "technik") {
                                        update reply {
                                                Tunnel-Medium-Type := IEEE-802
                                                Tunnel-Private-Group-ID:= 33
                                                Tunnel-Type:= VLAN
                                        }
                                }
                                elsif (&reply:UserSophomorixRole == "ipad") {
                                        update reply {
                                                Tunnel-Medium-Type := IEEE-802
                                                Tunnel-Private-Group-ID:= 13
                                                Tunnel-Type:= VLAN
                                        }
                                }
                                else {
                                        update reply {
                                                Tunnel-Medium-Type := IEEE-802
                                                Tunnel-Private-Group-ID:= 12
                                                Tunnel-Type:= VLAN
                                        }
                                }
                        }
                        elsif (&reply:UserRole == "teacher" || UserRole == "teacher") {
                                update reply {
                                        Tunnel-Medium-Type := IEEE-802
                                        Tunnel-Private-Group-ID:= 10
                                        Tunnel-Type:= VLAN
                                }
                        }
                }
                update reply {
                        &UserRole !* ANY
                }
                if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) {
                        update reply {
                                &User-Name !* ANY
                        }
                }
                update {
                        &reply: += &session-state:
                }
                exec
                remove_reply_message_if_eap
                Post-Auth-Type REJECT {
                        attr_filter.access_reject
                        eap
                        remove_reply_message_if_eap
                }
                Post-Auth-Type Challenge {
                }
        }
        post-proxy {
                eap
        }
        session {
                radutmp
        }
}
#mods-enabled/eap

eap {
        default_eap_type = peap
        timer_expire = 60
        ignore_unknown_eap_types = no
        cisco_accounting_username_bug = no
        max_sessions = ${max_requests}
        md5 {
        }
        gtc {
                auth_type = PAP
        }
        tls-config tls-eap-peap {
                private_key_file = ${certdir}/privkey.pem
                certificate_file = ${certdir}/fullchain.pem
                dh_file = ${certdir}/dh
                ca_path = ${certdir}
                cipher_list = "DEFAULT@SECLEVEL=1"
                cipher_server_preference = no
                tls_min_version = "1.0"
                tls_max_version = "1.2"
                ecdh_curve = "prime256v1"
                cache {
                        enable = no
                        lifetime = 12 # hours
                        store {
                                Tunnel-Private-Group-Id
                        }
                }
                verify {
                }
                ocsp {
                        enable = no
                        override_cert_url = yes
                        url = "http://127.0.0.1/ocsp/"
                }
        }
        tls-config tls-eap-tls {
                private_key_password = "dontlookat me"
                private_key_file = ${certdir}/server_local.pem
                certificate_file = ${certdir}/server_local.pem
                ca_file = ${cadir}/ca.pem
                dh_file = ${certdir}/dh
                ca_path = ${cadir}
                cipher_list = "ALL:!EXPORT:!eNULL:!SSLv2"
                cipher_server_preference = no
                tls_min_version = "1.0"
                tls_max_version = "1.2"
                ecdh_curve = "prime256v1"
                cache {
                        enable = no
                        lifetime = 12 # hours
                        store {
                                Tunnel-Private-Group-Id
                        }
                }
                verify {
                }
                ocsp {
                        enable = no
                        override_cert_url = yes
                        url = "http://127.0.0.1/ocsp/"
                }
        }
        tls {
                tls = tls-eap-tls
                virtual_server = check-eap-tls
        }
        ttls {
                tls = tls-eap-tls
                default_eap_type = md5
                copy_request_to_tunnel = yes
                use_tunneled_reply = no
                virtual_server = "inner-tunnel"
        }
        peap {
                tls = tls-eap-peap
                default_eap_type = mschapv2
                copy_request_to_tunnel = yes
                use_tunneled_reply = no
                virtual_server = "inner-tunnel"
        }
        mschapv2 {
                send_error = yes
                identity = "RADIUS Meine Schule"
        }
        fast {
                tls = tls-eap-peap
                cipher_list = "ALL:!EXPORT:!eNULL:!SSLv2@SECLEVEL=0"
                pac_lifetime = 604800
                authority_identity = "domain.schule"
                pac_opaque_key = "deadbeef1234567890c0ffee123456789"
                virtual_server = inner-tunnel
        }
}
# mods-enabled/ldap

ldap {
        server = "ldaps://10.0.0.1:636/"
        identity = "CN=radius-binduser,OU=Management,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule"
        password = "dontlookatme"
        base_dn = "DC=lmn,DC=domain,DC=schule"
        sasl {
        }
x
        update {
                control:Password-With-Header    += 'userPassword'
                reply:Reply-Message             := 'radiusReplyMessage'
                reply:Tunnel-Type               := 'radiusTunnelType'
                reply:Tunnel-Medium-Type        := 'radiusTunnelMediumType'
                reply:Tunnel-Private-Group-ID   := 'radiusTunnelPrivategroupId'
                reply:UserRole                  := 'sophomorixRole'
                reply:UserSophomorixRole        := 'sophomorixAdminClass'
                control:                        += 'radiusControlAttribute'
                request:                        += 'radiusRequestAttribute'
                reply:                          += 'radiusReplyAttribute'
        }
        user_dn = "LDAP-UserDn"
        user {
                base_dn = "${..base_dn}"
                filter = "(&(objectclass=person)(cn=%{%{Stripped-User-Name}:-%{mschap:User-Name}}))"
                sasl {
                }
        }
        group {
                base_dn = "${..base_dn}"
                filter = '(objectClass=group)'
                membership_filter = "(member=%{control:${..user_dn}})"
                membership_attribute = 'memberOf'
        }
        profile {
        }
        client {
                base_dn = "${..base_dn}"
                filter = '(objectClass=radiusClient)'
                template {
                }
                attribute {
                        ipaddr                          = 'radiusClientIdentifier'
                        secret                          = 'radiusClientSecret'
                }
        }
        accounting {
                reference = "%{tolower:type.%{Acct-Status-Type}}"
                type {
                        start {
                                update {
                                        description := "Online at %S"
                                }
                        }
                        interim-update {
                                update {
                                        description := "Last seen at %S"
                                }
                        }
                        stop {
                                update {
                                        description := "Offline at %S"
                                }
                        }
                }
        }
        post-auth {
                update {
                        description := "Authenticated at %S"
                }
        }
        options {
                chase_referrals = yes
                rebind = yes
                res_timeout = 10
                srv_timelimit = 3
                net_timeout = 1
                idle = 60
                probes = 3
                interval = 3
                ldap_debug = 0x0028
        }
        tls {
        }
        pool {
                start = ${thread[pool].start_servers}
                min = ${thread[pool].min_spare_servers}
                max = ${thread[pool].max_servers}
                spare = ${thread[pool].max_spare_servers}
                uses = 0
                retry_delay = 30
                lifetime = 0
                idle_timeout = 60
        }
}
# mods-enabled/ntlm_auth
exec ntlm_auth {
        wait = yes
        program = "/usr/bin/ntlm_auth --allow-mschapv2 --request-nt-key --domain=lmn --require-membership-of=lmn\wifi --username=%{mschap:User-Name} --password=%{User-Password}"
}
# mods-available/mschap
mschap {
        use_mppe = yes
        with_ntdomain_hack = yes
        ntlm_auth = "/usr/bin/ntlm_auth --allow-mschapv2 --request-nt-key --domain=lmn --require-membership-of=lmn\wifi --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}"
        pool {
                start = ${thread[pool].start_servers}
                min = ${thread[pool].min_spare_servers}
                max = ${thread[pool].max_servers}
                spare = ${thread[pool].max_spare_servers}
                uses = 0
                retry_delay = 30
                lifetime = 86400
                cleanup_interval = 300
                idle_timeout = 600
        }
        passchange {
        }
}
# policy.d/group_check
get_user_role {
  if (&LDAP-Group[*] == "CN=teachers,OU=Teachers,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "teacher"
    }
  }
  elsif (&LDAP-Group[*] == "CN=staff,OU=staff,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "staff"
    }
  }
  elsif (&LDAP-Group[*] == "CN=airtame,OU=Airtame,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "airtame"
    }
  }
  elsif (&LDAP-Group[*] == "CN=technik,OU=Technik,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "technik"
    }
  }
  elsif (&LDAP-Group[*] == "CN=ipad,OU=Ipad,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "ipad"
    }
  }
  elsif (&LDAP-Group[*] == "CN=role-student,OU=Groups,OU=GLOBAL,DC=lmn,DC=domain,DC=schule") {
    update reply {
      UserRole := "student"
    }
  }
}
# dictionary
ATTRIBUTE       UserRole                3003    string
ATTRIBUTE       UserSophomorixRole      3004    string
ATTRIBUTE       NetworkAccess           3005    integer