ilium007
(ilium007)
October 15, 2024, 11:15am
1
1. The problem I’m having:
I would like user1, user2, and user3 to have read only webdav access and admin-user to have read / write access. I have the following Caddyfile:
Before I added the handle @admin
block I was able to get user1-3 read only access working. I can’t get the read / write working for admin-user
2. Error messages and/or full log output:
{"level":"debug","ts":1728990184.4524872,"logger":"http.log.error","msg":"not authenticated","request":{"remote_ip":"xxx","remote_port":"42010","client_ip":"xxx","proto":"HTTP/1.1","method":"PROPFIND","host":"webdav.xxxx.com.au:9000","uri":"/dav/","headers":{"Content-Type":["text/xml"],"Depth":["0"],"Accept":["*/*"],"User-Agent":["WebDAVFS/3.0.0 (03008000) Darwin/24.0.0 (arm64)"],"Content-Length":["179"],"Connection":["keep-alive"]},"tls":{"resumed":false,"version":771,"cipher_suite":49195,"proto":"","server_name":"webdav.xxxx.com.au"}},"duration":0.000076738,"status":401,"err_id":"v6u0s99i2","err_trace":"caddyauth.Authentication.ServeHTTP (caddyauth.go:89)"}
3. Caddy version:
v2.8.4
4. How I installed and ran Caddy:
Docker compose
a. System environment:
Docker
b. Command:
docker compose up -d
c. Service/unit/compose file:
d. My complete Caddy config:
{
debug
email support@xxxx.com.au
}
webdav.xxxx.com.au:9000 {
tls {
dns cloudflare xxxx
}
route /dav/* {
root /webdav_root
@admin {
vars http.auth.user.id admin-user
}
handle @admin {
basic_auth {
admin-user xxxx
}
}
@noWrite {
not method GET HEAD OPTIONS PROPFIND
}
handle @noWrite {
respond 403
}
handle {
basic_auth {
user1 xxxx
user2 xxxx
user3 xxxx
}
}
uri strip_prefix /dav
webdav
}
}
5. Links to relevant resources:
ilium007
(ilium007)
October 15, 2024, 11:26am
2
This config works for read only access for all users, I just need admin-user to have read /write access.
{
debug
email support@xxxx.com.au
}
webdav.xxxx.com.au:9000 {
tls {
dns cloudflare xxxx
}
route /dav/* {
root /webdav_root
@noWrite {
not method GET HEAD OPTIONS PROPFIND
}
handle @noWrite {
respond 403
}
handle {
basic_auth {
admin-user xxxx
user1 xxxx
user2 xxxx
user3 xxxx
}
}
uri strip_prefix /dav
webdav
}
}
ilium007
(ilium007)
October 16, 2024, 1:19am
3
I feel like the answer is close in this threrad:
I have now found a solution that works - here it is!
{
http_port 8080
order webdav before file_server
order handle before webdav
}
:8080 {
rewrite /dav/media /dav/media/
route /dav/media* {
basicauth {
alba-guest <psw>
alba-shared <psw>
}
# Thank you mholt for hinting at a solution
# https://github.com/mholt/caddy-webdav/issues/27
# https://caddy.community/t/disallow-webdav-write-http-methods-for-certain-user/20781
@webdavAccess2 {
not {
not {
…
but I don’t understand the double {not {not
in that reply.
arichiardi
(Andrea Richiardi)
October 16, 2024, 1:43am
4
That is basically inverted (in the De Morgan sense) logic in order to make sure both clauses are eventually in OR.
2 Likes
ilium007
(ilium007)
October 16, 2024, 1:36pm
5
Sorry - I don’t quite understand. I started researching De Morgan Theory’s and got even more confused.
ilium007
(ilium007)
October 16, 2024, 2:43pm
7
Thanks - I have it working now.
{
email xxxx@xxxx.com.au
order webdav before file_server
order handle before webdav
}
webdav.xxxx.com.au:9000 {
tls {
dns cloudflare xxxx
}
rewrite /dav /dav/
route /dav/* {
basic_auth {
admin1 xxxx
admin2 xxxx
user1 xxxx
user2 xxxx
user3 xxxx
}
@webdavAccess {
not {
not {
vars {http.auth.user.id} "admin1"
method GET HEAD OPTIONS PROPFIND TRACE DELETE POST PUT PROPPATCH MKCOL MOVE LOCK UNLOCK COPY
}
not {
vars {http.auth.user.id} "admin2"
method GET HEAD OPTIONS PROPFIND TRACE DELETE POST PUT PROPPATCH MKCOL MOVE LOCK UNLOCK COPY
}
not {
method GET HEAD OPTIONS PROPFIND
}
}
}
@unauthorized {
not {
vars {http.auth.user.id} "admin1"
}
not {
vars {http.auth.user.id} "admin2"
}
not method GET HEAD OPTIONS PROPFIND
}
handle @unauthorized {
respond 403
}
webdav @webdavAccess {
root /webdav_root
prefix /dav
}
}
}
1 Like
Mohammed90
(Mohammed Al Sahaf)
October 16, 2024, 2:45pm
8
This should probably work or get you close to the solution:
{
debug
email support@xxxx.com.au
}
webdav.xxxx.com.au:9000 {
tls {
dns cloudflare xxxx
}
route /dav/* {
root /webdav_root
basic_auth {
admin-user xxxx
user1 xxxx
user2 xxxx
user3 xxxx
}
# using an expression matcher (https://caddyserver.com/docs/caddyfile/matchers#expression)
# to recognize disallowed scenarios
@unauthorized `({http.auth.user.id} in ["user-1", "user-2", "user-3"]) && !({method} in ["GET", "HEAD", "OPTIONS", "PROPFIND"])`
respond @unauthorized 403
uri strip_prefix /dav
webdav
}
}
It uses the expression
matcher to make the logic clear
3 Likes
ilium007
(ilium007)
October 17, 2024, 1:04pm
10
This solution is better than my efforts! I modified slightly:
{
#debug
email support@xxxx.com.au
}
webdav.xxxx.com.au:9000 {
tls {
dns cloudflare xxxx
}
rewrite /dav /dav/
route /dav/* {
basic_auth {
admin-user xxxx
user1 xxxx
user2 xxxx
}
@unauthorized `!({http.auth.user.id} in ["admin-user"]) && !({method} in ["GET", "HEAD", "OPTIONS", "PROPFIND"])`
respond @unauthorized 403
webdav {
root /webdav_root
prefix /dav
}
}
respond 404 # all requests not to `/dav/*` get a 404
}
1 Like
Ahh - so, since grouped matchers are AND, but we want OR logic…
We take “not A, AND not B” and invert that… Which gives us, essentially, “it can’t be missing both of them”. Basically, “it has to have at least one of them”. Which is the OR logic we wanted.
foo OR bar
= not (not foo AND not bar)
That’s actually a pretty neat trick I’d never really considered! Usually for this kind of thing I reach for CEL expressions nowadays like Mohammed gave - but it seems like it might be a useful trick to know some day…
2 Likes
you helped me figure those details out for the not
matcher docs years ago actually! I talked about it in my conference talk a couple years ago:
1 Like
arichiardi
(Andrea Richiardi)
November 1, 2024, 3:05am
13
Yeah thank you for expanding on that. It is indeed tricky as at the time I didn’t know any other way to achieve what I wanted.
I think a better way was already posted here…
system
(system)
Closed
December 1, 2024, 3:06am
14
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.