Freeradius:将属性从模块启动的虚拟服务器传递到主服务器

Freeradius:将属性从模块启动的虚拟服务器传递到主服务器

我目前被一个问题困扰了很长时间。我们有一个 freeradius 服务器,它既处理来自计算机的 eap_tls 请求,又处理手机的 mab 身份验证。为了实现这一点,我们创建了一个主服务器 (sites-enabled/freerad)。它运行良好,并能正确地对用户进行身份验证,但我们希望详细记录信息,这就是问题的根源。

您会看到,记录访问接受请求很简单,因为只有一种方法可以成功验证用户身份,但拒绝它们的方法却不止一种(我们在同一个请求中使用了证书黑名单、正则表达式匹配、Idap 身份验证等)。我们希望确切地知道用户被拒绝的原因。

我计划的方法是将属性值 (control:Tmp- String-1) 设置为一条消息,具体取决于拒绝用户的原因。此属性值在虚拟服务器 (sites-enabled/check-eap-tls) 中给出,eap 模块将其本身称为 tls 虚拟服务器(我们希望它只处理一次请求)。然后,我们的 linelog 模块应获取此值并使用它来形成日志,从而将失败的确切原因传输到日志中。

logline 模块未在属性中找到任何值。此外,主服务器也未找到任何值。我测试了在主服务器的授权部分中设置属性,并且确实有效,但是我无法根据拒绝的确切原因设置错误消息,因为此原因是在 check-eap-tls 服务器中定义的。避免这种情况的一种方法是将属性从虚拟服务器 check-eap-tls 传递到主服务器。我在网上查找过,找不到任何相关信息,因此请求您的帮助。

这是我的主服务器的配置:

    listen {
                type = "auth"
                ipaddr = 192.168.64.164
                port = 1819
    }

        authorize {

                rewrite_calling_station_id_dot

                if ( &User-Name == "bob") {
                        update control {
                                &Auth-Type := eap
                        }
                }

                else {

                        ldap-phone
                        if (ok) {
                                        update control {
                                                &Tmp-String-0 = "ok"
                                        }
                        }

                        elsif (notfound) {
                                        update control {
                                                &Tmp-String-0 = "notfound"
                                        }
                        }

                        else {
                                        update control {
                                                &Tmp-String-0 = "fail"
                                        }
                        }

                        update control {
                                &Auth-Type := ldap-phone
                        }
                }
        }

        authenticate {

                Auth-Type eap {
                        eap
                }

                Auth-Type ldap-phone {
                        if (&control:Tmp-String-0 == "ok") {
                                update reply {
                                        &cisco-avpair := "device-traffic-class=voice"
                                }
                                accept
                        }
                        elsif (&control:Tmp-String-0 == "notfound") {
                                update control {
                                &Tmp-String-1 := "Invalid User"
                                }
                                reject
                        }
                        else {
                                update control {
                                &Tmp-String-1 := "Error ldap-phone module Failed"
                                }
                                reject
                        }
                }
        }

        post-auth {

                Post-Auth-Type Reject {
                        update reply {
                                &Tunnel-Private-Group-Id := 105
                                &Tunnel-Type := 13
                                &Tunnel-Medium-Type := 6
                        }

                        auth_log
                        linelog_access
                        remove_reply_message_if_eap
                }

                Post-Auth-Type Accept {
                        update control {
                                &Tmp-String-1 := "Login OK"
                        }       
                                
                        auth_log
                        linelog_access
                        remove_reply_message_if_eap
                }

                auth_log
                linelog_access
                remove_reply_message_if_eap
        }
}

这是我的 check-eap-tls 虚拟服务器的配置,由 eap 模块启动为 tls 服务器:

server check-eap-tls {

        authorize {

                #CHECK IF MATCH WITH BLACKLIST

                CN-blacklist
                if (ok) {
                        update control {
                                &Auth-Type := Reject
                                &Tmp-String-1 := "Invalid Certificate"
                        }
                }

                #CHECK IF MATCH WITH REGEXP

                elsif !("%{TLS-Client-Cert-Common-Name}" =~ /^[A-z.]*@example\.org/) {
                        update control {
                                &Auth-Type := Reject
                                &Tmp-String-1 := "Invalid Certificate"
                        }
                }

                #CHECK IF MATCH WITH MAC

                else {
                        ldap-vlan
                        if (updated) {
                                update control {
                                        &Auth-Type := Accept
                                }
                        }
                        elsif (notfound) {
                                update control {
                                        &Auth-Type := Reject
                                        &Tmp-String-1 := "Invalid User"
                                }
                        }
                        else {
                                update control {
                                        &Auth-Type := Reject
                                        &Tmp-String-1 := "Error ldap-vlan module Failed"
                                }
                        }
                }
        }

        post-auth {
                update reply {
                        &Tunnel-Type := 13
                        &Tunnel-Medium-Type := 6
                }
        }
}

以下是测试连接的调试输出。它故意被拒绝(证书已被列入黑名单)。请注意,这只是请求的最后一个数据包,因为它是此情况下唯一重要的数据包:

注意:我无法发布完整的调试日志,无论如何,这表明 linelog 确实正在运行,只是没有获取属性的值并将其默认为“未知”字符串

(7) linelog_access: EXPAND messages.%{%{reply:Packet-Type}:-default}
(7) linelog_access:    --> messages.Access-Reject
(7) linelog_access: EXPAND %t : Auth: (8 CHIFFRES) %{%{control:Tmp-String-1}:-unknown}: [%{%{User-Name}:-unknown}] (from client %{%{control:Client-Shortname}:-unknown} port %{%{NAS-Port}:-unknown} cli %{%{Calling-Station-Id}:-unknown})
(7) linelog_access:    --> Fri Mar 15 10:57:11 2024 : Auth: (8 CHIFFRES) unknown: [bob] (from client test port REDACTED cli REDACTED)
(7) linelog_access: EXPAND /var/log/freeradius/linelog-access
(7) linelog_access:    --> /var/log/freeradius/linelog-access
(7)     [linelog_access] = ok

下面是我用来生成日志的 linelog_access 模块的配置:

linelog linelog_access {
        #
        #  Used if the expansion of "reference" fails.
        #
        delimiter = "\n"

        format = ""

        filename = ${logdir}/linelog-access

        permissions = 0600

        reference = "messages.%{%{reply:Packet-Type}:-default}"

        messages {
                Access-Accept = "%t : Auth: (8 CHIFFRES) %{%{control:Tmp-String-1}:-unknown}:>
                Access-Reject = "%t : Auth: (8 CHIFFRES) %{%{control:Tmp-String-1}:-unknown}:>
                default = "%t : Auth: (8 CHIFFRES) %{%{control:Tmp-String-1}:-unknown}: [%{%{>
                Access-Challenge = "%t - Sent challenge: %{User-Name} ;"
        }

}

最后,这是linelog生成的日志:

Fri Mar 15 10:57:11 2024 : Auth: (8 CHIFFRES) unknown: [bob] (from client test port REDACTED cli REDACTED)

它应该看起来像这样:

Fri Mar 15 10:57:11 2024 : Auth: (8 CHIFFRES) Invalid Certificate: [bob] (from client test port REDACTED cli REDACTED)

另外请注意这是我第一次发这种帖子。对于给您带来的不便,我深表歉意。

答案1

我通过在更改 Tmp-String-1 变量的值后立即在每个单独的服务器中启动 linelog 模块而不是在后认证部分启动该模块来解决了这个问题。

相关内容