google / google-authenticator-libpam

Apache License 2.0
1.78k stars 284 forks source link

Nginx with PAM authentication through pam_script #221

Open kuznetcoff777 opened 1 year ago

kuznetcoff777 commented 1 year ago

System information

Operating system (e.g. Ubuntu 22.04): oracle linux 8.5 Do you use selinux? (check with e.g. sestatus): disabled

Steps to reproduce

  1. Assembled nginx docker container with pam auth module, added apk google-authenticator to container
  2. /etc/pam.d/nginx contains this: auth required /lib/security/pam_google_authenticator.so
  3. locally created /root/.google_authenticator - chekcked it via sshd pam, works
  4. nginx.conf has this in config load_module /etc/nginx/modules/ngx_http_auth_pam_module.so;

and this in location /

                auth_pam "Secure area";
                auth_pam_service_name "nginx";

5 launching docker docker run --name nginx-pam -e TZ="Europe/Moscow" --network host -v /etc/ssl/nginx:/etc/ssl/nginx:ro -v /etc/pam.d/nginx:/etc/pam.d/nginx:ro -v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -v /root/.google_authenticator:/root/.google_authenticator -d nginx-pam-assemble

When enter http address in browser i see http auth "Secure area", but when enter root and OTP - in logs i see this:

2022/12/30 12:47:26 [error] 23#23: *3 PAM: user 'root' - not authenticated: Authentication failure, client: 1.1.1.1, server: _, request: "GET / HTTP/1.1", host: "2.2.2.2"

If i do something wrong and it cannot work as i expect?

ThomasHabets commented 1 year ago

This seems more like an nginx question than a question for this project. You're not showing any logs from PAM. E.g. /var/log/auth.log is usually the right place.

I assume that the section of the README on this project describing forward_pass is applicable, so you probably need those options.

And if the logs still don't help you, then add the debug option to get more logs.

kuznetcoff777 commented 1 year ago

/var/log/auth.log is empty, seems to be docker issue, so debug mode wont help. Need to do experiment without docker probably

forward_pass does not help

kuznetcoff777 commented 1 year ago

Made nginx withoud docker, the samep roblem, but now i see logs in /var/log/secure

Dec 30 16:39:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765503]: debug: start of google_authenticator for "root"
Dec 30 16:39:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765503]: Failed to change user id to "root"
Dec 30 16:39:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765503]: debug: end of google_authenticator for "root". Result: Authentication failure

Why is that? Why it try to change user id to "root"

ThomasHabets commented 1 year ago

Because you're asking it to auth as root, and read files owned as root.

You could try using the secret= and user= options.

kuznetcoff777 commented 1 year ago

Ok, made simplier test. Added user test.

cp /root/.google_authenticator /home/test/
chown test:test /home/test/.google_authenticator
ls -alt /home/test/.google_authenticator
-r--r--r--. 1 test test 94 Dec 30 16:49 /home/test/.google_authenticator

in pam.d

auth required pam_google_authenticator.so debug secret=/home/${USER}/.google_authenticator

And still the same after nginx restart:

Dec 30 16:53:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765585]: debug: start of google_authenticator for "test"
Dec 30 16:53:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765585]: Failed to change user id to "test"
Dec 30 16:53:21 test-oracle-linux-8 nginx(pam_google_authenticator)[1765585]: debug: end of google_authenticator for "test". Result: Authentication failure
kuznetcoff777 commented 1 year ago

Also attempted to place user=root

Still the same, i doing something wrong...

ThomasHabets commented 1 year ago

nginx is not running as user root, which means it can't change to user test either. Try user=www or whatever nginx runs as.

kuznetcoff777 commented 1 year ago

Master process from root:


[root@test-oracle-linux-8 transcoder]# ps aux | grep nginx
root     1765600  0.0  0.0  49176   912 ?        Ss   16:57   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    1765601  0.0  0.0  83884  6352 ?        S    16:57   0:00 nginx: worker process
nginx    1765602  0.0  0.0  83884  5360 ?        S    16:57   0:00 nginx: worker process
root     1765607  0.0  0.0  12132  1100 pts/0    S+   16:58   0:00 grep --color=auto nginx
ThomasHabets commented 1 year ago

So user=nginx.

kuznetcoff777 commented 1 year ago

I got it, /home/test have no permissions for nginx user. I made separate folder user=nginx secret=/var/google/${USER}/.google_authenticator now new error, but it is better then was before )

Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: start of google_authenticator for "test"
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: Secret file permissions are 0444. Allowed permissions are 0600
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Secret file "/var/google/test/.google_authenticator" permissions (0444) are more permissive than 0600
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: No secret configured for user test, asking for code anyway.
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Invalid verification code for test
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: end of google_authenticator for "test". Result: Authentication failure
ThomasHabets commented 1 year ago

These lines say pretty clearly what the error is:

Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: Secret file permissions are 0444. Allowed permissions are 0600
Dec 30 17:01:24 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Secret file "/var/google/test/.google_authenticator" permissions (0444) are more permissive than 0600

chmod 600 /var/google/test/.google_authenticator

kuznetcoff777 commented 1 year ago

Yep, made it. Now i catch this

Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: start of google_authenticator for "test"
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: Secret file permissions are 0600. Allowed permissions are 0600
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: "/var/google/test/.google_authenticator" read
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: shared secret in "/var/google/test/.google_authenticator" processed
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: google_authenticator for host "1.1.1.1"
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: no scratch code used from "/var/google/test/.google_authenticator"
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Accepted google_authenticator for test
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Failed to create tempfile "/var/google/test/.google_authenticator~FMagD9": Permission denied
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: Failed to update secret file "/var/google/test/.google_authenticator": Permission denied
Dec 30 17:06:38 test-oracle-linux-8 nginx(pam_google_authenticator)[1765647]: debug: end of google_authenticator for "test". Result: Authentication failure
kuznetcoff777 commented 1 year ago

why it errors " no scratch code used from"

ThomasHabets commented 1 year ago

Again, nginx runs as user nginx. That user therefore needs to own the secret files and the directories they're in. (except if nginx runs as root in which case it can change identity to any user)

ThomasHabets commented 1 year ago

No scratch code used because you probably didn't enter a scratch code (8 digit code).

Also you can't use scratch codes if you can't mark them as used. And you can't mark them as used if you can't write to the files.

kuznetcoff777 commented 1 year ago

Made new secret file, qr added to authenticator, added permissions to nginx for file(6) and folder(7)

Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: start of google_authenticator for "test"
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: Secret file permissions are 0600. Allowed permissions are 0600
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: "/var/google/test/.google_authenticator" read
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: shared secret in "/var/google/test/.google_authenticator" processed
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: google_authenticator for host "1.1.1.1"
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: no scratch code used from "/var/google/test/.google_authenticator"
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: Accepted google_authenticator for test
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: "/var/google/test/.google_authenticator" written
Dec 30 17:19:07 test-oracle-linux-8 nginx(pam_google_authenticator)[1765648]: debug: end of google_authenticator for "test". Result: Success

And why 8 digit, on authenticator i see 6 digits

kuznetcoff777 commented 1 year ago

Result: Success

but i still see 401 and basic auth window

kuznetcoff777 commented 1 year ago

Found scratch Dec 30 17:24:41 test-oracle-linux-8 nginx(pam_google_authenticator)[1765712]: debug: scratch code 13901918 used and removed from "/var/google/test/.google_authenticator"

Result: Success but still 401

kuznetcoff777 commented 1 year ago

Seems to be it is nginx pam module issue?

kuznetcoff777 commented 1 year ago

chmod 600 "/var/google/test/.google_authenticator"

after that i login-otp

Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: start of google_authenticator for "test"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: Secret file permissions are 0600. Allowed permissions are 0600
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: "/var/google/test/.google_authenticator" read
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: shared secret in "/var/google/test/.google_authenticator" processed
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: google_authenticator for host "1.1.1.1"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: no scratch code used from "/var/google/test/.google_authenticator"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: Accepted google_authenticator for test
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: "/var/google/test/.google_authenticator" written
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: end of google_authenticator for "test". Result: Success
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: start of google_authenticator for "test"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: Secret file permissions are 0400. Allowed permissions are 0600
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: "/var/google/test/.google_authenticator" read
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: shared secret in "/var/google/test/.google_authenticator" processed
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: google_authenticator for host "1.1.1.1"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: no scratch code used from "/var/google/test/.google_authenticator"
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: Trying to reuse a previously used time-based code. ("/var/google/test/.google_authenticator")Retry again in 30 seconds. Warning! This might mean, you are currently subject to a man-in-the-middle attack.
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: Invalid verification code for test
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: "/var/google/test/.google_authenticator" written
Dec 30 17:44:37 test-oracle-linux-8 nginx(pam_google_authenticator)[1765833]: debug: end of google_authenticator for "test". Result: Authentication failure

In the beginning 0600 and Result: Success

After that it begin another check it is 0400 and Result: Authentication failure

Any thoughts how come?

ThomasHabets commented 1 year ago

The reason for the authentication error is right there. Please read the logs more carefully.

kuznetcoff777 commented 1 year ago

I read it, and i see as a said: -it checks otp, says it ok, write it it to a file (permissions are ok = 0600) -after that - one more check - it see that 0400 permission (seems to be it some how changed it - why?) and see error Trying to reuse a previously used time-based code or Too many concurrent login attempts

I dont get it why it cheks twice?

ThomasHabets commented 1 year ago

Oh, this is just one attempt?

For some reason nginx is calling this PAM module twice. Maybe one request for the URL, one for favicon.ico?

Yeah I don't know how you mean for this to work.