29

I am trying to do basic auth on Nginx. I have version 1.9.3 up and running on Ubuntu 14.04 and it works fine with a simple html file.

Here is the html file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  "Some shoddy text"
</body>
</html>

And here is my nginx.conf file:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    server {
        listen 80;
        server_name 192.168.1.30;
        location / {
            root /www;
            index index.html;
            auth_basic "Restricted";
            auth_basic_user_file /etc/users;
        }
    }
}

I used htpasswd to create two users in the "users" file under /etc (username "calvin" password "Calvin", and username "hobbes" password "Hobbes"). It's encrypted by looks like this:

calvin:$apr1$Q8LGMfGw$RbO.cG4R1riIfERU/175q0
hobbes:$apr1$M9KoUUhh$ayGd8bqqlN989ghWdTP4r/

All files belong to root:root. The server IP address is 192.168.1.30 and I am referencing that directly in the conf file.

It all works fine if I comment out the two auth lines and restart nginx, but if I uncomment them, then I do indeed get the username and password prompts when I try to load the site, but immediately thereafter get an Error 500 Internal Server error which seems to persist and I have to restart nginx.

Anybody can see what I'm doing wrong here? I had the same behaviour on the standard Ubuntu 14.04 apt-get version of Nginx (1.4.something) so I don't think it's the nginx version.

Thomas Browne
  • 23,824
  • 32
  • 78
  • 121

11 Answers11

60

Not really an answer to your question as you are using MD5. However as this thread pops up when searching for the error, I am attaching this to it.

Similar errors happen when bcrypt is used to generate passwords for auth_basic:

htpasswd -B <file> <user> <pass>

Since bcrypt is not supported within auth_basic ATM, mysterious 500 errors can be found in nginx error.log, (usually found at /var/log/nginx/error.log), they look something like this:

*1 crypt_r() failed (22: Invalid argument), ...

At present the solution is to generate a new password using md5, which is the default anyway.

Edited to address md5 issues as brought up by @EricWolf in the comments:

md5 has its problems for sure, some context can be found in the following threads

Of the two, speed issue can be mitigated by using fail2ban, by banning on failed basic auth you'll make online brute forcing impractical (guide). You can also use long passwords to try and fortify a bit as suggested here.

Other than that it seems this is as good as it gets with nginx...

Community
  • 1
  • 1
Drazen Urch
  • 2,781
  • 1
  • 21
  • 23
  • 1
    OP's htpasswd file contains `$apr1$` which is Apache's MD5. If they were using bcrypt, it would contain `$2y$`. See https://httpd.apache.org/docs/2.4/misc/password_encryptions.html. – Martey Oct 26 '16 at 23:57
  • 1
    This is a valuable answer. Had the problem. Not using bcrypt for basic auth solved the issue. – Matt Bannert Nov 15 '16 at 12:05
  • Super happy it helped :) ! – Drazen Urch Nov 15 '16 at 16:20
  • Isn't md5 insecure though? – Eric Wolf Apr 03 '17 at 22:58
  • 3
    This answer isn't quite right. nginx defers support to crypt_r, which is a part of libc. If the version of libc shipped with the operating system doesn't have bcrypt support, then you will see this error message. – stevvooe Aug 31 '17 at 00:40
  • @stevvooe, interesting, I would expect password generation to fail as well than, or is `htpasswd` using something else. Also I don't see `bcrypt` mentioned in the [docs]: (http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html). Could you maybe link to the source, I'd really like to update the answer to be correct – Drazen Urch Sep 01 '17 at 11:16
  • 1
    @DrazenUrch This is exactly what the error message is saying. `crypt_r` is a libc function. [This](https://github.com/nginxinc/docker-nginx/issues/29) is directly from the nginx developers. I am unfamiliar with the code base of htpasswd, but it is safe to assume it using something else, likely provided by apr. – stevvooe Sep 05 '17 at 16:44
  • 1
    md5 is really not a good idea but luckily nginx supports anything the libraries do, so you can use sha-512 (`mkpasswd -m sha-512`) as a secure alternative of not-supported bcrypt, scrypt or else. – grin Feb 06 '20 at 23:49
15

I had goofed up when initially creating a user. As a result, the htpasswd file looked like:

user:
user:$apr1$passwdhashpasswdhashpasswdhash...

After deleting the blank user, everything worked fine.

Andy Pippin
  • 151
  • 1
  • 2
6

I was running Nginx in a Docker environment and I had the same issue. The reason was that some of the passwords were generated using bcrypt. I resolved it by using nginx:alpine.

Atakan E.
  • 205
  • 2
  • 6
6

Do you want a MORE secure password hash with nginx basic_auth? Do this:

echo "username:"$(mkpasswd -m sha-512) >> .htpasswd

SHA-512 is not considered nearly as good as bcrypt, but it's the best nginx supports at the moment.

Theodore R. Smith
  • 21,848
  • 12
  • 65
  • 91
2

I will just stick the htpassword file under "/etc/nginx" myself. Assuming it is named htcontrol, then ...

sudo htpasswd -c /etc/nginx/htcontrol calvin

Follow the prompt for the password and the file will be in the correct place.

location / {
    ...

    auth_basic "Restricted";
    auth_basic_user_file htcontrol;
}

or auth_basic_user_file /etc/nginx/htcontrol; but the first variant works for me

Dayo
  • 12,413
  • 5
  • 52
  • 67
1

I just had the same problem - after checking log as suggested by @Drazen Urch I've discovered that the file had root:root permissions - after changing to forge:forge (I'm using Forge with Digital Ocean) - the problem went away.

Sebastian Sulinski
  • 5,815
  • 7
  • 39
  • 61
1

Well, just use correct RFC 2307 syntax:

passwordvalue          = schemeprefix encryptedpassword
schemeprefix           = "{" scheme "}"
scheme                 = "crypt" / "md5" / "sha" / altscheme
altscheme              = "x-" keystring
encryptedpassword      = encrypted password

For example: sha1 for helloworld for admin will be

  • admin:{SHA}at+xg6SiyUovktq1redipHiJpaE=

I had same error cause i wrote {SHA1} what against RFC syntax. When i fixed it - all worked like a charm. {sha} will not work too. Only correct {SHA}.

Community
  • 1
  • 1
nikitasius
  • 99
  • 9
1

First, check out your nginx error logs:

tail -f /var/log/nginx/error.log

In my case, I found the error:

[crit] 18901#18901: *6847 open() "/root/temp/.htpasswd" failed (13: Permission denied),

The /root/temp directory is one of my test directories, and cannot be read by nginx. After change it to /etc/apache2/ (follow the official guide https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/) everything works fine.

===

After executing the ps command we can see the nginx worker process maintained by the user www-data, I had tried to chown www-data:www-data /root/temp to make sure www-data can access this file, but it still not working. To be honest, I don't have a very deep understanding on Linux File Permissions, so I change it to /etc/apache2/ to fix this in the end. And after a test, you can put the .htpasswd file in other directories which in /etc (like /etc/nginx).

enter image description here

Harry Yu
  • 323
  • 1
  • 3
  • 11
1

I too was facing the same problem while setting up authentication for kibana. Here is the error in my /var/log/nginx/error.log file

2020/04/13 13:43:08 [crit] 49662#49662: *152 crypt_r() failed (22: Invalid argument), client: 157.42.72.240, server: 168.61.168.150, request: “GET / HTTP/1.1”, host: “168.61.168.150”

I resolved this issue by adding authentication using this.

sudo sh -c "echo -n 'kibanaadmin:' >> /etc/nginx/htpasswd.users"
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/htpasswd.users"

You can refer this post if you are trying to setup kibana and got this issue.

https://medium.com/@shubham.singh98/log-monitoring-with-elk-stack-c5de72f0a822?postPublishedType=repub

shubham singh
  • 511
  • 1
  • 5
  • 16
1

In my case, I was using plain text password by -p flag, and coincidentally my password start with $ character. So I updated my password and thus the error was gone.

NB: Other people answer helped me a lot to figure out my problem. I am posting my solution here if anyone stuck in a rare case like me.

Rafik Farhad
  • 1,182
  • 2
  • 12
  • 21
1

In my case, I had my auth_basic setup protecting an nginx location that was served by a proxy_pass configuration.

The configured proxy_pass location wasn't returning a successful HTTP200 response, which caused nginx to respond with an Internal Server Error after I had entered the correct username and password.

If you have a similar setup, ensure that the proxy_pass location protected by auth_basic is returning an HTTP200 response after you rule out username/password issues.

Adil B
  • 14,635
  • 11
  • 60
  • 78