Hi All,
I am testing a scenario where we have 3 proxies and I'm trying to ensure that if a messages comes in to 1 proxy, which challenges the ua, is able to be auth'd successfully on one of the remaining 2 proxies if, for some reason the ua decides to send the response to one of the remaining two proxies.
I am testing this using a seperate kamailio proxy which loadbalances messages across the 3 proxies that I am testing with. I have 1 ua (zoiper) which I tell to subscribe for mwi, the initial subscribe is sent to proxy 1, which sends a 407 back, the new subscribe with auth, from the ua, is sent to proxy 2, which deems the nonce as expired and rechallenges, this continues in a loop across the 3 proxies and never authenticates.
I think I'm missing something in my settings that I just cannot put my finger on, and/or, I'm mis-understanding the documentation and how these settings interact with each other.
My auth module settings are as follows:
# # ----- auth params ----- # modparam("auth", "qop", "auth") modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1) modparam("auth", "nid_pool_no", 4) modparam("auth", "nc_array_size", 4194304) modparam("auth", "otn_in_flight_no", 8388608) modparam("auth", "auth_checks_no_dlg", 9) modparam("auth", "auth_checks_in_dlg", 15) modparam("auth", "auth_checks_register", 11) modparam("auth", "secret", "secret_32_char_str")
I tried with one_time_nonce enabled and disabled but the result is the same, continous rechallenge.
The documentation mentions that if nonce_count and one_time_nonce are enable, and a ua sends a response with nonce and qop in the auth header then one_time_nonce will not be used, one_time nonce will be used as a fallback in the case the ua does not support qop.
My auth block in the routing logic looks like so:
route[AUTH_CHECK]{ xlog("L_DBG", "route[AUTH_CHECK] : $rm : Performing authentication checks for '$var(creds_key)'"); $var(challenge_flags) = 1; if ( ! pv_auth_check("$fd", "$sht(creds=>$var(creds_key)::Password)", "20", "1") ) { switch($retcode) { case -1: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Generic error occurred, no reply sent out."); break; case -2: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Invalid password supplied, re-challenging client and removing from hash table."); sht_rm_name_re("creds=>$var(creds_key)"); break; case -4: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Nonce has expired, re-challenging client."); $var(challenge_flags) = $var(challenge_flags) + 16; break; case -5: xlog("L_DBG", "route[AUTH_CHECK] : $rm : No credentials supplied, challenging client."); break; case -6: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Nonce has already been used to auth a previous request, challenging client."); break; case -8: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Auth user is different to From/To user, challenging client."); break; } xlog("L_INFO", "route[AUTH_CHECK] : $rm : auth_challenge will be called with '$fd' and '$var(challenge_flags)'"); auth_challenge("$fd", "$var(challenge_flags)"); exit; } consume_credentials(); }
When I look at the logs I always see the proxies seeing the nonce as expired:
oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17'
I have checked:
[1] that the proxies are all syncing time, and they are not out of sync, [2] The source address of the client doesnt change (in case auth_checks_no_dlg is failing), [3] The r-uri of the subscription dialog is the same (in case auth_checks_no_dlg is failing)
I am using kamailio version 5.0.6:
kamailio -V version: kamailio 5.0.6 (x86_64/linux) flags: STATS: Off, USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB poll method support: poll, epoll_lt, epoll_et, sigio_rt, select. id: unknown compiled on 15:57:47 Mar 5 2018 with gcc 4.8.5
Any thoughts on what I can look at or if I'm missing something fundamental here?
All suggestions/criticisms are appreciated.
Thanks for reading.
Hi All,
Does anyone have any thoughts on how I can debug this further, I'm currently stumped as to what steps to take to see why these messages are failing authentication.
Any suggestions appreciated.
Thanks
On 03/05/18 11:02, Asgaroth wrote:
Hi All,
I am testing a scenario where we have 3 proxies and I'm trying to ensure that if a messages comes in to 1 proxy, which challenges the ua, is able to be auth'd successfully on one of the remaining 2 proxies if, for some reason the ua decides to send the response to one of the remaining two proxies.
I am testing this using a seperate kamailio proxy which loadbalances messages across the 3 proxies that I am testing with. I have 1 ua (zoiper) which I tell to subscribe for mwi, the initial subscribe is sent to proxy 1, which sends a 407 back, the new subscribe with auth, from the ua, is sent to proxy 2, which deems the nonce as expired and rechallenges, this continues in a loop across the 3 proxies and never authenticates.
I think I'm missing something in my settings that I just cannot put my finger on, and/or, I'm mis-understanding the documentation and how these settings interact with each other.
My auth module settings are as follows:
# # ----- auth params ----- # modparam("auth", "qop", "auth") modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1) modparam("auth", "nid_pool_no", 4) modparam("auth", "nc_array_size", 4194304) modparam("auth", "otn_in_flight_no", 8388608) modparam("auth", "auth_checks_no_dlg", 9) modparam("auth", "auth_checks_in_dlg", 15) modparam("auth", "auth_checks_register", 11) modparam("auth", "secret", "secret_32_char_str")
I tried with one_time_nonce enabled and disabled but the result is the same, continous rechallenge.
The documentation mentions that if nonce_count and one_time_nonce are enable, and a ua sends a response with nonce and qop in the auth header then one_time_nonce will not be used, one_time nonce will be used as a fallback in the case the ua does not support qop.
My auth block in the routing logic looks like so:
route[AUTH_CHECK]{ xlog("L_DBG", "route[AUTH_CHECK] : $rm : Performing authentication checks for '$var(creds_key)'"); $var(challenge_flags) = 1; if ( ! pv_auth_check("$fd", "$sht(creds=>$var(creds_key)::Password)", "20", "1") ) { switch($retcode) { case -1: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Generic error occurred, no reply sent out."); break; case -2: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Invalid password supplied, re-challenging client and removing from hash table."); sht_rm_name_re("creds=>$var(creds_key)"); break; case -4: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Nonce has expired, re-challenging client."); $var(challenge_flags) = $var(challenge_flags) + 16; break; case -5: xlog("L_DBG", "route[AUTH_CHECK] : $rm : No credentials supplied, challenging client."); break; case -6: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Nonce has already been used to auth a previous request, challenging client."); break; case -8: xlog("L_DBG", "route[AUTH_CHECK] : $rm : Auth user is different to From/To user, challenging client."); break; } xlog("L_INFO", "route[AUTH_CHECK] : $rm : auth_challenge will be called with '$fd' and '$var(challenge_flags)'"); auth_challenge("$fd", "$var(challenge_flags)"); exit; } consume_credentials(); }
When I look at the logs I always see the proxies seeing the nonce as expired:
oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17' oUBGp0n6HRWu_mvPPxJQqg..: INFO: <script>: route[AUTH_CHECK] : SUBSCRIBE : auth_challenge will be called with 'example.com' and '17'
I have checked:
[1] that the proxies are all syncing time, and they are not out of sync, [2] The source address of the client doesnt change (in case auth_checks_no_dlg is failing), [3] The r-uri of the subscription dialog is the same (in case auth_checks_no_dlg is failing)
I am using kamailio version 5.0.6:
kamailio -V version: kamailio 5.0.6 (x86_64/linux) flags: STATS: Off, USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB poll method support: poll, epoll_lt, epoll_et, sigio_rt, select. id: unknown compiled on 15:57:47 Mar 5 2018 with gcc 4.8.5
Any thoughts on what I can look at or if I'm missing something fundamental here?
All suggestions/criticisms are appreciated.
Thanks for reading.
On Wed, May 09, 2018 at 11:38:57PM +0100, Asgaroth wrote:
Does anyone have any thoughts on how I can debug this further, I'm currently stumped as to what steps to take to see why these messages are failing authentication.
This works with all auth params set to default. My guess the following are the cause of problems.
modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1)
On 11/05/18 13:47, Daniel Tryba wrote:
This works with all auth params set to default. My guess the following are the cause of problems.
modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1)
Thanks for the pointer Daniel, I'll take a look in the comming days and report back.
Much appreciated.
On 11/05/18 13:47, Daniel Tryba wrote:
On Wed, May 09, 2018 at 11:38:57PM +0100, Asgaroth wrote:
Does anyone have any thoughts on how I can debug this further, I'm currently stumped as to what steps to take to see why these messages are failing authentication.
This works with all auth params set to default. My guess the following are the cause of problems.
modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1)
Daniel, *thank you*, this was exactly what was causing the issue, disabled the above two module parameters and, boom, it started working.
I wonder why these particular module parameters would break the functionality though, I thought the idea was that each proxy would be able to generate the nonce with a shared secret if it recieved a challenge response from a ua who's nonce was generated on a different proxy. Is this a bug, or, is it working as intended when these two module paramters are enabled?
On Thu, May 17, 2018 at 11:48:48AM +0100, Asgaroth wrote:
This works with all auth params set to default. My guess the following are the cause of problems.
modparam("auth", "nonce_count", 1) modparam("auth", "one_time_nonce", 1)
Daniel, *thank you*, this was exactly what was causing the issue, disabled the above two module parameters and, boom, it started working.
I wonder why these particular module parameters would break the functionality though, I thought the idea was that each proxy would be able to generate the nonce with a shared secret if it recieved a challenge response from a ua who's nonce was generated on a different proxy. Is this a bug, or, is it working as intended when these two module paramters are enabled?
I was looking at the wording for nonce_count https://www.kamailio.org/docs/modules/5.1.x/modules/auth.html#auth.p.nonce_c... "3.5. nonce_count (boolean)
If enabled the received nc value is remembered and checked against the older value (for a successful authentication the received nc must be greater then the previously received one, see rfc2617 for more details). This will provide protection against replay attacks while still allowing credentials caching at the UA side."
It sounds like this is kept in memory. Since this isn't shared between kamailio instances, the discrepancies in nonce count should trigger the replay attack prevention mechanism (i.e. offer a new challenge).
So I guess this is indended behavior.
Am Donnerstag, 17. Mai 2018, 15:02:13 CEST schrieb Daniel Tryba:
[..]
I wonder why these particular module parameters would break the functionality though, I thought the idea was that each proxy would be able to generate the nonce with a shared secret if it recieved a challenge response from a ua who's nonce was generated on a different proxy. Is this a bug, or, is it working as intended when these two module paramters are enabled?
I was looking at the wording for nonce_count https://www.kamailio.org/docs/modules/5.1.x/modules/auth.html#auth.p.nonce_c ount "3.5. nonce_count (boolean)
If enabled the received nc value is remembered and checked against the older value (for a successful authentication the received nc must be greater then the previously received one, see rfc2617 for more details). This will provide protection against replay attacks while still allowing credentials caching at the UA side."
It sounds like this is kept in memory. Since this isn't shared between kamailio instances, the discrepancies in nonce count should trigger the replay attack prevention mechanism (i.e. offer a new challenge).
So I guess this is indended behavior.
The conditions for the nonce check are bit more complicated, but this is basically the way it works out in the end.
Henning