转载 . 留档 . 自用:Nginx搭建WebDAV服务
迫于无法忍受现成的 NAS 系统的限制,Alliot 正在着手将最常用的一些服务剥离出来,方便迁移与定制, WebDAV 首当其冲, Alliot 在许多场景下的同步与备份都依赖它。
WebDAV 作为一种基于HTTP/HTTPS协议的网络通信协议,预想是非常简单的,然而在具体动手的过程中还是遇到了挺多坑,Obsidian 的 Remotely-save 便是其中一个。
本文将基于 Nginx/Tengine 手把手构建一个 WebDAV 服务。
前言
Obsidian 的 Remotely-Save 插件在尝试使用 Nginx + nginx-dav-ext-module 搭建的 WebDAV 服务上同步时出现了 “405 Method Not Allowed” 的错误:
*26 mkdir() "/webdav/obsidian/note/.obsidian" failed (17: File exists)
request: "MKCOL /webdav/obsidian/note/.obsidian/ HTTP/2.0"
之前是直接使用的群晖 WebDAV 服务,没有遇到过这个问题, 而群晖使用的是 httpd 作为 WebDAV 服务端。
经过一轮测试与研究,发现了如下 Github Issue:
https://github.com/remotely-save/remotely-save/issues/81
RootOfCase 在于 nginx-dav-ext-module 这个拓展模块没有正确的对 .
开头的文件(即隐藏文件)处理,而 Obsidian 的配置文件夹 .obsidian
刚好是 .
开头:
https://github.com/arut/nginx-dav-ext-module/issues/41
不过这个项目已经年久失修,从评论区我们找到了一个修复这个问题的 Fork 仓库:
https://github.com/mid1221213/nginx-dav-ext-module
编译安装
注: Alliot 本文是以 Tengine 为例来进行编译安装的,Nginx 与 Openresty 基本一致,在此文中可以同等看待。
编译 Nginx:
```shell highlight-fold
下载 nginx-dav-ext-module
git clone https://github.com/mid1221213/nginx-dav-ext-module
下载Nginx源码
wget https://tengine.taobao.org/download/tengine-3.0.0.tar.gz tar -zxf tengine-3.0.0.tar.gz cd tengine-3.0.0
安装编译源码必要的依赖
apt-get install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev
./configure –prefix=/var/www/html
–sbin-path=/usr/sbin/nginx
–conf-path=/etc/nginx/nginx.conf
–user=www –group=www \
–error-log-path=/var/log/nginx/error.log
–http-log-path=/var/log/nginx/access.log
–lock-path=/var/lock/nginx.lock
–pid-path=/var/run/nginx.pid
–with-http_stub_status_module
–with-http_realip_module
–with-http_ssl_module
–with-http_gzip_static_module
–with-http_v2_module
–with-pcre
–with-http_dav_module
–add-module=../nginx-dav-ext-module
make -j
make install
Nginx 配置文件如下, 可以直接追加到 `/etc/nginx/nginx.conf`:
```nginx highlight-fold
dav_ext_lock_zone zone=webdav:10m;
server {
listen 443 ssl http2;
server_name www.iots.vip;
access_log /var/log/nginx/webdav.log;
ssl_certificate /etc/letsencrypt/live/www.iots.vip/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.iots.vip/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:MozSSL:10m;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
client_max_body_size 0;
error_page 497 https://$host:$server_port$request_uri;
location /webdav/ {
create_full_put_path on;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
dav_access user:rw group:rw all:rw;
dav_ext_lock zone=webdav;
client_max_body_size 0;
client_body_temp_path /tmp/nginx_client-bodies;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
alias /data/sync/webdav/;
}
这里的用户名密码使用 apache2-utils
中的 htpasswd
来生成:
apt install -y apache2-utils
htpasswd -c /etc/nginx/htpasswd <username>
使用 Systemd 来托管 Nginx 进程:
```routeros highlight-fold cat > /lib/systemd/system/nginx.service « EOF [Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target
[Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/usr/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true
[Install] WantedBy=multi-user.target EOF
systemctl daemon-reload systemctl enable –now nginx.service ```
测试同步
Alliot 使用 Obsidian 的 Remotely-save 配置:
服务器地址: https://domain/webdav/obsidian (这里注意,一定要加上obsidian子路径,因为这个插件不像其他的客户端,它不会帮你创建目录,如果不加obsidian,便会将所有的文件直接同步到webdav下)
用户名,密码
鉴权类型: basic
同步配置文件夹: 开启
PS
2023-10-23: 就在今天,蚂蚁旗下的云笔记——语雀,不出意外的出现了重大故障,故障时间长达八小时(五个 9 的 SLO 直接炸了),各个技术群里一片骂声。
笔记作为 IT 人的核心生产力工具,我始终相信最简单的 Markdown + Local-First + 云备份,才是最优解。