i'm currently stuck on an issue for quite some time now. We have a freeradius server that handles both eap_tls requests from computers and mab authentication for phones. To achieve that, we have created a main server (sites-enabled/freerad). It works fine and manages to authenticate users correctly but we want to log informations in detail and that's where the issues start.
You see, logging access-accept requests is simple as there is only one way of authenticating successfully a user, however there is more than one way of rejecting them (we have certificates blacklists, regexp matches, Idap authentications and whatnots used in the same request). We would like to know exactly the reason for a user to be rejected.
The way i planned to do it was to set an attribute's value (control:Tmp- String-1) to a message depending on what rejected the user. This attribute's value is given in a virtual server (sites-enabled/check-eap-tls), itself called by the eap module as the tls virtual server (we want it to treat the request only once). Then, our linelog module should take this value and use it to form the log, thus transmitting the exact reason of failure to logs.
The logline module doesn't find any value in the attribute. Furthermore, the main server doesn't find any either. I tested setting the attribute in the authorize section of the main server and it did work, however i cannot set error messages based on the exact reason of rejection as this reason is defined in the check-eap-tls server. One way to circumvent this would be to pass the attribute from the virtual server check-eap-tls to the main server. I've looked online and couldn't find anything relevant and am thus asking for your help.
Here is the configuration of my main server:
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
}
}
Here is the configuration of my check-eap-tls virtual server launched as tls server by the eap module:
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
}
}
}
And here is the debug output of a test connection. It is purposefully a rejected one (the certificate has been blacklisted). Please note that this is only the last packet of the request as it is the only important one in this situation:
note: i can't post the full debug logs, either way this shows that linelog is indeed running and just doesn't get the value of the attribute and defaults it to the "unknown" string
(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
Here is the configuration of my linelog_access module used to produce the log:
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} ;"
}
}
Finally, here is the log produced by linelog:
Fri Mar 15 10:57:11 2024 : Auth: (8 CHIFFRES) unknown: [bob] (from client test port REDACTED cli REDACTED)
Which should instead look like this:
Fri Mar 15 10:57:11 2024 : Auth: (8 CHIFFRES) Invalid Certificate: [bob] (from client test port REDACTED cli REDACTED)
Also please note this is my first time doing this kind of post. I apologize for the inconveniance i may have given you.
I fixed the issue by launching the linelog module in each individual server right after changing the Tmp-String-1 variable's value instead of launching the module in the post-auth part.