本文内容是尝试Nginx WebDav的过程中产物,虽然在Windows下,尝试Nginx WebDav失败了。
WebDav是什么,能做什么?
WebDAV(Web Distributed Authoring and Versioning)是一种基于HTTP协议的扩展,旨在提供在Web服务器上进行文件管理的标准化解决方案。允许用户通过网络对远程主机上的文件进行读写、编辑和删除操作;WebDAV支持文件锁定功能,确保在多个用户同时编辑同一个文件时不会发生冲突。这有助于团队成员之间的协作,使得多人协同编辑变得更加高效和方便。
与传统的HTTP相比,WebDAV添加了一组方法和头部,以支持更复杂的文件操作。使用https的WebDAV数据传输安全性较高,但WebDAV文件传输效率,大量文件管理效率是远不如SMB的。
- SMB(Server Message Block) 协议是1983年由IBM公司提出的,为了DOS系统(Windows基于DOS开发)开发的一种用于在计算机间共享文件、打印机、串口的协议。目前SMB协议作为Windows自带的协议,并且Linux、Mac现在都已经支持SMB,且支持跨网段。
WebDav 服务端
- IIS:通过“启用WebDav”功能开启,没有使用过。
- Apache HTTP Server:没有使用过。
- Nginx:通过 –with-http_dav_module 自带模块与 nginx-dav-ext-module 扩展模块的实现支持。
- Nginx for Windows 的WebDav不能挂载,是因为只有自带模块,没有扩展模块的支持(除非你自己编译生成)。
- –with-http_dav_module 自带模块,更多是用于http请求方法的支持;不主动配置,默认只支持GET,而POST还得要有响应支持,其他请求方法直接405了。
- Nginx WebDAV 扩展模块(nginx-dav-ext-module)补充了 Nginx 自带的部分 WebDAV 实现,添加了 PROPFIND、OPTIONS、LOCK 和 UNLOCK 方法,允许 Nginx 作为功能更全的 WebDAV 服务器运行。
WebDav 客户端
- 系统自带支持:Windows(会自动触发启动WebClient系统服务)、Linux、macOS
- 如果Nginx 没有WebDav扩展模块,在Windows中“添加网络位置”时,表现为重复弹出验证对话框,即使输入正确。
- 因为在使用PROPFIND(负责检索资源的属性)方法列出目录时,被响应405。
- 另外,Windows 写文件需要LOCK指令,Linux 不需要。
- 如果Nginx 没有WebDav扩展模块,在Windows中“添加网络位置”时,表现为重复弹出验证对话框,即使输入正确。
- WinSCP
- ……
nginx.exe -V
nginx version: nginx/1.26.1
built by cl 16.00.30319.01 for 80x86
built with OpenSSL 3.0.13 30 Jan 2024
TLS SNI support enabled
configure arguments: --with-cc=cl --builddir=objs.msvc8 --with-debug --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --http-scgi-temp-path=temp/scgi_temp --http-uwsgi-temp-path=temp/uwsgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs.msvc8/lib/pcre2-10.39 --with-zlib=objs.msvc8/lib/zlib-1.3.1 --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_stub_status_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_slice_module --with-mail --with-stream --with-stream_realip_module --with-stream_ssl_preread_module
Nginx 的基本认证
HTTP Basic认证是一种简单且广泛使用的身份验证机制,它通过在客户端与服务器之间传输经过Base64编码的用户名和密码来验证用户。虽然这种方式对安全性要求不高的场景较为实用,但请注意,其并未对传输的数据进行加密,因此在HTTPS环境下使用更为推荐。
在Nginx中,配置语句很简单,可在 http,server,location,limit_except 中使用。
auth_basic "提示文案" | off;
auth_basic_user_file htpasswd.conf;
- 在浏览器的输入user/password窗口中,没有看到”提示文案”内容;但在curl中,失败时看到了”提示文案”内容,应该是浏览器的原因。
- 使用 off 可取消继承自上级的认证设置,但要关注 location 匹配优先级,避免指定了off,还是要认证。
Nginx/conf/htpasswd.conf 文件内容
可能是Windows版本原因,不需要使用网上说的,利用 Apache工具包中的 htpasswd 工具把密码加密处理。
一个用户一个行,示例:用户admin的密码是123456
# user:password:comment
admin:123456:给人看的内容
curl.exe 验证
验证方法:成功响应200,失败响应401
curl -u admin:123456 -I http://x.y.z
curl --ca-native -u admin:123456 -I https://x.y.z
如果Web服务器支持,可以使用curl工具查询支持哪些 Http 请求方法(有风险,所以一般都默认不支持),及使用指定请求方法操作。
# 查询Web服务器支持的http请求方法:成功200,看响应里的【Allow:】行内容;但nginx默认不允许 OPTIONS 方法,会得到405。
curl --ca-native -X OPTIONS -I https://x.y.z
# 删除文件,成功2xx
curl --ca-native -X DELETE https://x.y.z/test.text
# 上传内容为abc的文件,因为不能使用-I,成功无反馈内容。
curl --ca-native -X PUT https://x.y.z/test.text -d "abc"



通过 satisfy,实现ip限制与auth_basic结合使用
示例:192.168.0.0/24 不需要登录,但其他请求,需要验证后,才可以访问。
location /internal/ {
satisfy any;
allow 192.168.0.0/24;
deny all;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}
- satisfy any:只需满足任意一个条件即可。
- satisfy all:必须满足所有条件;默认情况下,Nginx 使用 satisfy all,即所有条件都必须满足。
Nginx WebDav配置
http_dav_module
# 开启WebDav:https://nginx.org/en/docs/http/ngx_http_dav_module.html
dav_methods PUT DELETE MKCOL COPY MOVE;
create_full_put_path on;
dav_access user:rw group:rw all:r;
min_delete_depth 2;
- dav_methods 支持方法;
- create_full_put_path on=允许创建目录;
- dav_access 为新建的文件或目录,赋权限;
- min_delete_depth 使用 DELETE 方法删除文件时,最小层级;如果配置为2,则第1层级的不能删除,只删除2或2+的层级,这样可以保护第1层的目录与文件。
nginx-dav-ext-module:完整支持
dav_ext_xxx的配置,都是要这个模块做支持;没有试过,供参考。
- 进行 WebDAV 协议的 MOVE/COPY 操作时,会通过 HTTP 请求头属性字段 Destination 指定目标路径,如果客户端请求头中没有字段 Destination,Nginx 会直接报错。为增加服务端兼容性,可以通过第三方模块 headers-more-nginx-module 的 more_set_input_headers 指令在 MOVE/COPY 操作的 HTTP 请求头中强制添加 Destination 字段。
http {
# 锁定区域的名称、大小、超时时间
dav_ext_lock_zone zone=lockSpace:10m timeout=1m;
server {
# 最大允许上传的文件大小
client_max_body_size 20m;
location /webdav {
auth_basic "Authorized Users WebDAV";
auth_basic_user_file /etc/nginx/conf/.davpasswd;
root /data/webdav;
# 解决 WebDAV 不能创建文件夹问题
if ($request_method = MKCOL) {
rewrite ^(.*[^/])$ $1/ break;
}
# 解决 WebDAV 不能重命名问题:在对目录请求时,对URI自动添加"/"
if (-d $request_filename) {
rewrite ^(.*[^/])$ $1/;
set $webdav_dest $webdav_dest/;
more_set_input_headers 'Destination: $webdav_dest';
}
# 解决 WebDAV 不能复制、移动文件问题:对MOVE|COPY方法强制添加Destination请求头
if ($request_method ~ (MOVE|COPY)) {
more_set_input_headers 'Destination: $webdav_dest';
}
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
dav_ext_lock zone=lockSpace;
}
}
}
发表回复