Issues with Cached-Session-Policy in versions of FR after 3.0.8.
Hello, I've issues with fast-reauth using Cached-Session-Policy in FR3.0.9 and above. In the post-auth section of site-enabled/inner-tunnel I update the reply as below... post-auth { ... update reply { &Cached-Session-Policy = &Stripped-User-Name } ... } I then have the code below in site-enabled/default to recover the username from the stored Cached-Session-Policy for use on a fast-reauth, this is then used to run a few scripts to check the user's status and assign VLAN. post-auth { ... if ("%{Realm}" != "jrs") { #don't need to do this for JRS users update control { &Tmp-String-1 := &reply:Cached-Session-Policy } $INCLUDE ${raddbdir}/scripts/dosomestuff.conf $INCLUDE ${raddbdir}/scripts/poolacc.conf } ... } This works in V3.0.8, Tmp-String-1 is set to the stripped username from the saved session, but not in versions after this. Is there a better/another way to recover the username for use within site-enabled/default during fast re-auth / session resumption? Many thanks, Jezz. Jezz Palmer Information Services and Systems Swansea University Singleton Park Swansea SA2 8PP
J.D.F. [j.d.f.palmer@swansea.ac.uk] wrote:
This works in V3.0.8, Tmp-String-1 is set to the stripped username from the saved session, but not in versions after this.
Is there a better/another way to recover the username for use within site-enabled/default during fast re-auth / session resumption?
There's a new generic session state cache mechanism that interacts in fun ways with the TLS session state caching. Our setup is a bit more complicated probably than yours, and I can't share the whole thing without a massive edit, but hopefully these are enough clues to give you something to work with: authorize { preprocess # eap will set Auth-Type update { # These are all the attributes SSL session resumption supports. # That might eventually move to use the generic state mechanism # but for now they have to be moved to the request to be cached # via TLS session ID, and we have to do this before the we hit # eap in the next authorize section, which does not go into the # inner server on the last packet. # # 1) &reply:User-Name stashed after mschap &reply:User-Name := &session-state:User-Name # 2) &request:Stripped-User-Name &request:Stripped-User-Name := &session-state:Stripped-User-Name # 3) &request:Stripped-User-Domain we do not use # &request:Stripped-User-Domain := &session-state:Stripped-User-Domain # 4) &reply:Chargeable-User-Identity we do not use on this SSID # &reply:Chargeable-User-Identity := &session-state:Chargeable-User-Identity # 5) &reply:Cached-Session-Policy also stashed earlier; we put stuff # for other attributes in here. &reply:Cached-Session-Policy := &session-state:Cached-Session-Policy } ... post-auth { Post-Auth-Type WIFI-OUTER { if (&reply:Cached-Session-Policy =~ /POLICY=([^;]+);UNAME=([^;]*);/) { # This section gets entered for new connects, not just TLS fast-reauths. # (We just pre-load this variable and then treat them all the same.) # # We need to pull two things from the TLS session cache because # the NAS has no way to get them without a full authentication. # # 1) What VLAN or policy to send the user to # 2) The username we originally sent when we accepted them # 3) The original AD username # # #3 is pulled out automatically for us, and we want to log it. # #2 should not be logged because it has dorm addresses in it, # but it is the one we want to send it back as the User-Name # so it matches what the NAC and NAS have on file. update { &reply:Tunnel-Private-Group-Id !* ANY &reply:Tunnel-Private-Group-Id := "%{1}" &control:User-Name := "%{2}" } do_track_log update reply { &User-Name !* ANY &User-Name := &control:User-Name } else { # This should actually not ever happen ... Post-Auth-Type Challenge { # In the case of a fast reauthentication, the TLS cached # attributes are in the reply, but not saved in the general # purpose session-state cache yet, because we never ran the # inner tunnel. Fix that up by saving those attributes here # when we detect this situation. if (!session-state:Stripped-User-Name) { update { &session-state: += &reply: &session-state:Stripped-User-Name += &request:Stripped-User-Name } update session-state { &MS-MPPE-Encryption-Policy !* ANY &MS-MPPE-Encryption-Types !* ANY &MS-MPPE-Send-Key !* ANY &MS-MPPE-Recv-Key !* ANY &Message-Authenticator !* ANY &EAP-Message !* ANY &Proxy-State !* ANY &State !* ANY } } # And this deletes practically everything from the reply # since we don't want to send any actual attributes until # we are sending an Accept. access_challenge_filter } server inner { Autz-Type WIFI-INNER { update control { &Post-Auth-Type := WIFI-INNER } # eap will set Auth-Type before LDAP does, first-come-first-serve. eap { # We can skip the user access check on the first packet by # returning immediately when EAP returns "ok". The other # two times it will return "updated". This will skip all of # this rest of the "authorize" section. ok = return } # This has to be in the authorize section, it behaves differently # here and wil check if the user is flagged as WiFi eligible in # LDAP as configured in the module settings. However, it will # get run needlessly on the second packet. So, we cram an arbitrary # attribute into the state. We cannot use the inner tunnel State # entry, because that will only get written to cache in post-auth, # which we are going to skip, so we put it in the outer session state, # which will be writen in server "backend"'s post-proxy section # because this will be an Access-Challenge and that's a special case. # # (Yes you have to read the code to know this stuff.) # # The first packet never gets here, the second packet we have not # put anything in the state yet, so it is empty, and after that # (which should only be once) we check LDAP for permission to use WiFi. if (&outer.session-state:XXX-LDAPType) { ldap_ds_wifi } update { &outer.session-state:XXX-LDAPType := "pleasedoldapnexttime" } ... post-auth { update reply { &Cached-Session-Policy := "POLICY=%{reply:Tunnel-Private-Group-Id};UNAME=XXX; } # Copy all the reply attributes from inner to outer, plus one # of the TLS fast reconnect items that come from the request # rather than the reply. update { &outer.session-state: += &reply: &outer.session-state:Stripped-User-Name += &request:Stripped-User-Name } # Clean the state of some important variables that internal code # is about to write to. We don't want to have stacks of these. update outer.session-state { &MS-MPPE-Encryption-Policy !* ANY &MS-MPPE-Encryption-Types !* ANY &MS-MPPE-Send-Key !* ANY &MS-MPPE-Recv-Key !* ANY &Message-Authenticator !* ANY &EAP-Message !* ANY &Proxy-State !* ANY &State !* ANY } } - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
In v3.1.x: modules { cache cache_tls_session { driver = 'rlm_cache_redis' # Alc-Subsc-ID-Str is unique to each class/type of device on a circuit # NAS-Port-ID is used as the default by the DR if one is not provided # in the Access-Accept key = "cert:tls_session:%{hex:&TLS-Session-ID}" ttl = 86400 # 24 hrs # When creating or updating the flow is right to left. # When reading/merging the flow is left to right. # The cache entry # The current request update { &session-state: += &session-state:[*] } } } server tls-cache { # # Only the "authorize" section is needed. # Only the listed Autz-Types are used. # Everything else in the virtual server is ignored. # # The attribute &request:TLS-Session-Identity is set to the identity # of the session to read / write / delete from the cache. This # identity is an opaque blob. # authorize { Autz-Type Session-Cache-Read { update control { Cache-Allow-Insert := no } cache_tls_session } Autz-Type Session-Cache-Write { update control { Cache-TTL := 0 } cache_tls_session } Autz-Type Session-Cache-Delete { update control { Cache-TTL := 0 Cache-Allow-Insert := no } cache_tls_session } } } eap { tls-common { cache { enable = yes virtual_server = 'tls-cache' } } } Put stuff in session-state and it's automatically restored if the session is resumed... because you're resuming the session, right? and session-state is the state of the session... The main requirement with this method is that everything you want to store in session-state, is in there by the time the TLS session is ready to be frozen, so you likely want to run your policies in the post-auth section of the inner tunnel. -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
participants (3)
-
Arran Cudbard-Bell -
Brian Julin -
Palmer J.D.F.