NGINX WebDAV服务器

安装NGINX及支持WebDAV模块

Ubuntu Linux

  • 对于Ubuntu执行以下安装NGINX以及支持WebDAV模块:

Ubuntu安装NGINX及WebDAV模块
sudo apt -y update
sudo apt -y install nginx nginx-extras libnginx-mod-http-dav-ext libnginx-mod-http-auth-pam
  • 检查 ngnix -V 输出:

检查Ubuntu安装NGINX及WebDAV模块
if nginx -V 2>&1 | grep -qE "http_dav_module|http-dav-ext"; then echo "good to go :)"; else echo "missing dav module :("; fi

macOS

Homebrew NGINX不支持完整WebDAV

macOS中使用 Homebrew 安装NGINX默认已经启用了 ( ngx_http_dav_module ),以下是 macOS工作室 安装工具软件命令。但是,默认 Homebrew 安装的NGINX只提供了 --with-http_dav_module 支持,但是没有 http_ext_module 支持,这会导致 nginx.conf 配置中:

dav_ext_methods PROPFIND OPTIONS;

无法识别,启动nginx时日志提示:

2023/02/13 16:31:56 [emerg] 29049#0: unknown directive "dav_ext_methods" in /usr/local/etc/nginx/nginx.conf:52

这个问题必须解决,否则在 通过WebDAV同步Joplin数据 ,WebDAV客户端执行 MKCOL / PROPFIND 会报错返回 405 返回码

通过编译NGINX支持完整WebDAV功能

要能够支持 通过WebDAV同步Joplin数据 ,需要自己 macOS环境编译NGINX 支持第三方模块 ngx_http_dav_module ,就能够进行下面的配置

配置WebDAV

为Joplin配置WebDAV同步数据( Homebrew )

备注

本段实践为 通过WebDAV同步Joplin数据 提供支持,在 macOS 上采用 Homebrew 提供的NGNIX

创建NGINX的HTTP认证文件
USER=huatai
PASSWORD=XXXXXXX
printf "${USER}:$(openssl passwd -apr1 ${PASSWORD})\n" >> /usr/local/etc/nginx/.htpasswd
  • Homebrew 提供的NGIX配置 /usr/local/etc/nginx/nginx.conf ( brew 安装的NGINX位置可能不同 ) 添加如下段落(我的NGINX监听 8080 端口)

配置NGINX( macOS环境编译NGINX )支持WebDAV
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

#第三方插件 ngx_http_dav_ext_module 支持完整WebDAV功能 https://github.com/arut/nginx-dav-ext-module
load_module "modules/ngx_http_dav_ext_module.so";

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            #root   html;
            root /Users/huatai/docs/github.com/cloud-atlas/build/html;
            index  index.html index.htm;
        }

        location /joplin {
            alias /Users/huatai/docs/joplin;
            #启用 ngx_http_dav_ext_module 模块后可使用 dav_ext_methods 指令
            dav_ext_methods PROPFIND OPTIONS;

            #NGINX核心模块 ngx_http_dav_module 详细配置参考 https://nginx.org/en/docs/http/ngx_http_dav_module.html
            dav_methods PUT DELETE MKCOL COPY MOVE;
            dav_access user:rw group:rw all:rw;
            client_max_body_size 0;
            create_full_put_path on;
            client_body_temp_path /tmp/;

            #使用操作系统PAM认证,适合Linux系统
            #auth_pam "Restricted";
            #auth_pam_service_name "common-auth";

            #使用HTTP 基本认证
            auth_basic "Restricted";
            auth_basic_user_file /opt/nginx/conf/.htpasswd;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    #忽略部分注释内容
    }
    #忽略部分注释内容
    include servers/*;
}
  • 重启 NGINX 服务:

    brew services restart nginx
    
  • /Users/huatai/docs/joplin 目录下存放一个 test_webdav.txt 文件,然后执行不带密码的访问方式:

不使用密码执行curl访问WebDAV测试
curl -I http://127.0.0.1:8080/joplin/test_webdav.txt

提示没有认证的报错:

不使用密码执行curl访问WebDAV测试显示认证错误
HTTP/1.1 401 Unauthorized
Server: nginx/1.23.3
Date: Mon, 13 Feb 2023 09:08:32 GMT
Content-Type: text/html
Content-Length: 179
Connection: keep-alive
WWW-Authenticate: Basic realm="Restricted"
  • 改为提供密码账号方式访问:

使用密码 执行curl访问WebDAV测试
curl -I --user huatai:XXXXXXX http://127.0.0.1:8080/joplin/test_webdav.txt

此时提示信息显示认证通过,返回 200 :

使用密码 执行curl访问WebDAV测试显示正确返回结果
HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Mon, 13 Feb 2023 09:19:17 GMT
Content-Type: text/plain
Content-Length: 13
Last-Modified: Mon, 13 Feb 2023 09:11:25 GMT
Connection: keep-alive
ETag: "63e9febd-d"
Accept-Ranges: bytes

去掉上述 curl 命令的 -I 参数,就能看到终端返回 test_webdav.txt 内容:

Hello WebDAV

然后就可以测试 通过WebDAV同步Joplin数据

异常排查

  • 启动同步后, Joplin 同步提示错误:

Joplin同步报错显示405错误(Method Not Allowed)
Completed: 13/02/2023 17:53 (21s)
Last error: Error: PROPFIND locks/: Unknown error 2 (405): <html> <head><title>405 Not Allowed</title></head> <body> <center><h1>405 Not Allowed</h1></center> <hr><center>nginx/1.23.3</center> </body> </html>
  • 检查 NGINX 的 access.log 日志:

Joplin同步报错时NGINX的access.log日志
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "GET /joplin/info.json HTTP/1.1" 404 153 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "GET /joplin/.sync/version.txt HTTP/1.1" 404 153 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "GET /joplin/info.json HTTP/1.1" 404 153 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "GET /joplin/.sync/version.txt HTTP/1.1" 404 153 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "MKCOL /joplin/locks/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "MKCOL /joplin/temp/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:49 +0800] "PROPFIND /joplin/locks/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:17:59:53 +0800] "PROPFIND /joplin/locks/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:18:00:00 +0800] "PROPFIND /joplin/locks/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:18:00:10 +0800] "PROPFIND /joplin/locks/ HTTP/1.1" 405 157 "-" "Joplin/1.0"
127.0.0.1 - huatai [13/Feb/2023:18:00:10 +0800] "DELETE /joplin/locks/2_1_9264130d027d4c938534be341aba16d2.json HTTP/1.1" 404 153 "-" "Joplin/1.0"

可以看到 405 返回码对应的指令是 MKCOLPROPFIND ,这说明配置中,以下模块选项配置是非常重要的:

dav_ext_methods PROPFIND OPTIONS;

注意,在这个配置前面有一行:

dav_methods PUT DELETE MKCOL COPY MOVE;

表明已经配置允许了 MKCOL WebDAV指令,但是完整的WebDAV指令支持已经不在NGINX中:

这个问题参考:

编译包含 nginx-dav-ext-module 的NGINX

备注

标准的 ngx_http_dav_module 只提供部分WebDAV实现,只支持 GET,HEAD,PUT,DELETE,MKCOL,COPY,MOVE 方法;而 nginx-dav-ext-module 扩展支持了完整的WebDAV方法。

  • 采用 ref:build_nginx_macos 方法完成NGINX安装

  • 配置文件采用上文

参考