Using rlm_caching: rejects on cached requests
Hi, We have a SSL-VPN client that authenticates in two stages. When using authentication with RSA OTP tokens, the second request is considered to be a replay by the RSA server, and denied for that reason. The authentication itself is handled by proxy through a Freeradius server (2.1.12 with experimental modules). What I'd like to acomplish is: - Cache authentication requests - Uncached or expired requests are passed on to the proxy - Cached authentication requests are handled (within the specified TTL) I've set up caching, and I see some of it working. From the debug output, I see this for the first request: ---- Snip ---- +- entering group authorize {...} [preprocess] expand: %{User-Name} -> js [preprocess] hints: Matched DEFAULT at 80 [preprocess] expand: on2it-%{User-Name}@rsa.on2it.net -> on2it-js@rsa.on2it.net ++[preprocess] returns ok [caching] expand: %{User-Name}:%{User-Password}:%{NAS-IP-Address} -> on2it-js@rsa.on2it.net:480378:172.17.202.55 rlm_caching: Searching the database for key 'on2it-js@rsa.on2it.net:480378:172.17.202.55' rlm_caching: Could not find the requested key in the database. rlm_caching: Cache Queries: 4, Cache Hits: 0, Hit Ratio: 0.00% […] [then we see the proxy request being handled, successfully] […] +- entering group post-auth {...} ++[exec] returns noop rlm_caching: Found Auth-Type, value: '' [caching] expand: %{User-Name}:%{User-Password}:%{NAS-IP-Address} -> on2it-js@rsa.on2it.net:480378:172.17.202.55 rlm_caching: VP=Class,VALUE=default_group,length=38,cache record length=39, space left=711 rlm_caching: Storing cache for Key='on2it-js@rsa.on2it.net:480378:172.17.202.55' rlm_caching: New value stored successfully. ++[caching] returns ok Sending Access-Accept of id 69 to 127.0.0.1 port 18782 Class = 0x64656661756c745f67726f757000 ---- pinS ---- This all seems more or less plausible, except for "Found Auth-Type, value: ''" For the second request (fired within a few seconds), I see: ---- Snip ---- Executing section authorize from file /root/etc/raddb/sites-enabled/default +- entering group authorize {...} [preprocess] expand: %{User-Name} -> js [preprocess] hints: Matched DEFAULT at 80 [preprocess] expand: on2it-%{User-Name}@rsa.on2it.net -> on2it-js@rsa.on2it.net ++[preprocess] returns ok [caching] expand: %{User-Name}:%{User-Password}:%{NAS-IP-Address} -> on2it-js@rsa.on2it.net:480378:172.17.202.55 rlm_caching: Searching the database for key 'on2it-js@rsa.on2it.net:480378:172.17.202.55' rlm_caching: Key Found. rlm_caching: VP='Class',VALUE='default_group',lenth='14',cache record length='39' rlm_caching: Adding Auth-Type '' rlm_caching: Cache Queries: 5, Cache Hits: 1, Hit Ratio: 20.00% ++[caching] returns ok Found Auth-Type = Local WARNING: Please update your configuration, and remove 'Auth-Type = Local' WARNING: Use the PAP or CHAP modules instead. No "known good" password was configured for the user. As a result, we cannot authenticate the user. Failed to authenticate the user. Using Post-Auth-Type Reject ---- pinS ---- So I'm getting a Reject for a cached Accept, in effect, and that seems to be due to the Auth-Type. This happens equally for non-proxied requests, i.e. with the following entry in "users": testing Cleartext-Password := "password" User-Name = "%{User-Name}", NAS-IP-Address = "%{NAS-IP-Address}" What am I missing, and what can I do to get cached authentication requests handled? TIA, JS. -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.net | E: Jeroen.Scheerder@on2it.net Premier Business Partner - IBM | Reseller of the Year 2011 - Palo Alto Networks
On 23 Apr 2012(Q2, W17), at 12:09, Jeroen Scheerder wrote:
What I'd like to acomplish is:
- Cache authentication requests - Uncached or expired requests are passed on to the proxy - Cached authentication requests are handled (within the specified TTL)
I've set up caching, and I see some of it working.
With a little more work, I've narrowed my problem down to the caching_postauth function in rlm_caching.c. It reads: "" if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL){ DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue); if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){ DEBUG("rlm_caching: No caching of Rejects. Returning NOOP"); return RLM_MODULE_NOOP; } if (strlen(auth_type->vp_strvalue) > MAX_AUTH_TYPE - 1){ DEBUG("rlm_caching: Auth-Type value too large"); return RLM_MODULE_NOOP; } } "" When ran, this results in: rlm_caching: Found Auth-Type, value: '' … when caching an already accepted authentication request. Subsequent requests are actually found in the cache and handled: rlm_caching: Searching the database for key 'on2it-js@rsa.on2it.net:480378:172.17.202.55' rlm_caching: Key Found. rlm_caching: VP='Class',VALUE='default_group',lenth='14',cache record length='39' rlm_caching: Adding Auth-Type '' rlm_caching: Cache Queries: 5, Cache Hits: 1, Hit Ratio: 20.00% ++[caching] returns ok However, the cached Auth-Type of '' poses a problem: Found Auth-Type = Local WARNING: Please update your configuration, and remove 'Auth-Type = Local' WARNING: Use the PAP or CHAP modules instead. No "known good" password was configured for the user. As a result, we cannot authenticate the user. Failed to authenticate the user. Using Post-Auth-Type Reject I've modified rlm_caching.c thusly: if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL){ DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue); /* JS - set Auth-Type to 'Accept' if unset */ if (strcmp(auth_type->vp_strvalue,"") == 0){ DEBUG("rlm_caching: Auth-Type unset, assigning value: '%s'", "Accept"); strcpy(auth_type->vp_strvalue, "Accept"); } if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){ DEBUG("rlm_caching: No caching of Rejects. Returning NOOP"); return RLM_MODULE_NOOP; } if (strlen(auth_type->vp_strvalue) > MAX_AUTH_TYPE - 1){ DEBUG("rlm_caching: Auth-Type value too large"); return RLM_MODULE_NOOP; } } This has the following effect: rlm_caching: Found Auth-Type, value: '' rlm_caching: Auth-Type unset, assigning value: 'Accept' […] rlm_caching: New value stored successfully. ++[caching] returns ok Sending Access-Accept of id 72 to 127.0.0.1 port 56586 User-Name = "testing" NAS-IP-Address = 172.17.202.55 Finished request 0. Going to the next request Waking up in 4.9 seconds. rad_recv: Access-Request packet from host 127.0.0.1 port 63643, id=178, length=77 User-Name = "testing" User-Password = "password" NAS-IP-Address = 172.17.202.55 NAS-Port = 0 Message-Authenticator = 0x22ec5564c881d6ba20af882fa2369b31 # Executing section authorize from file /root/etc/raddb/sites-enabled/default […] [caching] expand: %{User-Name}:%{User-Password}:%{NAS-IP-Address} -> testing:password:172.17.202.55 rlm_caching: Searching the database for key 'testing:password:172.17.202.55' rlm_caching: Key Found. rlm_caching: VP='User-Name',VALUE='testing',lenth='7',cache record length='22' rlm_caching: VP='NAS-IP-Address',VALUE='172.17.202.55',lenth='4',cache record length='53' rlm_caching: Adding Auth-Type 'Accept' rlm_caching: Cache Queries: 2, Cache Hits: 2, Hit Ratio: 100.00% ++[caching] returns ok Found Auth-Type = Accept Auth-Type = Accept, accepting the user Note that actual rejects don't seem to make the caching_postauth function, for whatever reason. This seems to be working. No doubt somebody'll step in and tell me how utterly wrong this is. :-) Still, I'm content so far. But I have one more thing to take care of: I'd like to enable caching only for specific clients. How could I acomplish that? Regards, Jeroen. -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.net | E: Jeroen.Scheerder@on2it.net Premier Business Partner - IBM | Reseller of the Year 2011 - Palo Alto Networks
Jeroen Scheerder wrote:
I've modified rlm_caching.c thusly:
if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL){ DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue); /* JS - set Auth-Type to 'Accept' if unset */ if (strcmp(auth_type->vp_strvalue,"") == 0){
Except that Auth-Type is an "integer" attribute. So why look at the string when you can look at the integer value? i.e. *What* is the integer value when the string is empty?
DEBUG("rlm_caching: Auth-Type unset, assigning value: '%s'", "Accept"); strcpy(auth_type->vp_strvalue, "Accept"); } if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){
See src/main/auth.c. You shouldn't do strcmp().
Note that actual rejects don't seem to make the caching_postauth function, for whatever reason.
Because you didn't list "caching" in the "Post-Auth-Type Reject" section.
This seems to be working. No doubt somebody'll step in and tell me how utterly wrong this is. :-)
I'd like to understand *why* the value is wrong. If it's cached, it should cache the working value.
Still, I'm content so far. But I have one more thing to take care of: I'd like to enable caching only for specific clients. How could I acomplish that?
"man unlang". Write conditional checks around the caching module. Alan DeKok.
On 26 Apr 2012(Q2, W17), at 10:01, Alan DeKok wrote:
Jeroen Scheerder wrote:
I've modified rlm_caching.c thusly:
if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL){ DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue); /* JS - set Auth-Type to 'Accept' if unset */ if (strcmp(auth_type->vp_strvalue,"") == 0){
Except that Auth-Type is an "integer" attribute. So why look at the string when you can look at the integer value?
That's a valid question. I've followed the way it was done in rlm_caching.c. Actually, that's found in src/main/auth.c as well: auth_type = pairfind(request->config_items, PW_AUTH_TYPE); if (auth_type && (auth_type->vp_strvalue[0] != '\0')) {
i.e. *What* is the integer value when the string is empty?
I'm printing auth_type->vp_integer as well. The result: rlm_caching: Found Auth-Type, int value: 1024, string value: ''
DEBUG("rlm_caching: Auth-Type unset, assigning value: '%s'", "Accept"); strcpy(auth_type->vp_strvalue, "Accept"); } if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){
See src/main/auth.c. You shouldn't do strcmp().
Well, that's just rlm_caching.c as is. I'm sure it can be improved.
Note that actual rejects don't seem to make the caching_postauth function, for whatever reason.
Because you didn't list "caching" in the "Post-Auth-Type Reject" section.
Added it. Interestingly, rejected requests then enter rlm_caching as follows: rlm_caching: Found Auth-Type, int value: 1024, string value: '' rlm_caching: Auth-Type unset, assigning value: 'Accept' rlm_caching: The Request does not contain any reply attributes
This seems to be working. No doubt somebody'll step in and tell me how utterly wrong this is. :-)
I'd like to understand *why* the value is wrong. If it's cached, it should cache the working value.
I agree. Yet I always seem to get a vp_integer of 1024 and a vp_str of '', regardless of accepted or rejected auths.
Still, I'm content so far. But I have one more thing to take care of: I'd like to enable caching only for specific clients. How could I acomplish that?
"man unlang". Write conditional checks around the caching module.
That'll do wonders. Thanks. Regards, Jeroen -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.net | E: Jeroen.Scheerder@on2it.net Premier Business Partner - IBM | Reseller of the Year 2011 - Palo Alto Networks
Jeroen Scheerder wrote:
On 26 Apr 2012(Q2, W17), at 10:01, Alan DeKok wrote: That's a valid question. I've followed the way it was done in rlm_caching.c.
That should be fixed, then.
Actually, that's found in src/main/auth.c as well:
auth_type = pairfind(request->config_items, PW_AUTH_TYPE); if (auth_type && (auth_type->vp_strvalue[0] != '\0')) {
I can't find that code in the current source. Which version are you using?
i.e. *What* is the integer value when the string is empty?
I'm printing auth_type->vp_integer as well. The result:
rlm_caching: Found Auth-Type, int value: 1024, string value: ''
Weird.
Added it. Interestingly, rejected requests then enter rlm_caching as follows:
Probably because it's not intended to cache rejects.
I agree. Yet I always seem to get a vp_integer of 1024 and a vp_str of '', regardless of accepted or rejected auths.
Well, current versions of the server don't add that value or string. So if it's there, it's because of something in your local configuration. Alan DeKok.
On 26 Apr 2012(Q2, W17), at 11:06, Alan DeKok wrote:
Jeroen Scheerder wrote:
On 26 Apr 2012(Q2, W17), at 10:01, Alan DeKok wrote: That's a valid question. I've followed the way it was done in rlm_caching.c.
That should be fixed, then.
Actually, that's found in src/main/auth.c as well:
auth_type = pairfind(request->config_items, PW_AUTH_TYPE); if (auth_type && (auth_type->vp_strvalue[0] != '\0')) {
I can't find that code in the current source. Which version are you using?
freeradius-server-2.1.12.
i.e. *What* is the integer value when the string is empty?
I'm printing auth_type->vp_integer as well. The result:
rlm_caching: Found Auth-Type, int value: 1024, string value: ''
Weird.
Added it. Interestingly, rejected requests then enter rlm_caching as follows:
Probably because it's not intended to cache rejects.
I agree. Yet I always seem to get a vp_integer of 1024 and a vp_str of '', regardless of accepted or rejected auths.
Well, current versions of the server don't add that value or string. So if it's there, it's because of something in your local configuration.
Sure. But it's just the most recent tarball extracted, with only the 'testing' user (with cleartype password) added, and caching enabled. Regards, Jeroen. -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.net | E: Jeroen.Scheerder@on2it.net Premier Business Partner - IBM | Reseller of the Year 2011 - Palo Alto Networks
Jeroen Scheerder wrote:
freeradius-server-2.1.12.
OK. Well... that's been fixed.
Sure. But it's just the most recent tarball extracted, with only the 'testing' user (with cleartype password) added, and caching enabled.
Weird. I think it's been fixed in the git v2.1.x branch. Alan DeKok.
On 26 apr. 2012, at 11:58, Alan DeKok wrote:
freeradius-server-2.1.12.
OK. Well... that's been fixed.
Sure. But it's just the most recent tarball extracted, with only the 'testing' user (with cleartype password) added, and caching enabled.
Weird. I think it's been fixed in the git v2.1.x branch.
I'll replicate from the stable branch in git and report. In case of further issues, perhaps I should take things to the dev list? Regards, Jeroen. -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.nl | E: jeroenscheerder@on2it.net
On 26 Apr 2012(Q2, W17), at 16:36, Jeroen Scheerder wrote:
I'll replicate from the stable branch in git and report.
Sadly, working from the main git branch I get immediate segmentation faults (with the stock raddb, and no changes to the source). I enabled core dumps, and gdb tells me: (gdb) bt #0 0x0000000800fbb376 in strcmp () from /lib/libc.so.7 #1 0x00000008006a840a in rbtree_find (tree=0x80121a2b0, Data=0x7fffffffb740) at rbtree.c:479 #2 0x00000008006a8449 in rbtree_finddata (tree=Variable "tree" is not available. ) at rbtree.c:498 #3 0x000000000040fad7 in cf_pair_find (cs=0x8012281c0, name=0x14 <Address 0x14 out of bounds>) at conffile.c:1964 #4 0x00000000004109e2 in cf_item_parse (cs=0x8012281c0, name=0x14 <Address 0x14 out of bounds>, type=5405185, data=0x1c00000014, dflt=0x4dffeff5c0 <Address 0x4dffeff5c0 out of bounds>) at conffile.c:912 #5 0x0000000000410f44 in cf_section_parse (cs=0x8012281c0, base=0x8012136e0, variables=0x802338b90) at conffile.c:1210 #6 0x0000000802238754 in eaptls_attach (cs=0x8012281c0, instance=0x8012160f0) at rlm_eap_tls.c:76 #7 0x0000000801e2bbb7 in eaptype_load (type=0x8013bf588, eap_type=Variable "eap_type" is not available. ) at eap.c:142 #8 0x0000000801e2a2e7 in eap_instantiate (cs=0x801227ec0, instance=0x801236fc8) at rlm_eap.c:197 #9 0x000000000041ed70 in find_module_instance (modules=Variable "modules" is not available. ) at modules.c:661 #10 0x0000000000420171 in do_compile_modsingle (parent=0x0, component=0, ci=0x80121f1f0, grouptype=0, modname=0x7fffffffe008) at modcall.c:2090 #11 0x000000000041dcf0 in load_component_section (cs=0x8012437c0, components=0x801214b20, comp=0) at modules.c:952 #12 0x000000000041e1ad in load_byserver (cs=0x80120c0c0) at modules.c:1171 #13 0x000000000041e6f2 in virtual_servers_load (config=0x80120c0c0) at modules.c:1306 #14 0x000000000041f26f in setup_modules (reload=Variable "reload" is not available. ) at modules.c:1630 #15 0x000000000041d026 in read_mainconfig (reload=Variable "reload" is not available. ) at mainconfig.c:983 #16 0x0000000000422388 in main (argc=2, argv=Variable "argv" is not available. ) at radiusd.c:264 Regards, Jeroen. -- Jeroen Scheerder ON2IT B.V. Steenweg 17 B 4181 AJ WAARDENBURG T: +31 418-653818 | F: +31 418-653716 W: www.on2it.net | E: Jeroen.Scheerder@on2it.net Premier Business Partner - IBM | Reseller of the Year 2011 - Palo Alto Networks
participants (3)
-
Alan DeKok -
Jeroen Scheerder -
Jeroen Scheerder