Назад | Перейти на главную страницу

FreeRadius возвращает группы пользователей в поле класса

Я использую strongSwan для аутентификации с помощью FreeRadius, что он и делает, но теперь мне нужно, чтобы FreeRadius возвращал группы пользователей в поле «Класс», чтобы их можно было проверить с помощью strongSwan [1].

я использую winbind и ntlm_auth на freeradius для аутентификации пользователей, который работает.

Мне удалось придумать, как добавить в ответ дополнительные поля, поставив update reply в файле /etc/raddb/sites-available/default

post-auth {
   ...
   update reply {
       Class = "%{Group}"
   }
   ...
}

Это то место, куда его поставить ??

но, как вы можете видеть ниже, класс равен нулю.

(3) Sent Access-Accept Id 223 from 10.0.0.247:1812 to 10.0.0.120:48653 length 0
(3)   MS-MPPE-Encryption-Policy = Encryption-Allowed
(3)   MS-MPPE-Encryption-Types = RC4-40or128-bit-Allowed
(3)   MS-MPPE-Send-Key = 0x316216f0c4d55abb0cb8c2c741cad90c
(3)   MS-MPPE-Recv-Key = 0x1ec76bc2958017969cbc3d67e716d4a4
(3)   EAP-Message = 0x03030004
(3)   Message-Authenticator = 0x00000000000000000000000000000000
(3)   User-Name = "christian.salway"
(3)   Class = 0x
(3) Finished request

Как я могу вернуть группы Active Directory пользователя в поле Class?

[1] https://wiki.strongswan.org/projects/strongswan/wiki/EapRadius#Group-selection

(0) Received Access-Request Id 179 from 10.0.0.120:46201 to 10.0.0.247:1812 length 159
(0)   User-Name = "christian.salway"
(0)   NAS-Port-Type = Virtual
(0)   Service-Type = Framed-User
(0)   NAS-Port = 4
(0)   NAS-Port-Id = "pod"
(0)   NAS-IP-Address = 10.0.0.120
(0)   Called-Station-Id = "10.0.0.120[4500]"
(0)   Calling-Station-Id = "148.252.225.26[46452]"
(0)   EAP-Message = 0x020000150163687269737469616e2e73616c776179
(0)   NAS-Identifier = "test.vpn"
(0)   Message-Authenticator = 0x3a5d4de82ee89b6e96ecaf7051593242
(0) # Executing section authorize from file /etc/raddb/sites-enabled/default
(0)   authorize {
(0)     policy filter_username {
(0)       if (&User-Name) {
(0)       if (&User-Name)  -> TRUE
(0)       if (&User-Name)  {
(0)         if (&User-Name =~ / /) {
(0)         if (&User-Name =~ / /)  -> FALSE
(0)         if (&User-Name =~ /@[^@]*@/ ) {
(0)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(0)         if (&User-Name =~ /\.\./ ) {
(0)         if (&User-Name =~ /\.\./ )  -> FALSE
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   -> FALSE
(0)         if (&User-Name =~ /\.$/)  {
(0)         if (&User-Name =~ /\.$/)   -> FALSE
(0)         if (&User-Name =~ /@\./)  {
(0)         if (&User-Name =~ /@\./)   -> FALSE
(0)       } # if (&User-Name)  = notfound
(0)     } # policy filter_username = notfound
(0)     [preprocess] = ok
(0)     [chap] = noop
(0)     [mschap] = noop
(0)     [digest] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: No '@' in User-Name = "christian.salway", looking up realm NULL
(0) suffix: No such realm "NULL"
(0)     [suffix] = noop
(0) eap: Peer sent EAP Response (code 2) ID 0 length 21
(0) eap: EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize
(0)     [eap] = ok
(0)   } # authorize = ok
(0) Found Auth-Type = eap
(0) # Executing group from file /etc/raddb/sites-enabled/default
(0)   authenticate {
(0) eap: Peer sent packet with method EAP Identity (1)
(0) eap: Calling submodule eap_md5 to process data
(0) eap_md5: Issuing MD5 Challenge
(0) eap: Sending EAP Request (code 1) ID 1 length 22
(0) eap: EAP session adding &reply:State = 0x54b7902754b694bf
(0)     [eap] = handled
(0)   } # authenticate = handled
(0) Using Post-Auth-Type Challenge
(0) # Executing group from file /etc/raddb/sites-enabled/default
(0)   Challenge { ... } # empty sub-section is ignored
(0) Sent Access-Challenge Id 179 from 10.0.0.247:1812 to 10.0.0.120:46201 length 0
(0)   EAP-Message = 0x010100160410d6f72d6ea8b978ed7e177475d8235482
(0)   Message-Authenticator = 0x00000000000000000000000000000000
(0)   State = 0x54b7902754b694bfe21d25f70628a0fb
(0) Finished request
Waking up in 4.9 seconds.
(1) Received Access-Request Id 57 from 10.0.0.120:50205 to 10.0.0.247:1812 length 162
(1)   User-Name = "christian.salway"
(1)   NAS-Port-Type = Virtual
(1)   Service-Type = Framed-User
(1)   NAS-Port = 4
(1)   NAS-Port-Id = "pod"
(1)   NAS-IP-Address = 10.0.0.120
(1)   Called-Station-Id = "10.0.0.120[4500]"
(1)   Calling-Station-Id = "148.252.225.26[46452]"
(1)   EAP-Message = 0x02010006031a
(1)   NAS-Identifier = "test.vpn"
(1)   State = 0x54b7902754b694bfe21d25f70628a0fb
(1)   Message-Authenticator = 0xec9534905c7948436fba36fac34097e9
(1) session-state: No cached attributes
(1) # Executing section authorize from file /etc/raddb/sites-enabled/default
(1)   authorize {
(1)     policy filter_username {
(1)       if (&User-Name) {
(1)       if (&User-Name)  -> TRUE
(1)       if (&User-Name)  {
(1)         if (&User-Name =~ / /) {
(1)         if (&User-Name =~ / /)  -> FALSE
(1)         if (&User-Name =~ /@[^@]*@/ ) {
(1)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(1)         if (&User-Name =~ /\.\./ ) {
(1)         if (&User-Name =~ /\.\./ )  -> FALSE
(1)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(1)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   -> FALSE
(1)         if (&User-Name =~ /\.$/)  {
(1)         if (&User-Name =~ /\.$/)   -> FALSE
(1)         if (&User-Name =~ /@\./)  {
(1)         if (&User-Name =~ /@\./)   -> FALSE
(1)       } # if (&User-Name)  = notfound
(1)     } # policy filter_username = notfound
(1)     [preprocess] = ok
(1)     [chap] = noop
(1)     [mschap] = noop
(1)     [digest] = noop
(1) suffix: Checking for suffix after "@"
(1) suffix: No '@' in User-Name = "christian.salway", looking up realm NULL
(1) suffix: No such realm "NULL"
(1)     [suffix] = noop
(1) eap: Peer sent EAP Response (code 2) ID 1 length 6
(1) eap: No EAP Start, assuming it's an on-going EAP conversation
(1)     [eap] = updated
(1)     [files] = noop
rlm_ldap (ldap): Reserved connection (0)
(1) ldap: EXPAND (uid=%{%{Stripped-User-Name}:-%{User-Name}})
(1) ldap:    --> (uid=christian.salway)
(1) ldap: Performing search in "OU=Users,OU=directory,DC=directory,DC=local" with filter "(uid=christian.salway)", scope "sub"
(1) ldap: Waiting for search result...
(1) ldap: Search returned no results
rlm_ldap (ldap): Released connection (0)
Need 5 more connections to reach 10 spares
rlm_ldap (ldap): Opening additional connection (5), 1 of 27 pending slots used
rlm_ldap (ldap): Connecting to ldap://10.0.14.211:389
TLSMC: MozNSS compatibility interception begins.
tlsmc_convert: INFO: cannot open the NSS DB, expecting PEM configuration is present.
tlsmc_intercept_initialization: INFO: successfully intercepted TLS initialization. Continuing with OpenSSL only.
TLSMC: MozNSS compatibility interception ends.
rlm_ldap (ldap): Waiting for bind result...
rlm_ldap (ldap): Bind successful
(1)     [ldap] = notfound
(1)     [expiration] = noop
(1)     [logintime] = noop
(1)   } # authorize = updated
(1) Found Auth-Type = eap
(1) # Executing group from file /etc/raddb/sites-enabled/default
(1)   authenticate {
(1) eap: Expiring EAP session with state 0x54b7902754b694bf
(1) eap: Finished EAP session with state 0x54b7902754b694bf
(1) eap: Previous EAP request found for state 0x54b7902754b694bf, released from the list
(1) eap: Peer sent packet with method EAP NAK (3)
(1) eap: Found mutually acceptable type MSCHAPv2 (26)
(1) eap: Calling submodule eap_mschapv2 to process data
(1) eap_mschapv2: Issuing Challenge
(1) eap: Sending EAP Request (code 1) ID 2 length 43
(1) eap: EAP session adding &reply:State = 0x54b7902755b58abf
(1)     [eap] = handled
(1)   } # authenticate = handled
(1) Using Post-Auth-Type Challenge
(1) # Executing group from file /etc/raddb/sites-enabled/default
(1)   Challenge { ... } # empty sub-section is ignored
(1) Sent Access-Challenge Id 57 from 10.0.0.247:1812 to 10.0.0.120:50205 length 0
(1)   EAP-Message = 0x0102002b1a01020026100ebe1822b5ac80ccb4c6865f139ce768667265657261646975732d332e302e3133
(1)   Message-Authenticator = 0x00000000000000000000000000000000
(1)   State = 0x54b7902755b58abfe21d25f70628a0fb
(1) Finished request
Waking up in 4.9 seconds.
(2) Received Access-Request Id 49 from 10.0.0.120:58147 to 10.0.0.247:1812 length 231
(2)   User-Name = "christian.salway"
(2)   NAS-Port-Type = Virtual
(2)   Service-Type = Framed-User
(2)   NAS-Port = 4
(2)   NAS-Port-Id = "pod"
(2)   NAS-IP-Address = 10.0.0.120
(2)   Called-Station-Id = "10.0.0.120[4500]"
(2)   Calling-Station-Id = "148.252.225.26[46452]"
(2)   EAP-Message = 0x0202004b1a02020046313273ea09204ebe6c15324a74ef6c608600000000000000004e9f07d6254012928721219474ab36964e7ee601940acd530063687269737469616e2e73616c776179
(2)   NAS-Identifier = "test.vpn"
(2)   State = 0x54b7902755b58abfe21d25f70628a0fb
(2)   Message-Authenticator = 0xda48ace7787828ea6b17398cd2252839
(2) session-state: No cached attributes
(2) # Executing section authorize from file /etc/raddb/sites-enabled/default
(2)   authorize {
(2)     policy filter_username {
(2)       if (&User-Name) {
(2)       if (&User-Name)  -> TRUE
(2)       if (&User-Name)  {
(2)         if (&User-Name =~ / /) {
(2)         if (&User-Name =~ / /)  -> FALSE
(2)         if (&User-Name =~ /@[^@]*@/ ) {
(2)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(2)         if (&User-Name =~ /\.\./ ) {
(2)         if (&User-Name =~ /\.\./ )  -> FALSE
(2)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(2)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   -> FALSE
(2)         if (&User-Name =~ /\.$/)  {
(2)         if (&User-Name =~ /\.$/)   -> FALSE
(2)         if (&User-Name =~ /@\./)  {
(2)         if (&User-Name =~ /@\./)   -> FALSE
(2)       } # if (&User-Name)  = notfound
(2)     } # policy filter_username = notfound
(2)     [preprocess] = ok
(2)     [chap] = noop
(2)     [mschap] = noop
(2)     [digest] = noop
(2) suffix: Checking for suffix after "@"
(2) suffix: No '@' in User-Name = "christian.salway", looking up realm NULL
(2) suffix: No such realm "NULL"
(2)     [suffix] = noop
(2) eap: Peer sent EAP Response (code 2) ID 2 length 75
(2) eap: No EAP Start, assuming it's an on-going EAP conversation
(2)     [eap] = updated
(2)     [files] = noop
rlm_ldap (ldap): Reserved connection (1)
(2) ldap: EXPAND (uid=%{%{Stripped-User-Name}:-%{User-Name}})
(2) ldap:    --> (uid=christian.salway)
(2) ldap: Performing search in "OU=Users,OU=directory,DC=directory,DC=local" with filter "(uid=christian.salway)", scope "sub"
(2) ldap: Waiting for search result...
(2) ldap: Search returned no results
rlm_ldap (ldap): Released connection (1)
(2)     [ldap] = notfound
(2)     [expiration] = noop
(2)     [logintime] = noop
(2)   } # authorize = updated
(2) Found Auth-Type = eap
(2) # Executing group from file /etc/raddb/sites-enabled/default
(2)   authenticate {
(2) eap: Expiring EAP session with state 0x54b7902755b58abf
(2) eap: Finished EAP session with state 0x54b7902755b58abf
(2) eap: Previous EAP request found for state 0x54b7902755b58abf, released from the list
(2) eap: Peer sent packet with method EAP MSCHAPv2 (26)
(2) eap: Calling submodule eap_mschapv2 to process data
(2) eap_mschapv2: # Executing group from file /etc/raddb/sites-enabled/default
(2) eap_mschapv2:   authenticate {
(2) mschap: Creating challenge hash with username: christian.salway
(2) mschap: Client is using MS-CHAPv2
(2) mschap: Executing: /usr/bin/ntlm_auth --request-nt-key --username=%{mschap:User-Name} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}:
(2) mschap: EXPAND --username=%{mschap:User-Name}
(2) mschap:    --> --username=christian.salway
(2) mschap: Creating challenge hash with username: christian.salway
(2) mschap: EXPAND --challenge=%{%{mschap:Challenge}:-00}
(2) mschap:    --> --challenge=901534adcf416acd
(2) mschap: EXPAND --nt-response=%{%{mschap:NT-Response}:-00}
(2) mschap:    --> --nt-response=4e9f07d6254012928721219474ab36964e7ee601940acd53
(2) mschap: Program returned code (0) and output 'NT_KEY: 7EAE67D582A054C071FC841CE38DCC98'
(2) mschap: Adding MS-CHAPv2 MPPE keys
(2)     [mschap] = ok
(2)   } # authenticate = ok
(2) MSCHAP Success
(2) eap: Sending EAP Request (code 1) ID 3 length 51
(2) eap: EAP session adding &reply:State = 0x54b7902756b48abf
(2)     [eap] = handled
(2)   } # authenticate = handled
(2) Using Post-Auth-Type Challenge
(2) # Executing group from file /etc/raddb/sites-enabled/default
(2)   Challenge { ... } # empty sub-section is ignored
(2) Sent Access-Challenge Id 49 from 10.0.0.247:1812 to 10.0.0.120:58147 length 0
(2)   EAP-Message = 0x010300331a0302002e533d35394541323943313237434245394134354338414433394535364535343233443236323045443943
(2)   Message-Authenticator = 0x00000000000000000000000000000000
(2)   State = 0x54b7902756b48abfe21d25f70628a0fb
(2) Finished request
Waking up in 4.9 seconds.
(3) Received Access-Request Id 197 from 10.0.0.120:49731 to 10.0.0.247:1812 length 162
(3)   User-Name = "christian.salway"
(3)   NAS-Port-Type = Virtual
(3)   Service-Type = Framed-User
(3)   NAS-Port = 4
(3)   NAS-Port-Id = "pod"
(3)   NAS-IP-Address = 10.0.0.120
(3)   Called-Station-Id = "10.0.0.120[4500]"
(3)   Calling-Station-Id = "148.252.225.26[46452]"
(3)   EAP-Message = 0x020300061a03
(3)   NAS-Identifier = "test.vpn"
(3)   State = 0x54b7902756b48abfe21d25f70628a0fb
(3)   Message-Authenticator = 0xefadb173cef56d9ee5ec66621fd0211f
(3) session-state: No cached attributes
(3) # Executing section authorize from file /etc/raddb/sites-enabled/default
(3)   authorize {
(3)     policy filter_username {
(3)       if (&User-Name) {
(3)       if (&User-Name)  -> TRUE
(3)       if (&User-Name)  {
(3)         if (&User-Name =~ / /) {
(3)         if (&User-Name =~ / /)  -> FALSE
(3)         if (&User-Name =~ /@[^@]*@/ ) {
(3)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(3)         if (&User-Name =~ /\.\./ ) {
(3)         if (&User-Name =~ /\.\./ )  -> FALSE
(3)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(3)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   -> FALSE
(3)         if (&User-Name =~ /\.$/)  {
(3)         if (&User-Name =~ /\.$/)   -> FALSE
(3)         if (&User-Name =~ /@\./)  {
(3)         if (&User-Name =~ /@\./)   -> FALSE
(3)       } # if (&User-Name)  = notfound
(3)     } # policy filter_username = notfound
(3)     [preprocess] = ok
(3)     [chap] = noop
(3)     [mschap] = noop
(3)     [digest] = noop
(3) suffix: Checking for suffix after "@"
(3) suffix: No '@' in User-Name = "christian.salway", looking up realm NULL
(3) suffix: No such realm "NULL"
(3)     [suffix] = noop
(3) eap: Peer sent EAP Response (code 2) ID 3 length 6
(3) eap: No EAP Start, assuming it's an on-going EAP conversation
(3)     [eap] = updated
(3)     [files] = noop
rlm_ldap (ldap): Reserved connection (2)
(3) ldap: EXPAND (samaccountname=%{%{Stripped-User-Name}:-%{User-Name}})
(3) ldap:    --> (samaccountname=christian.salway)
(3) ldap: Performing search in "OU=Users,OU=directory,DC=directory,DC=local" with filter "(samaccountname=christian.salway)", scope "sub"
(3) ldap: Waiting for search result...
(3) ldap: User object found at DN "CN=christian.salway,OU=Users,OU=directory,DC=directory,DC=local"
(3) ldap: Processing user attributes
(3) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute
(3) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure)
rlm_ldap (ldap): Released connection (2)
(3)     [ldap] = notfound
(3)     [expiration] = noop
(3)     [logintime] = noop
(3)   } # authorize = updated
(3) Found Auth-Type = eap
(3) # Executing group from file /etc/raddb/sites-enabled/default
(3)   authenticate {
(3) eap: Expiring EAP session with state 0x54b7902756b48abf
(3) eap: Finished EAP session with state 0x54b7902756b48abf
(3) eap: Previous EAP request found for state 0x54b7902756b48abf, released from the list
(3) eap: Peer sent packet with method EAP MSCHAPv2 (26)
(3) eap: Calling submodule eap_mschapv2 to process data
(3) eap: Sending EAP Success (code 3) ID 3 length 4
(3) eap: Freeing handler
(3)     [eap] = ok
(3)   } # authenticate = ok
(3) # Executing section post-auth from file /etc/raddb/sites-enabled/default
(3)   post-auth {
(3)     update {
(3)       No attributes updated
(3)     } # update = noop
(3)     [exec] = noop
(3)     update reply {
(3)       EXPAND %{Group}
(3)          --> 
(3)       Class = 0x
(3)     } # update reply = noop
(3)     policy remove_reply_message_if_eap {
(3)       if (&reply:EAP-Message && &reply:Reply-Message) {
(3)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(3)       else {
(3)         [noop] = noop
(3)       } # else = noop
(3)     } # policy remove_reply_message_if_eap = noop
(3)   } # post-auth = noop
(3) Sent Access-Accept Id 197 from 10.0.0.247:1812 to 10.0.0.120:49731 length 0
(3)   MS-MPPE-Encryption-Policy = Encryption-Allowed
(3)   MS-MPPE-Encryption-Types = RC4-40or128-bit-Allowed
(3)   MS-MPPE-Send-Key = 0xef26546a7c78d1dcd573403ab44047a3
(3)   MS-MPPE-Recv-Key = 0x0a30fd26c29498159842c0b946e7e724
(3)   EAP-Message = 0x03030004
(3)   Message-Authenticator = 0x00000000000000000000000000000000
(3)   User-Name = "christian.salway"
(3)   Class = 0x
(3) Finished request

Мне удалось ввести в класс «группу», следуя этой статье и используя memberOf в качестве атрибута.

http://lists.freeradius.org/pipermail/freeradius-users/2016-August/084450.html

Вот что я сделал:

1) Добавлен маппинг в мод ldap.

/ и т.д. / Raddb / с поддержкой модов / LDAP

ldap {
...
  update {
     ...
     reply:memberOf                  += 'memberOf'
  }
...
}

2) Добавлена ​​ссылка на атрибут

/ и т.д. / Raddb / словарь

ATTRIBUTE   memberOf                3001    string

3) Добавлен ответ на обновление

/ и т.д. / Raddb / сайты-включены / по умолчанию

post-auth {
...
    foreach &reply:memberOf {
            update reply {
                Class += "%{exec:/etc/raddb/rewrite-dn.sh %{Foreach-Variable-0}}"
            }
    }
...
}

/ и т.д. / Raddb / с поддержкой модов / exec

wait=yes

/etc/raddb/rewrite-dn.sh

#!/bin/bash
echo "${1}" | cut -d',' -f1 | cut -d'=' -f2

Nb. Спасибо @ecdsa за указание на то, что strongSwan читает только первые 43 символа значения класса. См. Комментарий в исходном вопросе.

Журнал тогда выглядит следующим образом

rlm_ldap (ldap): Reserved connection (2)
(3) ldap: EXPAND (samaccountname=%{%{Stripped-User-Name}:-%{User-Name}})
(3) ldap:    --> (samaccountname=christian.salway)
(3) ldap: Performing search in "OU=Users,OU=directory,DC=directory,DC=local" with filter "(samaccountname=christian.salway)", scope "sub"
(3) ldap: Waiting for search result...
(3) ldap: User object found at DN "CN=christian.salway,OU=Users,OU=directory,DC=directory,DC=local"
(3) ldap: Processing user attributes
(3) ldap: reply:memberOf += 'CN=api-user,OU=Special,OU=directory,DC=directory,DC=local'
(3) ldap: reply:memberOf += 'CN=pod2-admin,OU=Groups,OU=directory,DC=directory,DC=local'
(3) ldap: reply:memberOf += 'CN=pod1-admin,OU=Groups,OU=directory,DC=directory,DC=local'
(3) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute
(3) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure)
rlm_ldap (ldap): Released connection (2)
(3)     [ldap] = updated
(3)     [expiration] = noop
(3)     [logintime] = noop
(3)   } # authorize = updated
(3) Found Auth-Type = eap
(3) # Executing group from file /etc/raddb/sites-enabled/default
(3)   authenticate {
(3) eap: Expiring EAP session with state 0x802bdd118228c7fe
(3) eap: Finished EAP session with state 0x802bdd118228c7fe
(3) eap: Previous EAP request found for state 0x802bdd118228c7fe, released from the list
(3) eap: Peer sent packet with method EAP MSCHAPv2 (26)
(3) eap: Calling submodule eap_mschapv2 to process data
(3) eap: Sending EAP Success (code 3) ID 3 length 4
(3) eap: Freeing handler
(3)     [eap] = ok
(3)   } # authenticate = ok
(3) # Executing section post-auth from file /etc/raddb/sites-enabled/default
(3)   post-auth {
(3)     update {
(3)       No attributes updated
(3)     } # update = noop
(3)     [exec] = noop
(3)     foreach &reply:memberOf 
(3)       update reply {
(3)         EXPAND Foreach-Variable-0
(3)            --> CN=api-user,OU=Special,OU=directory,DC=directory,DC=local
(3)         Executing: /etc/raddb/rewrite-dn.sh CN\=api-user,OU\=Special,OU\=directory,DC\=directory,DC\=local:
(3)         Program returned code (0) and output 'api-user'
(3)         EXPAND %{exec:/etc/raddb/rewrite-dn.sh %{Foreach-Variable-0}}
(3)            --> CN\=api-user/OU\=Special/OU\=directory/DC\=directory/DC\=local
(3)         Class += 0x434e5c3d6170692d757365722f4f555c3d5370656369616c2f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3)       } # update reply = noop
(3)       update reply {
(3)         EXPAND Foreach-Variable-0
(3)            --> CN=pod2-admin,OU=Groups,OU=directory,DC=directory,DC=local
(3)         Executing: /etc/raddb/rewrite-dn.sh CN\=pod2-admin,OU\=Groups,OU\=directory,DC\=directory,DC\=local:
(3)         Program returned code (0) and output 'pod2-admin'
(3)         EXPAND %{exec:/etc/raddb/rewrite-dn.sh %{Foreach-Variable-0}}
(3)            --> CN\=pod2-admin/OU\=Groups/OU\=directory/DC\=directory/DC\=local
(3)         Class += 0x434e5c3d706f64322d61646d696e2f4f555c3d47726f7570732f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3)       } # update reply = noop
(3)       update reply {
(3)         EXPAND Foreach-Variable-0
(3)            --> CN=pod1-admin,OU=Groups,OU=directory,DC=directory,DC=local
(3)         Executing: /etc/raddb/rewrite-dn.sh CN\=pod1-admin,OU\=Groups,OU\=directory,DC\=directory,DC\=local:
(3)         Program returned code (0) and output 'pod1-admin'
(3)         EXPAND %{exec:/etc/raddb/rewrite-dn.sh %{Foreach-Variable-0}}
(3)            --> CN\=pod1-admin/OU\=Groups/OU\=directory/DC\=directory/DC\=local
(3)         Class += 0x434e5c3d706f64312d61646d696e2f4f555c3d47726f7570732f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3)       } # update reply = noop
(3)     } # foreach &reply:memberOf = noop
(3)     policy remove_reply_message_if_eap {
(3)       if (&reply:EAP-Message && &reply:Reply-Message) {
(3)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(3)       else {
(3)         [noop] = noop
(3)       } # else = noop
(3)     } # policy remove_reply_message_if_eap = noop
(3)   } # post-auth = noop
(3) Sent Access-Accept Id 236 from 10.0.0.247:1812 to 10.0.0.120:46336 length 0
(3)   MS-MPPE-Encryption-Policy = Encryption-Allowed
(3)   MS-MPPE-Encryption-Types = RC4-40or128-bit-Allowed
(3)   MS-MPPE-Send-Key = 0xf22b62d7972fdc9d4f6d48235831bf81
(3)   MS-MPPE-Recv-Key = 0xccb031384f6eeb26bdb13ed3f034fcbf
(3)   EAP-Message = 0x03030004
(3)   Message-Authenticator = 0x00000000000000000000000000000000
(3)   User-Name = "christian.salway"
(3)   Class += 0x434e5c3d6170692d757365722f4f555c3d5370656369616c2f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3)   Class += 0x434e5c3d706f64322d61646d696e2f4f555c3d47726f7570732f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3)   Class += 0x434e5c3d706f64312d61646d696e2f4f555c3d47726f7570732f4f555c3d6469726563746f72792f44435c3d6469726563746f72792f44435c3d6c6f63616c
(3) Finished request

При использовании unlang в FreeRadius 3 нет необходимости использовать внешний скрипт для извлечения имени группы. Вместо этого можно использовать сравнение регулярных выражений:

/ и т.д. / Raddb / сайты-включены / по умолчанию

post-auth {
  ...
  foreach &reply:memberOf {
    if (Foreach-Variable-0 ~= /CN=([^,=]+)/) {
      update reply { Class += "%{1}" }
    }
  }
  ...
}