Freeradius:如何将模块调用的虚拟服务器中的属性传递至主服务器
Hey there! Let's work through this issue you're having with passing attributes from your check-eap-tls virtual server back to the main FreeRADIUS server. I get why this is frustrating—virtual servers can feel like black boxes sometimes when it comes to sharing data, but there's a straightforward fix here.
The Root of the Problem
When the EAP module calls your check-eap-tls virtual server, it runs in a sub-request context. Any attributes you set under the control: namespace (like control:Tmp-String-1) are only local to that sub-request—they don’t automatically carry over to the main request’s context. That’s exactly why your main server and linelog module can’t see the error message you set.
The Fix: Move Attributes to the Request Namespace
To get the attribute back to the main server, you need to store your error message in the request: namespace instead of control:. Attributes in the request: namespace are shared between the sub-request and the main request. Here’s how to adjust your configs step by step:
1. Update the check-eap-tls Virtual Server
In every section where you set the error message, replace the control: namespace update with request:. For example:
authorize { # CHECK IF MATCH WITH BLACKLIST CN-blacklist if (ok) { update request { &Tmp-String-1 := "Invalid Certificate" } update control { &Auth-Type := Reject } } # CHECK IF MATCH WITH REGEXP elsif !("%{TLS-Client-Cert-Common-Name}" =~ /^[A-z.]*@example\.org/) { update request { &Tmp-String-1 := "Invalid Certificate" } update control { &Auth-Type := Reject } } # CHECK IF MATCH WITH MAC else { ldap-vlan if (updated) { update control { &Auth-Type := Accept } } elsif (notfound) { update request { &Tmp-String-1 := "Invalid User" } update control { &Auth-Type := Reject } } else { update request { &Tmp-String-1 := "Error ldap-vlan module Failed" } update control { &Auth-Type := Reject } } } } post-auth { update reply { &Tunnel-Type := 13 &Tunnel-Medium-Type := 6 } } }
2. Sync the Attribute to Control Namespace (Optional but Recommended)
If your linelog module is already configured to look for control:Tmp-String-1, add a small snippet in your main server’s post-auth section to copy the value from request: to control::
# Copy error message from request to control namespace for linelog if (&request:Tmp-String-1) { update control { &Tmp-String-1 := "%{request:Tmp-String-1}" } } 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 }
3. Verify with Debug Logs
To confirm this works, run FreeRADIUS in debug mode with raddebug -x and watch the request flow. You should see Tmp-String-1 appear in the main request’s attribute list after the check-eap-tls virtual server runs. Your linelog should now log the correct error message instead of "unknown".
Quick Troubleshooting Tips
If you still don’t see the attribute in logs:
- Check that
check-eap-tlsis actually being called (your debug logs should show entries from this server during EAP-TLS requests). - Ensure you’re not accidentally overriding
Tmp-String-1in the main server’s authorize/post-auth sections. - Double-check that the attribute names are spelled correctly (case matters in FreeRADIUS!).
That should resolve the issue. Virtual servers are powerful, but remembering their context separation is key to making them play nice with the main server. Let me know if you hit any snags along the way!
备注:内容来源于stack exchange,提问作者TNM

