1. The problem I’m having:
I am using the webdav module to serve Keepass files. I have migrated from Apache to Caddy.
The webdav URL is mounted in MacOS and Keepass accesses the mounted directory.
When Keepass tries to write a new file (this is AFAIK a safety measure, writing a new file and then deleting the old and then renaming), it gets operation not permitted.
Reading the file works fine.
When I try to create a file with touch on the Mac inside the mounted directory, I get no error and the file is not there.
When I try to rename a file with “mv”, I get “Operation not permitted”.
2. Error messages and/or full log output:
Caddy log (I have replaced my domain):
caddy-caddy-1 | {"level":"error","ts":1716108819.0998316,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._thomas.kdbx: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._thomas.kdbx","headers":{"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"],"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.1009986,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/thomas.kdbx.xTmtuh: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/thomas.kdbx.xTmtuh","headers":{"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"],"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.1035361,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._thomas.kdbx.xTmtuh: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._thomas.kdbx.xTmtuh","headers":{"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.1171443,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._.: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._.","headers":{"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"],"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.290026,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._thomas.kdbx.xTmtuh: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._thomas.kdbx.xTmtuh","headers":{"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"],"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.2907417,"logger":"http.handlers.webdav","msg":"internal handler error","error":"rename /dav/thomas.kdbx.xTmtuh /dav/dav/thomas.kdbx: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"MOVE","host":"mydomain.com","uri":"/thomas.kdbx.xTmtuh","headers":{"Authorization":[],"Content-Length":["0"],"Connection":["keep-alive"],"Destination":["https://mydomain.com/dav/thomas.kdbx"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.2960703,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._thomas.kdbx.xTmtuh: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._thomas.kdbx.xTmtuh","headers":{"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"],"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.3010716,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/thomas.kdbx.xTmtuh: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/thomas.kdbx.xTmtuh","headers":{"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
caddy-caddy-1 | {"level":"error","ts":1716108819.6185136,"logger":"http.handlers.webdav","msg":"internal handler error","error":"stat /dav/._.: no such file or directory","request":{"remote_ip":"192.168.0.1","remote_port":"56962","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"PROPFIND","host":"mydomain.com","uri":"/._.","headers":{"Authorization":[],"Content-Length":["179"],"Connection":["keep-alive"],"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/23.4.0 (arm64)"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"mydomain.com"}}}
It’s also strange that Keepass tries to access /dav/dav/thomas.kdbx instead of /dav/thomas.kdbx at one point.
3. Caddy version:
2.7.6
4. How I installed and ran Caddy:
Docker.
a. System environment:
Docker.
I have mounted the dav directory to the Caddy in docker like this in docker-compose.yml:
- type: bind
source: /var/dav/data
target: /dav
When I enter the container I can create files in the mounted directory with touch.
b. Command:
docker compose up -d
c. Service/unit/compose file:
See above for the relevant snippet.
d. My complete Caddy config:
{
order webdav before file_server
}
(webdav) {
handle_path /dav* {
root * /dav
basicauth {
thomas xxx
}
webdav
}
}
mydomain.com:443 {
import webdav
}
I have also tried “handle_path /dav/*” but that did not cure the problem.
I also tried the most basic syntax from the webdav module’s GitHub page, temporarily accepting the loss of basic auth:
webdav /dav/* {
root /dav
prefix /dav
}
This got rid of the “/dav/dav” access error in the log, but the main problem remains: Keepass cannot save.
Thanks!
Edit:
It works fine with Keepassium on the iPhone, so it is a issue with mounting the webdav directory on the Mac.
Edit 2:
Looks like MacOS webdav client support requires Level 2 locking to be available, which Apache has and Nginx not (without workarounds). So, I guess, that the webdav module for Caddy also does not support Level 2 locking.