1. Caddy version (caddy version
):
2.2.1
2. How I run Caddy:
Systemd, with “/path/to/caddy run /path/to/Caddyfile”
a. System environment:
Centos 8, with SELinux disabled (running in a Hyper-V 2019 VM). All current updates installed. Using systemd.
b. Command:
as above
c. Service/unit/compose file:
# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
User=caddy
#User=root
Group=caddy
#Group=root
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
#PrivateTmp=true
#ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
d. My complete Caddyfile or JSON config:
####################################################################################
# Test Caddyfile
####################################################################################
{
debug
email pwh@cassland.org
}
####################################################################################
# Sites
####################################################################################
pen2.cassland.org {
root * /var/www/html/cassland_org
basicauth /Nic/* { # directory is browsed
NBH JDJhJDE0JHo5WGN5eGZ6SkNiRlEwYmtaZjlMMWVMeE1rVWIwZjNCNGhDdXJvRGRjVWRxQ1I5V3ozcWpH # something
}
@browsedirs {
path /Nic
path /Nic/* #basicauth required
}
file_server @browsedirs browse
file_server
handle_errors {
@404 {
expression {http.error.status_code} == "404"
}
rewrite @404 /404.html # /404.html or /New404.html
file_server
}
log {
output file /var/log/caddy/CLaccess.log
format single_field common_log
}
}
3. The problem I’m having:
I have a directory, which is browsed, and which is protected by basicauth. If I add a handle_errors directive, the basicauth fails to send the correct status back to the client, which therefore does not proceed to ask for credentials - in the error case, instead of the expected 401 the status returned is logged as 0 but shown by curl as 200.
4. Error messages and/or full log output:
Without handle_errors:
Log:
192.168.1.74 - - [18/Nov/2020:12:12:37 +0000] "GET /Nic/ HTTP/1.1" 401 0
Curl:
C:\Users\paul.CASS>curl -v https://pen2.cassland.org/Nic/
* Trying 192.168.1.86...
* TCP_NODELAY set
* Connected to pen2.cassland.org (192.168.1.86) port 443 (#0)
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 1/3)
* schannel: checking server certificate revocation
* schannel: sending initial handshake data: sending 188 bytes...
* schannel: sent initial handshake data: sent 188 bytes
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 2/3)
* schannel: encrypted data got 3100
* schannel: encrypted data buffer: offset 3100 length 4096
* schannel: sending next handshake data: sending 93 bytes...
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 2/3)
* schannel: encrypted data got 186
* schannel: encrypted data buffer: offset 186 length 4096
* schannel: SSL/TLS handshake complete
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 3/3)
* schannel: stored credential handle in session cache
> GET /Nic/ HTTP/1.1
> Host: pen2.cassland.org
> User-Agent: curl/7.55.1
> Accept: */*
>
* schannel: client wants to read 102400 bytes
* schannel: encdata_buffer resized 103424
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: encrypted data got 173
* schannel: encrypted data buffer: offset 173 length 103424
* schannel: decrypted data length: 144
* schannel: decrypted data added: 144
* schannel: decrypted data cached: offset 144 length 102400
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: decrypted data buffer: offset 144 length 102400
* schannel: schannel_recv cleanup
* schannel: decrypted data returned 144
* schannel: decrypted data buffer: offset 0 length 102400
< HTTP/1.1 401 Unauthorized
< Server: Caddy
< Www-Authenticate: Basic realm="restricted"
< Date: Wed, 18 Nov 2020 12:12:37 GMT
< Content-Length: 0
<
* Connection #0 to host pen2.cassland.org left intact
But when handle_errors is added to the Caddyfile I get the following:
Log:
192.168.1.74 - - [18/Nov/2020:12:13:31 +0000] "GET /Nic/ HTTP/1.1" 0 0
Curl:
C:\Users\paul.CASS>curl -v https://pen2.cassland.org/Nic/
* Trying 192.168.1.86...
* TCP_NODELAY set
* Connected to pen2.cassland.org (192.168.1.86) port 443 (#0)
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 1/3)
* schannel: checking server certificate revocation
* schannel: sending initial handshake data: sending 188 bytes...
* schannel: sent initial handshake data: sent 188 bytes
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 2/3)
* schannel: encrypted data got 3101
* schannel: encrypted data buffer: offset 3101 length 4096
* schannel: sending next handshake data: sending 93 bytes...
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 2/3)
* schannel: encrypted data got 186
* schannel: encrypted data buffer: offset 186 length 4096
* schannel: SSL/TLS handshake complete
* schannel: SSL/TLS connection with pen2.cassland.org port 443 (step 3/3)
* schannel: stored credential handle in session cache
> GET /Nic/ HTTP/1.1
> Host: pen2.cassland.org
> User-Agent: curl/7.55.1
> Accept: */*
>
* schannel: client wants to read 102400 bytes
* schannel: encdata_buffer resized 103424
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: encrypted data got 163
* schannel: encrypted data buffer: offset 163 length 103424
* schannel: decrypted data length: 134
* schannel: decrypted data added: 134
* schannel: decrypted data cached: offset 134 length 102400
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: decrypted data buffer: offset 134 length 102400
* schannel: schannel_recv cleanup
* schannel: decrypted data returned 134
* schannel: decrypted data buffer: offset 0 length 102400
< HTTP/1.1 200 OK
< Server: Caddy
< Www-Authenticate: Basic realm="restricted"
< Date: Wed, 18 Nov 2020 12:13:31 GMT
< Content-Length: 0
<
* Connection #0 to host pen2.cassland.org left intact
Debug log:
{"level":"error","ts":1605703916.8081162,"logger":"http.log.error.log0","msg":"error handling handler error","request":{"remote_addr":"192.168.1.74:1281","proto":"HTTP/1.1","method":"GET","host":"pen2.cassland.org","uri":"/Nic/","headers":{"User-Agent":["curl/7.55.1"],"Accept":["*/*"]},"tls":{"resumed":false,"version":771,"cipher_suite":49196,"proto":"","proto_mutual":true,"server_name":"pen2.cassland.org"}},"duration":0.0001428,"error":"{id=pcd6e6rcx} fileserver.(*FileServer).notFound (staticfiles.go:386): HTTP 404","first_error":{"msg":"not authenticated","status":401,"err_id":"bsz4y89g5","err_trace":"caddyauth.Authentication.ServeHTTP (caddyauth.go:78)"}}
{"level":"info","ts":1605703916.8096578,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_addr":"192.168.1.74:1281","proto":"HTTP/1.1","method":"GET","host":"pen2.cassland.org","uri":"/Nic/","headers":{"User-Agent":["curl/7.55.1"],"Accept":["*/*"]},"tls":{"resumed":false,"version":771,"cipher_suite":49196,"proto":"","proto_mutual":true,"server_name":"pen2.cassland.org"}},"common_log":"192.168.1.74 - - [18/Nov/2020:12:51:56 +0000] \"GET /Nic/ HTTP/1.1\" 0 0","duration":0.0001428,"size":0,"status":0,"resp_headers":{"Server":["Caddy"],"Www-Authenticate":["Basic realm=\"restricted\""]}}
5. What I already tried:
Previously discussed in this thread. The present thread shows the simplest form of the error that I can produce. Not all the problems I discussed before show up in this simple form - in particular, if the protected resource is not browsed and has an index.html file, then in this simple case the problem doesn’t occur.
Paul