摘自原文: https://blog.jaspirit.cc/posts/69f0ff47/ 作者本人

Nginx 反向代理 WebDAV 服务,不能上传、新建、重命名文件及文件夹的解决办法

1 NAS简介

NAS网络附属存储)是专用于数据存储的服务器,可将其视作大容量自建云盘。同时,多数NAS设备会挂载多个磁盘并组成磁盘阵列,通过将文件分散存储或拷贝到多个磁盘以保证某一磁盘损坏时数据不会丢失。目前市场普及率最高的家用NAS设备提供商为群晖(Synology)。笔者使用群晖的一款双盘位NAS与2块西数4T红盘组建NAS服务,总可用容量约3.6TB。

2 将NAS服务进行HTTPS加密

使用http协议传输数据是不安全的,且输入网址时还要附带端口号,十分麻烦。若可使用nginx对内网穿透服务端进行反向代理并进行https加密,则有望通过https默认端口(443)访问NAS服务。

对NAS的Web管理界面的反向代理操作十分简单,只需在location块中添加反向代理参数即可:

location / {
    proxy_pass http://127.0.0.1:9080;
    proxy_redirect $host/ $http_host/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
}

但对于WebDAV服务而言,仅添加上述的反向代理参数是不够的,会出现无法上传文件和无法新建、重命名和移动文件及文件夹等一系列问题,经分析,原因如下:

  1. WebDAV的请求头存在自定义字段Destination。在反向代理时,nginx默认不会将Destination字段中https://in-naswebdav.yourdomain.com/...https替换为http,后台的NAS因而无法定位目标地址,进而出现502等一系列问题(若使用frp的https服务,则需添加https2http插件
    ,详见此文,本文不使用此方法)。
  2. WebDAV对文件夹的创建以及文件和文件夹的重命名操作,其请求路径需以/结尾,而通过nginx的uri往往缺少结尾的/,导致操作失败。

为了解决上述第一个问题,将Destination请求头中的https替换为http,我们使用nginx的第三方模块more_set_headers,具体安装方法可参考此文章
模块添加完成后,在nginx.conf配置文件的http块(注意 不是 server块)中添加map指令,将请求头Destination中的https替换为http,并解决webdav重命名中文文件夹的乱码问题:

map $http_destination $webdav_dest {
    ~*https://(.+) http://$1;
    default $http_destination;
}

接着,在location块中添加如下语句,解决WebDAV不能复制、移动文件问题:

if ($request_method ~ (MOVE|COPY))
{  
    more_set_input_headers 'Destination: $webdav_dest';
}

接下来解决创建及重命名文件夹的问题,在location块中添加如下语句:

# 解决webdav不能创建文件夹问题
if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; }

# 解决webdav不能重命名问题
if (-d $request_filename) {
    rewrite ^(.*[^/])$ $1/;
    set $webdav_dest $webdav_dest/;
    more_set_input_headers 'Destination: $webdav_dest';
}

然后在location块中加上反向代理设置,即完成配置。完整的server块如下:

server {
    listen 443 ssl;
    server_name  in-nas.yourdomain.com;
    charset utf-8;
    
    ssl_certificate yourdomain.com/fullchain.pem;
    ssl_certificate_key yourdomain.com/privkey.pem;
    ssl_trusted_certificate  yourdomain.com/chain.pem;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    server_tokens off;

    fastcgi_param   HTTPS               on;
    fastcgi_param   HTTP_SCHEME         https;
    
    # 修改包大小上限避免上传错误
    client_max_body_size 10G;

    location / {

        # 解决webdav不能创建文件夹问题
        if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; }

        # 解决webdav不能重命名问题
        if (-d $request_filename) {
            rewrite ^(.*[^/])$ $1/;
            set $webdav_dest $webdav_dest/;
            more_set_input_headers 'Destination: $webdav_dest';
        }

        # 解决webdav不能复制、移动文件问题
        if ($request_method ~ (MOVE|COPY))
        {  
            more_set_input_headers 'Destination: $webdav_dest';
        }

        proxy_pass http://127.0.0.1:9080;
        proxy_redirect $host/ $http_host/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }
}

重启nginx后,WebDAV功能全部正常,可通过https://naswebdav.yourdomain.com/使用WebDAV服务,具体包括网络磁盘挂载、文件同步等。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐