atomx / nginx-http-auth-digest

Digest Authentication for Nginx
Other
44 stars 14 forks source link

how is auth_digest realm supposed to work #24

Closed rickysarraf closed 3 years ago

rickysarraf commented 3 years ago

I have a config snippet like:

server {

       listen 80;
       listen [::]:80;
       server_name lenovo;
       return 302 https://$host$request_uri;
       rewrite ^ https://$http_host$request_uri? permanent;    # force redirect http to https

        server_tokens off;
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    server_tokens off;
    server_name lenovo;
    client_max_body_size 500M;

    auth_digest_user_file /etc/nginx/htdigest;
    location /private {
        auth_digest 'abc';
        auth_digest_expires 300s;
        auth_digest_evasion_time 5s;
        auth_digest_replays 500;

        proxy_pass http://localhost/private;
    }

    location /discover {
        auth_digest 'abc';
        auth_digest_expires 600s;
        auth_digest_evasion_time 5s;
        auth_digest_replays 500;

        proxy_pass http://localhost/discover;
    }

    location / {
        auth_digest 'general';
        auth_digest_replays 50000;
        auth_digest_evasion_time 5s;
        auth_digest_expires 1800s;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://localhost;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        #auth_basic "Priv";
        #auth_basic_user_file /etc/nginx/htpasswd;
    }
}

and secrets

rrs@lenovo:~$ cat /etc/nginx/htdigest 
user:abc:17724a1c5a9f23daqwer324df4badsfase485abf
user:general:40432d117673asdf34205fd9c82c5dfas1fc

I can authenticate proper with the realm defined for general in my secrets. Then, when I switch to URL /discover, I expect the auth digest to kick in again, for realm abc. But that doesn't happen. Instead, with the credentials validated from general realm, it proceeds to /discover without prompting for any further auth.

So, how is auth_digest supposed to be used ?

I'm running nginx 1.18.0, with http-auth-digest from this repo.

erikdubbelboer commented 3 years ago

You are right this doesn't seem to be checked at all. I would suggest you switch to https://github.com/samizdatco/nginx-http-auth-digest which is a more up to date version of this module (which I also maintain). I made a pull request there: https://github.com/samizdatco/nginx-http-auth-digest/pull/35 can you try if this change works for you? If it does I'll merge it.

rickysarraf commented 3 years ago

You are right this doesn't seem to be checked at all. I would suggest you switch to https://github.com/samizdatco/nginx-http-auth-digest which is a more up to date version of this module (which I also maintain). I made a pull request there: samizdatco#35 can you try if this change works for you? If it does I'll merge it.

Thank you for the quick reply. I tried the proposed change but that doesn't solve the problem. The auth form the general realm is still carried and the abc realm is bypassed.

rickysarraf commented 3 years ago

I was curious as to why such a simple change wouldn't work. So I tried to check what was being returned. From what I found, and surprised, the check for ngx_strcmp(realm.data, auth_fields->realm.data) returned value (-34: Unknown error).

rickysarraf commented 3 years ago

That error, -34, is my misinterpretation. That's the value from strcmp(). And I pushed it as an error code to ngx_log_err.

/* msvc and icc7 compile strcmp() to inline loop */
#define ngx_strcmp(s1, s2)  strcmp((const char *) s1, (const char *) s2)

So, are these fields supposed to have identical data: realm.data and auth_fields->realm.data ?

erikdubbelboer commented 3 years ago

That is weird. ngx_strcmp returns 0 if the strings are the same, and returns the difference in ascii codes if the strings are different. So -34 just means that if the name of your general ream is real your abc realm probably starts with a K in your real test.

But if it doesn't return 0 it also means it goes into the if and returns a challenge for the correct realm. Are you sure your browser doesn't already have the password for the other realm as well? Or are you using the same password for both realms? Try doing the test again after completely restarting your browser so it doesn't have any previous logins. When I tested it myself just now it worked it seemed.

rickysarraf commented 3 years ago

I don't know.

Your fix looked simple enough that I can't see a reason for it to not work. But unfortunately, in all my tests so far, the auth from realm general gets carried forward to the other one, abc.

It may be something on the client end on my setup but I'm yet to ascertain what. So far, I tried incognito mode, and multiple browsers. But I got the same annoyance.

I think you should commit your changes irrespective, given that the change is very simple.

Thank you. :pray:

erikdubbelboer commented 3 years ago

Is the password for both realms the same maybe?

rickysarraf commented 3 years ago

Is the password for both realms the same maybe?

No. They are different. That's something I made sure of right from the beginning. And I also validated it now be recreating them again, just to be very sure.

rickysarraf commented 3 years ago

I don't think there's anything wrong in my config but I'd still let you have a look as you've already spent time on this issue. Let's be sure that there's no user error on this part.

rrs@lenovo:~$ cat /etc/nginx/sites-available/lenovo
server {

       listen 80;
       listen [::]:80;
       server_name lenovo;
       return 302 https://$host$request_uri;
       rewrite ^ https://$http_host$request_uri? permanent;    # force redirect http to https

        server_tokens off;
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    server_tokens off;
    server_name lenovo;
    client_max_body_size 500M;

    #access_log /var/log/nginx/access.log;
    #error_log /var/log/nginx/error.log;

    location /discover {
        auth_digest_user_file /etc/nginx/htdigest;
        auth_digest 'private';
        auth_digest_expires 600s;
        auth_digest_evasion_time 5s;
        auth_digest_replays 500;

        proxy_pass http://localhost:2342/discover;
    }

    location /private {
        auth_digest_user_file /etc/nginx/htdigest;
        auth_digest 'private';
        auth_digest_expires 300s;
        auth_digest_evasion_time 5s;
        auth_digest_replays 500;

        proxy_pass http://localhost:2342/private;
    }

    location / {
        if ($arg_q ~ 'private:') {
                return 404;
        }
        if ($request_uri ~ 'private:') {
                return 404;
        }

        #auth_basic "General Area";
        #auth_basic_user_file /etc/nginx/htpasswd;

        auth_digest_user_file /etc/nginx/htdigest;
        auth_digest 'general';
        auth_digest_replays 50000;
        auth_digest_evasion_time 5s;
        auth_digest_expires 1800s;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://localhost:2342;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

When, I log into lenovo, it asks for password twice, I think. And in the logs, I get this:

2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/e5ef9780467b9fe8feb06ebd773645e5bf8a6520/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/403dd62b554402644de3b7cca7315719b8fed693/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/828f46910dbd1defe2bd06de69289261cbbe2f84/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/439ddcf35973f9f32f81c8bc655bf7d80fafd056/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/b66e706425df48bd5993ed7e37e394aac46678ae/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/2ca7b078ba02061095608b6b9d164bd9b0778bb2/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/6b9ba15080188c81d44988f7cea92d367e0a801a/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/8c81938a1d378f41aa893a894e87752e7e3f6238/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/12eab493fcb795a187a0ec51831fde8e74572872/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/7db3d55a1c85586cb0a3a9c42d8b20fa9705eee7/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/9737943af74ed95e9f24945e1f11c5907b03b6d9/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/98fd4a84feab10c890231a2272c92a3bbb9f703a/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/e409c9f4954571c8f682ead9fe4e70512f83ff3a/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/56548408c10d3c9a5fd7e1f558deabecd20298bf/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/92f39bc829bd1651befe2dec32add3c58cdc7976/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/d1efa4e80afcd4e972ee55aa2e48d5dab8ee95f8/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/photos?count=60&offset=60&merged=true&country=&camera=0&lens=0&label=&year=0&month=0&color=&order=newest&q=&public=true&quality=3 HTTP
/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/photos?count=360&offset=0&merged=true&country=&camera=0&lens=0&label=&year=0&month=0&color=&order=newest&q=&public=true&quality=3 HTTP
/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/086caf57d55b9f67160b44f057fbdb49b119953b/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/bc167a7e768b6c0003319472843bbfb7b6ecc6ba/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/857e4d65c7ca2b048441b42c15ae2934c5ea0783/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/345d0e6e099904675ad3e59eaf44df3e5040ffed/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/f9fff54e8b2aa460e74a46ed8b8d8d51c5993a3d/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/f169e096144e345ad804886b1418b73225a9b786/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/19fd8dc3feb4380bc603537a1aafefb11e6bc7cb/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/3606bb61e0845357df30d246345c41c2e15eefef/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/0f0c1bdb876354610c6c7e4de2c43b49ecd52e11/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/a9d5f2772653a10de9f7bbe87048fbe03e698c70/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/8b527497c7f1deef8167d4b9b7d161945467d243/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/fb9071c2810ba6378a4c1b6ec28300f92dcd7183/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/d704e00a01afe79391df52076c18254af04ef540/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/fe5404d87393d7c74e37d775e848fbd471bdd68a/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/a404118386cfb6609065cb88c07621b181a55658/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:48 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /api/v1/t/7d6551700180e692e4e2e885e69c9d8f270e3690/9364f06e/tile_500 HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
2021/05/31 17:55:52 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /browse HTTP/2.0", host: "lenovo"
2021/05/31 17:55:52 [error] 2535709#2535709: *2 ignoring authentication request - in evasion period, client: 10.42.0.24, server: lenovo, request: "GET /favicon.ico HTTP/2.0", host: "lenovo", referrer: "https://lenovo/browse"
rickysarraf commented 3 years ago

I think the twice password may have to do with the server ignoring the first authentication request, for reasons it screams, that it is in evasion period. And then the subsequent request gets served, which is odd.

erikdubbelboer commented 3 years ago

@rickysarraf The comparison went wrong. I have fixed the pull request and test it, for me it works now. Can you also check: https://github.com/samizdatco/nginx-http-auth-digest/pull/35

rickysarraf commented 3 years ago

@rickysarraf The comparison went wrong. I have fixed the pull request and test it, for me it works now. Can you also check: samizdatco#35

Good day @erikdubbelboer Thank you for the revised fix. That does indeed solve the problem and behaves as one would expect.