freeradius-proxy with Rlm_cache
Hi, We would like to configure a freeradius proxy-server v. 2.2.0 under RHEL6 with users caching. The scenario we would like to achieve is the following: 1. client sends username/OTP to freeradius-proxy that relays to central radius server. Central radius server accepts and replies to freeradius-proxy that relays to client. 2. client sends same username/OTP within TTL to freeradius-proxy that accepts and replies to client. This should be possible using Rlm_cache module but we did not find a proper how-to for configuring this. Any help much appreciated. Dominique
On 20/02/13 08:38, Dominique Frise wrote:
Hi,
We would like to configure a freeradius proxy-server v. 2.2.0 under RHEL6 with users caching.
The scenario we would like to achieve is the following:
1. client sends username/OTP to freeradius-proxy that relays to central radius server. Central radius server accepts and replies to freeradius-proxy that relays to client.
2. client sends same username/OTP within TTL to freeradius-proxy that accepts and replies to client.
This should be possible using Rlm_cache module but we did not find a proper how-to for configuring this.
Can you show a debug ("radiusd -X") of an auth request? This will make it more obvious what attributes you need to have as key/value. Also, this will probably only work if your OTP is simple PAP-like i.e. request/accept. It probably won't work if Access-Challenge or any challenge/response is involved. But, for example, if your request looked like this: User-Name = foo User-Password = bar OTP-Password = 123456 ...then you'd want an rlm_cache config like this: cache otpcache { # note - we need to escape the key values # otherwise the client can perform injection/overlap # attacks by modifying their username key = "%{urlquote:%{User-Name}}/%{urlquote:%{User-Password}}/%{urlquote:%{OTP-Password}}" ttl = 60 } ...and then: authorize { # first, just check the cache, don't # create entries or set reply attrs update control { Cache-Status-Only = yes } otpcache # future cache lookups here, and in post-auth, # should be normal ones update control { Cache-Status-Only !* ANY } if (ok) { # entry found in cache; set auth type to accept # and call cache again to get reply attrs update control { Auth-Type := Accept } otpcache ok } ... } post-auth { # first, delete any existing cache entries update control { Cache-TTL = 0 } otpcache # clear that variable update control { Cache-TTL !* ANY } # now cache the reply otpcache } It's a bit awkward TBH; I kind of wish modules could have "named methods" e.g. "cache.{check,get,set,expire}" but you can wrap it all in a policy.conf if you want readability.
On 20/02/13 12:47, Phil Mayers wrote:
...and then:
authorize {
Damn, sorry this is not right. The 2nd "update" will squash the return values. You'll need: authorize { # first, just check the cache, don't # create entries or set reply attrs update control { Cache-Status-Only = yes } otpcache if (ok) { # entry found in cache; set auth type to accept # and call cache again to get reply attrs update control { Auth-Type := Accept Cache-Status-Only !* ANY } otpcache ok } else { # future cache lookups here, and in post-auth, # should be normal ones update control { Cache-Status-Only !* ANY } } ... }
Hi Phil, Here below a debug output : ================== rad_recv: Access-Request packet from host 127.0.0.1 port 11148, id=74, length=94 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 10123 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" # Executing section authorize from file /etc/raddb/sites-enabled/default +- entering group authorize {...} ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop ++[digest] returns noop [suffix] No '@' in User-Name = "dfrise", looking up realm NULL [suffix] Found realm "NULL" [suffix] Adding Stripped-User-Name = "dfrise" [suffix] Adding Realm = "NULL" [suffix] Proxying request from user dfrise to realm NULL [suffix] Preparing to proxy authentication request to realm "NULL" ++[suffix] returns updated [eap] No EAP-Message, not doing EAP ++[eap] returns noop ++[files] returns noop ++[expiration] returns noop ++[logintime] returns noop ++[pap] returns noop # Executing section pre-proxy from file /etc/raddb/sites-enabled/default +- entering group pre-proxy {...} [cache] expand: %{User-Name} -> dfrise [cache] expand: I'm the cached reply from %t -> I'm the cached reply from Wed Feb 20 08:28:43 2013 [cache] expand: 0x010203 -> 0x010203 rlm_cache: Adding entry for "dfrise", with TTL of 10 ++[cache] returns updated Sending Access-Request of id 24 to 13.22.27.198 port 1812 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 10123 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" Proxy-State = 0x3734 Proxying request 0 to home server 13.22.27.198 port 1812 Sending Access-Request of id 24 to 13.22.27.198 port 1812 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 10123 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" Proxy-State = 0x3734 Going to the next request Waking up in 0.9 seconds. rad_recv: Access-Accept packet from host 13.22.27.198 port 1812, id=24, length=30 Idle-Timeout = 1800 Proxy-State = 0x3734 # Executing section post-proxy from file /etc/raddb/sites-enabled/default +- entering group post-proxy {...} [eap] No pre-existing handler found ++[eap] returns noop [cache] expand: %{User-Name} -> dfrise rlm_cache: Found entry for "dfrise" ++[cache] returns ok Found Auth-Type = Accept Auth-Type = Accept, accepting the user # Executing section post-auth from file /etc/raddb/sites-enabled/default +- entering group post-auth {...} ++[exec] returns noop [cache] expand: %{User-Name} -> dfrise rlm_cache: Found entry for "dfrise" ++[cache] returns ok Sending Access-Accept of id 74 to 127.0.0.1 port 11148 Reply-Message += "I'm the cached reply from Wed Feb 20 08:28:43 2013" Idle-Timeout = 1800 Reply-Message += "I'm the cached reply from Wed Feb 20 08:28:43 2013" 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 22765, id=125, length=94 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 21740 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" # Executing section authorize from file /etc/raddb/sites-enabled/default +- entering group authorize {...} ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop ++[digest] returns noop [suffix] No '@' in User-Name = "dfrise", looking up realm NULL [suffix] Found realm "NULL" [suffix] Adding Stripped-User-Name = "dfrise" [suffix] Adding Realm = "NULL" [suffix] Proxying request from user dfrise to realm NULL [suffix] Preparing to proxy authentication request to realm "NULL" ++[suffix] returns updated [eap] No EAP-Message, not doing EAP ++[eap] returns noop ++[files] returns noop ++[expiration] returns noop ++[logintime] returns noop ++[pap] returns noop # Executing section pre-proxy from file /etc/raddb/sites-enabled/default +- entering group pre-proxy {...} [cache] expand: %{User-Name} -> dfrise rlm_cache: Found entry for "dfrise" ++[cache] returns ok Sending Access-Request of id 105 to 13.22.27.198 port 1812 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 21740 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" Proxy-State = 0x313235 Proxying request 1 to home server 13.22.27.198 port 1812 Sending Access-Request of id 105 to 13.22.27.198 port 1812 User-Name = "dfrise" User-Password = "xxxx276988" NAS-IP-Address = 13.22.27.94 NAS-Identifier = "sshd" NAS-Port = 21740 NAS-Port-Type = Virtual Service-Type = Authenticate-Only Calling-Station-Id = "ci-1-6.unil.ch" Proxy-State = 0x313235 Going to the next request Waking up in 0.9 seconds. Waking up in 3.0 seconds. rad_recv: Access-Reject packet from host 13.22.27.198 port 1812, id=105, length=25 Proxy-State = 0x313235 # Executing section post-proxy from file /etc/raddb/sites-enabled/default +- entering group post-proxy {...} [eap] No pre-existing handler found ++[eap] returns noop [cache] expand: %{User-Name} -> dfrise rlm_cache: Found entry for "dfrise" ++[cache] returns ok Using Post-Auth-Type REJECT # Executing group from file /etc/raddb/sites-enabled/default +- entering group REJECT {...} [attr_filter.access_reject] expand: %{User-Name} -> dfrise attr_filter: Matched entry DEFAULT at line 11 ++[attr_filter.access_reject] returns updated Sending Access-Reject of id 125 to 127.0.0.1 port 22765 Reply-Message += "I'm the cached reply from Wed Feb 20 08:28:43 2013" Finished request 1. Going to the next request Waking up in 3.0 seconds. Cleaning up request 0 ID 74 with timestamp +45 Waking up in 1.9 seconds. Cleaning up request 1 ID 125 with timestamp +46 Ready to process requests. ================= Dominique On 02/20/13 01:47 PM, Phil Mayers wrote:
On 20/02/13 08:38, Dominique Frise wrote:
Hi,
We would like to configure a freeradius proxy-server v. 2.2.0 under RHEL6 with users caching.
The scenario we would like to achieve is the following:
1. client sends username/OTP to freeradius-proxy that relays to central radius server. Central radius server accepts and replies to freeradius-proxy that relays to client.
2. client sends same username/OTP within TTL to freeradius-proxy that accepts and replies to client.
This should be possible using Rlm_cache module but we did not find a proper how-to for configuring this.
Can you show a debug ("radiusd -X") of an auth request? This will make it more obvious what attributes you need to have as key/value.
Also, this will probably only work if your OTP is simple PAP-like i.e. request/accept. It probably won't work if Access-Challenge or any challenge/response is involved.
But, for example, if your request looked like this:
User-Name = foo User-Password = bar OTP-Password = 123456
...then you'd want an rlm_cache config like this:
cache otpcache { # note - we need to escape the key values # otherwise the client can perform injection/overlap # attacks by modifying their username key = "%{urlquote:%{User-Name}}/%{urlquote:%{User-Password}}/%{urlquote:%{OTP-Password}}"
ttl = 60 }
...and then:
authorize { # first, just check the cache, don't # create entries or set reply attrs update control { Cache-Status-Only = yes } otpcache
# future cache lookups here, and in post-auth, # should be normal ones update control { Cache-Status-Only !* ANY }
if (ok) { # entry found in cache; set auth type to accept # and call cache again to get reply attrs update control { Auth-Type := Accept } otpcache ok }
... } post-auth { # first, delete any existing cache entries update control { Cache-TTL = 0 } otpcache
# clear that variable update control { Cache-TTL !* ANY }
# now cache the reply otpcache }
It's a bit awkward TBH; I kind of wish modules could have "named methods" e.g. "cache.{check,get,set,expire}" but you can wrap it all in a policy.conf if you want readability. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On 20/02/13 13:31, Dominique Frise wrote:
Hi Phil,
Here below a debug output :
================== rad_recv: Access-Request packet from host 127.0.0.1 port 11148, id=74, length=94 User-Name = "dfrise" User-Password = "xxxx276988"
Ok, so the PIN is appended to the password. In which case your "key" is just "User-Name" and "User-Password". Anyway - the recipe in my other email should cover what you need. What you're doing now - single calls to "cache" - probably won't cover it. You will need more logic, as per my example.
Hi Phil, I have now a working config. "authorize" section : ... # auth_log # Caching module will allow to log twice with the same OTP. # Cached entry will be removed after second login or at # the end of TTL (value set in modules/cache) cache if (ok) { # entry found in cache; set Auth-Type to Accept. # force TTL to 0 for removing this entry update control { Auth-Type := Accept Cache-TTL = 0 } cache # remove entry noop = return } ... Thanks for your help. Dominique On 02/20/13 03:05 PM, Phil Mayers wrote:
On 20/02/13 13:31, Dominique Frise wrote:
Hi Phil,
Here below a debug output :
================== rad_recv: Access-Request packet from host 127.0.0.1 port 11148, id=74, length=94 User-Name = "dfrise" User-Password = "xxxx276988"
Ok, so the PIN is appended to the password. In which case your "key" is just "User-Name" and "User-Password".
Anyway - the recipe in my other email should cover what you need. What you're doing now - single calls to "cache" - probably won't cover it. You will need more logic, as per my example. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
participants (2)
-
Dominique Frise -
Phil Mayers