Basic Auth with Scrypt

1. Caddy version (caddy version):

v2.2.0 h1:sMUFqTbVIRlmA8NkFnNt9l7s0e+0gw+7GPIrhty905A=

2. How I run Caddy:

a. System environment:

Ubuntu 20.04

b. Command:

sudo ./caddy run

Prior to configuring, I ran: ./caddy hash-password --plaintext password --algorithm scrypt --salt salt

It returned: S8D9UH6TpgB2gCE0HscmxXwAy1WkcCoWUBMTZVAM9HE=

I then converted the salt to base64: echo 'salt' | base64

It returned: c2FsdAo=.

Thus I used:

    basicauth / scrypt prometheus {
        matt S8D9UH6TpgB2gCE0HscmxXwAy1WkcCoWUBMTZVAM9HE= c2FsdAo=
    }

c. Service/unit/compose file:

N/A

d. My complete Caddyfile or JSON config:

192.168.1.106:9089 {
    tls /etc/caddy/ssl/prometheus-bundle.pem /etc/caddy/ssl/prometheus-key.pem {
        protocols tls1.3
    }

    # Reverse proxy to Prometheus
    reverse_proxy localhost:9090

    root * /var/www/caddy/prometheus/

    # Use https://caddyserver.com/docs/command-line#caddy-hash-password
    basicauth / scrypt prometheus {
        matt S8D9UH6TpgB2gCE0HscmxXwAy1WkcCoWUBMTZVAM9HE= c2FsdAo=
    }

    # https://caddyserver.com/docs/caddyfile/directives/log
    log {
        output file /var/log/caddy/prometheus/caddy.log {
            roll_size     5mb      # Rotate after the log file reaches this size (in megabytes)
            roll_keep     40       # Keep at most this many log files (older files get pruned)
            roll_keep_for 90d      # Keep rotated files for this many days
        }

}

3. The problem I’m having:

I am unable to login with basic auth when using scrypt.

I went to https://192.168.1.106:9089/ and input:
Username: matt
Password: password

However, it doesn’t let me in.

4. Error messages and/or full log output:

HTTP 401

2020/10/05 22:45:00.936	error	http.log.access.log0	handled request	{
   "request":{
      "remote_addr":"192.168.1.101:50630",
      "proto":"HTTP/2.0",
      "method":"GET",
      "host":"192.168.1.106:9089",
      "uri":"/",
      "headers":{
         "Referer":[
            "https://192.168.1.106:9089/graph?g0.range_input=1h&g0.expr=prometheus_build_info&g0.tab=0"
         ],
         "Accept-Language":[
            "en-US,en;q=0.9,es-US;q=0.8,es;q=0.7"
         ],
         "Cache-Control":[
            "max-age=0"
         ],
         "Dnt":[
            "1"
         ],
         "Sec-Fetch-Mode":[
            "navigate"
         ],
         "Sec-Fetch-Dest":[
            "document"
         ],
         "Sec-Fetch-User":[
            "?1"
         ],
         "Accept-Encoding":[
            "gzip, deflate, br"
         ],
         "Upgrade-Insecure-Requests":[
            "1"
         ],
         "User-Agent":[
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
         ],
         "Accept":[
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
         ],
         "Sec-Fetch-Site":[
            "cross-site"
         ]
      },
      "tls":{
         "resumed":false,
         "version":772,
         "cipher_suite":4865,
         "proto":"h2",
         "proto_mutual":true,
         "server_name":""
      }
   },
   "common_log":"192.168.1.101 - - [05/Oct/2020:17:45:00 -0500] \"GET / HTTP/2.0\" 401 0",
   "duration":0.000124642,
   "size":0,
   "status":401,
   "resp_headers":{
      "Server":[
         "Caddy"
      ],
      "Www-Authenticate":[
         "Basic realm=\"prometheus\""
      ]
   }
}2020/10/05 22:45:01.517	error	http.log.access.log0	handled request{
   "request":{
      "remote_addr":"192.168.1.101:50630",
      "proto":"HTTP/2.0",
      "method":"GET",
      "host":"192.168.1.106:9089",
      "uri":"/",
      "headers":{
         "User-Agent":[
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
         ],
         "Accept":[
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
         ],
         "Sec-Fetch-User":[
            "?1"
         ],
         "Sec-Fetch-Dest":[
            "document"
         ],
         "Accept-Language":[
            "en-US,en;q=0.9,es-US;q=0.8,es;q=0.7"
         ],
         "Cache-Control":[
            "max-age=0"
         ],
         "Dnt":[
            "1"
         ],
         "Upgrade-Insecure-Requests":[
            "1"
         ],
         "Accept-Encoding":[
            "gzip, deflate, br"
         ],
         "Sec-Fetch-Site":[
            "cross-site"
         ],
         "Sec-Fetch-Mode":[
            "navigate"
         ],
         "Referer":[
            "https://192.168.1.106:9089/graph?g0.range_input=1h&g0.expr=prometheus_build_info&g0.tab=0"
         ]
      },
      "tls":{
         "resumed":false,
         "version":772,
         "cipher_suite":4865,
         "proto":"h2",
         "proto_mutual":true,
         "server_name":""
      }
   },
   "common_log":"192.168.1.101 - - [05/Oct/2020:17:45:01 -0500] \"GET / HTTP/2.0\" 401 0",
   "duration":0.000070331,
   "size":0,
   "status":401,
   "resp_headers":{
      "Server":[
         "Caddy"
      ],
      "Www-Authenticate":[
         "Basic realm=\"prometheus\""
      ]
   }
}2020/10/05 22:45:11.661	error	http.log.access.log0	handled request{
   "request":{
      "remote_addr":"192.168.1.101:50630",
      "proto":"HTTP/2.0",
      "method":"GET",
      "host":"192.168.1.106:9089",
      "uri":"/",
      "headers":{
         "Cache-Control":[
            "max-age=0"
         ],
         "Dnt":[
            "1"
         ],
         "Upgrade-Insecure-Requests":[
            "1"
         ],
         "User-Agent":[
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
         ],
         "Accept":[
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
         ],
         "Sec-Fetch-Dest":[
            "document"
         ],
         "Referer":[
            "https://192.168.1.106:9089/graph?g0.range_input=1h&g0.expr=prometheus_build_info&g0.tab=0"
         ],
         "Authorization":[
            "Basic bWF0dDpwYXNzd29yZA=="
         ],
         "Sec-Fetch-Site":[
            "cross-site"
         ],
         "Sec-Fetch-Mode":[
            "navigate"
         ],
         "Sec-Fetch-User":[
            "?1"
         ],
         "Accept-Encoding":[
            "gzip, deflate, br"
         ],
         "Accept-Language":[
            "en-US,en;q=0.9,es-US;q=0.8,es;q=0.7"
         ]
      },
      "tls":{
         "resumed":false,
         "version":772,
         "cipher_suite":4865,
         "proto":"h2",
         "proto_mutual":true,
         "server_name":""
      }
   },
   "common_log":"192.168.1.101 - - [05/Oct/2020:17:45:11 -0500] \"GET / HTTP/2.0\" 401 0",
   "duration":0.098174738,
   "size":0,
   "status":401,
   "resp_headers":{
      "Server":[
         "Caddy"
      ],
      "Www-Authenticate":[
         "Basic realm=\"prometheus\""
      ]
   }
}

5. What I already tried:

Various different inputs to ./caddy hash-password and various different basic auth configs within the Caddyfile. For instance:

    basicauth / scrypt prometheus {
        matt S8D9UH6TpgB2gCE0HscmxXwAy1WkcCoWUBMTZVAM9HE= salt
    }

I also tried prefixing my user name with the real name in the base64 prompt in my browser.

When configuring to use bcrypt, it worked as expected.

I searched the forum and Github issues looking for better examples than what is available in the documentation. The documentation discusses scrypt but only shows a full example of bcrypt.

6. Links to relevant resources:

The salt input to the hash-password command is expected to be a base64 string already. salt is technically itself valid base64.

That said, I highly recommend using bcrypt anyways. The problem with scrypt is that the salt is chosen by the user, which makes is extremely easy to shoot yourself in the foot by picking a very weak salt. You should also not be using the same salt for every password. bcrypt deals with these problems automatically by always generating a good random salt, and embedding it in the output hash.

Thank you for this info. I read the docs as saying the hash-password salt input was a plain string rather than a base64 encoded string.

caddy hash-password
	[--plaintext <password>]
	[--algorithm <name>]
	[--salt <string>]

I hear your points on bcrypt vs scrypt. I don’t have a strong preference either way and tend to agree that bcrypt is better for most folks. I like that scrypt is memory hard vs CPU hard. Hopefully, Argon2 support will be implemented as discussed at x/crypto/scrypt,x/crypto/argon2: add high-level APIs · Issue #16971 · golang/go · GitHub, making it easier to support in Caddy.

Argon2 is actually worse than bcrypt, turns out. Here’s a twitter thread about it that I happened to participate in:

Very interesting. Thanks for sharing. That was news to me.

This topic was automatically closed after 30 days. New replies are no longer allowed.