CentOS 7 用Nginx搭建 WebDav 服务器

标签: none

WebDAV (Web-based Distributed Authoring and Versioning) 一種基於 HTTP 1.1協議的通信協議。它擴展了HTTP 1.1,在GET、POST、HEAD等幾個HTTP標準方法以外添加了一些新的方法,使應用程序可直接對Web Server直接讀寫,並支持寫文件鎖定(Locking)及解鎖(Unlock),還可以支持文件的版本控制。

WebDAV 就是通过 Restful API ,实现对服务端文件的 创建 / 删除 / 读取 / 修改,比起其他文件传输协议,它基于 HTTP,不容易被当作不明流量被砍掉。同时能够利用 HTTP 的各种扩展,比如 HTTPS 提供数据加密功能、HTTP 2.0 提供数据流传输、HTTP 范围请求(RFC7233)等。

正是因为这些好处,很多系统和软件都提供了对 WebDAV 的支持。比如说 OS X 的 finder 支持远程连接到 WebDAV 服务器。IOS 的播放器 nPlayer 能够播放 WebDAV 上的视频文件,且传输速度高于 FTP / SMB 等协议。

准备工作

1.Linux 服务器 (本文以CentOS 7为主)
2.Nginx 1.16.0
3.nginx-dav-ext-module Branch/master (release-v3.0.0)
4.headers-more-nginx-module Branch/master (v0.33)
5.openssl-1.1.1b #开启TLS 1.3
6.zlib 1.2.11 #按照这个版本没问题,由于Nginx是用脚本安装的,未实际测试
7.pcre 8.39 #按照这个版本没问题,由于Nginx是用脚本安装的,未实际测试
8.gcc 8.2 可选
9.LNMP 1.5 | 中文页面

安装工作环境

yum install epel-release expat-devel httpd-tools unzip wget centos-release-scl git
yum install devtoolset-8-gcc*
yum groupinstall "Development tools" 
yum update

编译安装 Nginx

提供两个方案, 我使用的是 方案二
方案一 适用于手动编译,但是没有整理,可以根据方案二的尝试修改

方案一

# nginx user
useradd -r nginx
usermod -s /sbin/nologin nginx

# install pcre 8.39
cd /tmp
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz
tar -zxf pcre-8.39.tar.gz
cd pcre-8.39
./configure
make && make install

# install zlib 1.2.11
cd /tmp
wget http://zlib.net/zlib-1.2.11.tar.gz
tar -zxf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure
make && make install

# install openssl 1.1.0h
cd /tmp
wget http://www.openssl.org/source/openssl-1.1.0h.tar.gz
tar -zxf openssl-1.1.0h.tar.gz
cd openssl-1.1.0h
./config --prefix=/usr
make && make install

# nginx dav ext module
cd /tmp
wget -c https://github.com/arut/nginx-dav-ext-module/archive/v0.1.0.zip -O nginx-dav-ext-module-v0.1.0.zip
unzip nginx-dav-ext-module-v0.1.0.zip

# install nginx 1.15.2
cd /tmp
wget http://nginx.org/download/nginx-1.15.2.tar.gz
tar -zxf nginx-1.15.2.tar.gz
cd nginx-1.15.2
./configure --user=nginx --group=nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_ssl_module --with-stream --with-pcre=../pcre-8.39 --with-zlib=../zlib-1.2.11 --without-http_empty_gif_module --with-http_dav_module --add-module=../nginx-dav-ext-module-0.1.0
make && make install

方案二

为了方(tou)便(lan)首先使用lnmp 的一键脚本安装环境,lnmp或lnmpa都可以.
修改脚本设置编译我们需要有WebDav的nginx.

wget http://soft.vpser.net/lnmp/lnmp1.5.tar.gz
tar zxf lnmp1.5.tar.gz 
cd lnmp1.5

脚本默认安装的没有包含 webdav 所以需要修改一下代码.

首先下载2个nginx 需要的扩展 nginx-dav-ext-moduleheaders-more-nginx-module

为了让 nginx 能够支持 WebDAV 规范中的 PROPFIND 和 OPTIONS ,我们需要安装模块 nginx-dav-ext-module 。

然后在 configure 时,添加 --with-http_dav_module 和 --add-module=/path/to/nginx-dav-ext-module

git clone https://github.com/arut/nginx-dav-ext-module.git
git clone https://github.com/openresty/headers-more-nginx-module.git

开启TLS 1.3,nginx-1.16.0 修改文件 /lnmp1.5/include/version.sh 修改 Openssl_VerNginx_Ver

Openssl_Ver='openssl-1.1.1b'
Nginx_Ver='nginx-1.16.0'

添加扩展编译参数, 修改文件 /lnmp1.5/lnmp.conf 修改 Nginx_Modules_Options

Nginx_Modules_Options='--with-http_dav_module --add-module=../nginx-dav-ext-module --add-module=../headers-more-nginx-module --with-pcre'`

用gcc8.2编译,修改文件 /lnmp1.5/include/nginx.sh./configure 在86行, 有两个./configure 我们安装的是 1.16.0 修改第二个 86行的. 可选

scl enable devtoolset-8 "./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_sub_module --with-stream --with-stream_ssl_module ${Nginx_With_Openssl} ${Nginx_Module_Lua} ${NginxMAOpt} ${Nginx_Modules_Options}"

开始安装,选择你需要的安装

./install.sh lnmpa

安装完检查 Nginx的版本 nginx -V

# nginx -V
nginx version: nginx/1.16.0
built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
built with OpenSSL 1.1.1b  26 Feb 2019
TLS SNI support enabled
configure arguments: ....

这样就ok啦.
如果安装错了 可以用 upgrade_nginx.sh 用更新的方式再次编译nginx.

配置Nginx

修改文件 /usr/local/nginx/conf/nginx.conf
在 http {} 加入

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

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

        server_names_hash_bucket_size 128;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 50m;

        charset utf-8;
        sendfile   on;
        tcp_nopush on;
        types_hash_max_size 2048;
        keepalive_timeout 60;

        tcp_nodelay on;

        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 64k;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_file_write_size 256k;

        gzip on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";

        #limit_conn_zone $binary_remote_addr zone=perip:10m;
        ##If enable limit_conn_zone,add "limit_conn perip 10;" to server section.

        server_tokens off;
        access_log off;
        include vhost/*.conf;

server{} 部分

server
    {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name qaq.app;

        ssl_certificate "证书.crt";
        ssl_certificate_key "py.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers TLS13-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_prefer_server_ciphers on;

        location / {
            set $dest $http_destination;
            if (-d $request_filename) {
                rewrite ^(.*[^/])$ $1/;
                set $dest $dest/;
            }
            if ($request_method ~ (MOVE|COPY)) {
                more_set_input_headers 'Destination: $dest';
            }

            if ($request_method ~ MKCOL) {
                rewrite ^(.*[^/])$ $1/ break;
            }

            dav_methods PUT DELETE MKCOL COPY MOVE;
            dav_ext_methods PROPFIND OPTIONS;
            create_full_put_path  on;
            dav_access user:rw group:rw all:rw;
            autoindex  on;
            client_max_body_size  10G;
            root /home/qaq;

            auth_basic  "closed site";
            auth_basic_user_file ../.htpasswd;
        }
        access_log  /home/wwwlogs/access.log;
    }

该配置开启了 HTTPS ,因为 HTTP2 需要开启 SSL。因此需要设置域名的证书和密钥。同时为了保证安全性,还设置了密码认证,密码文件通过 htpasswd 工具生成。

用途

            set $dest $http_destination;
            if (-d $request_filename) {
                rewrite ^(.*[^/])$ $1/;
                set $dest $dest/;
            }
            if ($request_method ~ (MOVE|COPY)) {
                more_set_input_headers 'Destination: $dest';
            }

            if ($request_method ~ MKCOL) {
                rewrite ^(.*[^/])$ $1/ break;
            }

处理的是某些 WebDAV 客户端(如 OS X 下的 ForkLift) 在 创建文件夹 / 复制文件夹 / 移动文件夹 失败的问题:

2018/06/03 08:03:58 [error] 7#7: *1 MKCOL can create a collection only, client: 8.8.8.8, server: yourhostname.com, request: "MKCOL /sp HTTP/2.0", host: "yourhostname.com"

2018/06/03 08:17:20 [error] 7#7: *18 "/sp" is collection, client: 8.8.8.8, server: yourhostname.com, request: "MOVE /sp HTTP/2.0", host: "yourhostname.com"

这是因为 nginx 创建的 WebDAV server 要求所有对文件夹的操作,路径结尾都要有斜杠 / 。而某些客户端在对文件夹进行操作时路径结尾没有斜杠 /,于是报错。

解决方法是 url rewrite,如果操作的是文件夹,则补上 /。

但对于 MOVE / COPY 操作,文件路径还会设置到 header 的 Destination 中,也需要 rewrite ,这需要借助 headers-more-nginx-module 模块。
需要在 configure 时,添加 --add-module=/path/to/headers-more-nginx-module

创建 htpasswd 用户

htpasswd -c /home/SSL/.htpasswd 'rbq'

都配置完之后 reload nginx

service nginx reload
nginx -s reload

此时,安装了Nginx并配置了基本的WebDav服务器。如果您在Web浏览器中浏览到新的WebDav实例,您应该能够看到该目录中任何现有文件的目录列表,但您将无法通过Web浏览器上载任何新文件。需要使用WebDav客户端(移动应用程序,Windws / Mac / Linux应用程序等),这是管理这些文件的理想方式。

如果目录在 /home 目录 需要把nginx 用户按添加到 组里面 不然无权访问.

id qaq
id www
usermod -G qaq www
id qaq

#并且需要把文件夹权限修改为 774
chmod -R 774 /home/qaq

文章安装贡献价值排序
Install Nginx as a WebDav File Server on CentOS 7
使用 nginx 搭建 WebDAV 服务器
Linux用户(组)管理与权限设定,老司机开车深入浅出你懂得!!
用 Nginx 建立 WebDAV 盘
nginx實戰(二) WebDAV 模塊 http_dav_module


扫描二维码,在手机上阅读!

添加新评论