惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
Hacker News: Ask HN
Hacker News: Ask HN
T
Threatpost
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
S
SegmentFault 最新的问题
月光博客
月光博客
Latest news
Latest news
博客园 - Franky
T
Threat Research - Cisco Blogs
有赞技术团队
有赞技术团队
博客园_首页
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
爱范儿
爱范儿
Security Latest
Security Latest
Scott Helme
Scott Helme
博客园 - 聂微东
T
Tor Project blog
美团技术团队
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AWS News Blog
AWS News Blog
Jina AI
Jina AI
Vercel News
Vercel News
小众软件
小众软件
T
Tenable Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Forbes - Security
Forbes - Security
aimingoo的专栏
aimingoo的专栏
O
OpenAI News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
AI
AI

Alliot's blog

域名切换到blog.alliot.tech Docker 代理配置机制与作用域 Docker 代理配置机制与作用域 2025年底的安卓搞机备忘录 2025年底的安卓搞机备忘录 ArgoCD部署应用出现metadata.annotations过大问题 ArgoCD部署应用出现metadata.annotations过大问题 APC UPS更换电池校准容量 APC UPS更换电池校准容量 M1 Mac安装低版本Node.js M1 Mac安装低版本Node.js Ansible使用Bitwarden存储Vault密码 Ansible使用Bitwarden存储Vault密码 Cloudflare Tunnel前置代理支持 Cloudflare Tunnel前置代理支持 CDN场景下配置Vaultwarden启用fail2ban CDN场景下配置Vaultwarden启用fail2ban 中银香港丝滑开户总结 中银香港丝滑开户总结 从指定路径更新雷池WAF证书 从指定路径更新雷池WAF证书 AWS ECS使用EBS作为Volume AWS ECS使用EBS作为Volume 浅浅的调教一下国产智障电视 浅浅的调教一下国产智障电视 Nginx proxy_pass到AWS ALB的504问题 Nginx proxy_pass到AWS ALB的504问题 OpenV**手动指定路由规则 OpenV**手动指定路由规则 本地模拟CNAME解析 本地模拟CNAME解析 Nginx搭建WebDAV服务 迎来船新版本的Hexo+NexT 迎来船新版本的Hexo+NexT 优雅的处理Git多帐号与代理问题 优雅的处理Git多帐号与代理问题 验光配镜扫盲 验光配镜扫盲 Prometheus relabel实现动态metrics path Prometheus relabel实现动态metrics path
Nginx搭建WebDAV服务
Alliot · 2023-10-23 · via Alliot's blog

  迫于无法忍受现成的 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” 的错误:

1
2
 *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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 下载 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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 来生成:

1
2
3
4
apt install -y apache2-utils

htpasswd -c /etc/nginx/htpasswd <username>

使用 Systemd 来托管 Nginx 进程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 + 云备份,才是最优解。