caddy not logging basic authentication failures to log/error

Created on 20 Dec 2018  路  10Comments  路  Source: caddyserver/caddy

I'm attempting to use tools like fail2ban to protect basic authentication from brute force. Caddy implements basic auth but doesn't log failures.

I'm using Caddy 0.11.1.

feature request good first issue

Most helpful comment

I have a working implementation of this, I will push a PR later today or over weekend.

All 10 comments

Hello @calisro

Thank you for your issue. Can you be as clear as possible what you are looking for. As far as I can see caddy logs failed authorization attempts in the domain log file with a 401 code. However it doesnt log the username that the failed attempt used.

Hi. Yes 401s are logged but those are unauthorized errors not necessarily authentication failures I believe. For example, when a user comes to a site and see's the basic challenge and simply cancels the request to authorize we'll still see 401's for resources such as favicon.ico. That wasn't an authentication failure. What I am looking for is the basic module to actually log password error attempts.

I believe apache and nginx both do this where they capture the actual attempts at an authorization and not just a 'unauthorized' 401. If you look at the fail2ban config files for nginx, for example, we see this:

failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$

Its logging an actual attempt at passing a username/password to the nginx auth module.

This example is a SINGLE authorization attempt on caddy. One time.

xxxx - xxxxx:0000 - - [21/Dec/2018:08:38:22 -0500] "GET /sdf/sdf HTTP/2.0" 401 17 - /sdf/sdf
xxxx - xxxxx:0000 - - [21/Dec/2018:08:38:27 -0500] "GET /sdf/sdf HTTP/2.0" 401 17 - /sdf/sdf
xxxx - xxxxx:0000 - - [21/Dec/2018:08:38:28 -0500] "GET /favicon.ico HTTP/2.0" 401 17 - /file_not_found

In the above example, we get 3 401's for a single attempt. That is just showing the resources attempted.

In this example, the user didn't even attempted to authorize. They simple cancelled the challange:

xxxx - xxxxx:0000 - - [21/Dec/2018:08:41:58 -0500] "GET /sdf/sdf HTTP/2.0" 401 17 - /sdf/sdf
xxxx - xxxxx:0000 - - [21/Dec/2018:08:42:00 -0500] "GET /favicon.ico HTTP/2.0" 401 17 - /file_not_found

There is currently no way to differentiate between a brute force attack and a resources just not being served because the user hasn't authenticated.

Thank you for the additional information, this is very helpful. This makes it easier for someone to implement the logging.

As ever we are delighted if anyone would like to provide a PR with this functionality.

Would you have an example of the full log line that the regex is matching?

It'll look like this on nginx.

Jun 20 20:22:42 HOST nginx: 2017/06/15 20:22:42 [error] 5413#5413: *101013 user "USER": password mismatch, client: X.X.X.X , server:localhost , request: "GET / HTTP/1.1", host: "HOST"

Jun 20 20:22:42 HOST nginx: 2017/06/15 20:22:42 [error] 5413#5413: *55700 user "engineer" was not found in "/usr/local/nginx/.htpasswd", client: X.X.X.X, server: localhost, request: "GET / HTTP/1.1", host: "HOST"

Is this anywhere in the pipeline to add? I'd offer a PR but I don't have the golang expertise.

I have a working implementation of this, I will push a PR later today or over weekend.

@calisro I have posted a PR can you take a look.

I took a look and it looks good to me. Key fields are captured. Appreciate it @tobya.

@calisro This has now been merged and is in the most recent release 0.11.14

Was this page helpful?
0 / 5 - 0 ratings