前言
距离上次写这个栏目已经很久了,主要是因为之前的那些东西已经够用了,基本没有改动。
今天继续之前的文章,是因为通过Ubuntu Server搭建SMB服务来做共享感觉不太够用,主要的问题在于外网访问,外网的环境下明显WebDav比SMB协议快的非常多,其次,SMB的另一个劣势也是历史问题,出现过一些比较严重的漏洞(如永恒之蓝EternalBlue),WebDav相对来说则比较安全一些。
特性 | SMB | WebDAV |
---|---|---|
设计初衷 | 局域网(LAN) 文件共享和打印服务 | 广域网(WAN/Internet) 上的文档协作与管理 |
底层协议 | 直接运行在TCP/IP之上(或更早的NetBIOS),使用非标准端口(445, 139) | 运行在HTTP/HTTPS之上,使用标准Web端口(80, 443) |
通信模式 | 有状态连接:客户端和服务器需要建立一个复杂的、持续的会话,维护连接状态。 | 无状态连接:基于HTTP的请求-响应模式,每个请求都是独立的。 |
数据包结构 | 密集的二进制格式,包含大量小数据包进行协商和确认。 | 基于文本的XML和标准HTTP头,数据包更大、更整合。 |
内容
这篇文章就是放弃SMB,选择WebDav,以及WebDav的搭建、优化,并记录在搭建过程遇到的问题,以及解决方案,最终达到一个相对比较满意的结果。
问题
在搭建过程中,我遇到的一些比较大的问题:
使用Nginx搭建WebDav
-
网页端能访问,但是手机平板上的流媒体App无法访问
解决方法:安装
dav_ext_methods
模块,可以参考上一篇文章:使用Nginx搭建WebDav的注意事项补充(流媒体访问) - Forever Young -
解决了流媒体App的访问后,在Windows映射网络驱动,出现了以下问题:
-
上传文件时 Windows 提示要覆盖文件
-
上传失败
-
目标位置只留下一个 0KB 文件
尝试了很多方法,均无法解决。这是因为Nginx WebDAV 模块和 Windows 自带 WebDAV 客户端不兼容。
-
如果不需要映射磁盘,后续对文件编辑直接在终端进行就能满足的话,可以直接使用Nginx搭建,如果需要映射到本地,像本地硬盘一样进行访问、编辑的话,那就只能放弃使用Nginx搭建WebDav。
方案
更换WebDav服务器,使用Apache2来解决磁盘映射的问题,因为Apache mod_dav完整支持 LOCK/UNLOCK,和 Windows 兼容。
因此,可以考虑:
🔹 方案 1:只用 Apache2 提供 WebDAV
最简单,只用Apache2搭建WebDAV,Nginx 继续跑其他应用。
🔹 方案 2:Nginx 前端 + Apache2 后端(反向代理)
Apache2搭建WebDAV后使用Nginx反向代理,从而统一管理。
因为考虑到最终使用HTTPS,对证书、服务配置的简洁化,选用方案2。
步骤
第一步:安装Apache2
sudo apt install apache2
sudo a2enmod dav dav_fs # 启用 WebDAV 模块
第二步:建立WebDav目录
sudo mkdir -p /var/www/webdav
sudo chown -R www-data:www-data /var/www/webdav
sudo chmod -R 755 /var/www/webdav
第三步:配置WebDav服务
新建 /etc/apache2/sites-available/webdav.conf
配置文件:
<VirtualHost *:8080>
ServerName webdav.local
DocumentRoot /var/www/webdav
<Directory /var/www/webdav>
Options Indexes
AllowOverride None
Dav On
Require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/webdav_error.log
CustomLog ${APACHE_LOG_DIR}/webdav_access.log combined
</VirtualHost>
tips:如果服务器有ddns解析,为了防止外网可以通过
http://域名:端口号
进行不安全的访问,可以相应限制,只允许内网设备访问。<VirtualHost 10.0.0.11:8080> # 更换自己的服务器IP+代理的端口号 ServerName webdav.local DocumentRoot /var/www/webdav <Directory /var/www/webdav> Options Indexes AllowOverride None Dav On Require valid-user Require ip 10.0.0.0/24 # 只允许局域网访问,更换自己的内网IP地址段 </Directory> ErrorLog ${APACHE_LOG_DIR}/webdav_error.log CustomLog ${APACHE_LOG_DIR}/webdav_access.log combined </VirtualHost>
第四步:配置端口号
根据上述服务监听的端口,需要在 /etc/apache2/ports.conf
添加对应的端口:
Listen 8080 # 添加,其他的都可以注释掉
第五步:启用WebDav服务
sudo a2ensite webdav.conf # 启用配置
systemctl restart apache2 # 重启并应用apache2
systemctl enable apache2 # apache2自启动
到这一步,已经可以通过 http://<ip>:<port>
访问WebDav了(无账户密码)。
特别注意:我这边后面是使用Nginx做身份验证的,如果只用Apache2的话,配置文件中务必添加身份验证的配置!!!
加上身份验证完整的配置应该是:
<VirtualHost 10.0.0.11:8080> # 更换自己的服务器IP+代理的端口号 ServerName webdav.local DocumentRoot /var/www/webdav <Directory /var/www/webdav> Options Indexes AllowOverride None Dav On # 身份验证 AuthType Digest AuthName "WebDAV" AuthUserFile /etc/apache2/webdav.passwd Require valid-user Require ip 10.0.0.0/24 # 只允许局域网访问,更换自己的内网IP地址段 </Directory> ErrorLog ${APACHE_LOG_DIR}/webdav_error.log CustomLog ${APACHE_LOG_DIR}/webdav_access.log combined </VirtualHost>
身份验证:
sudo a2enmod auth_digest # 启用Digest Auth认证 echo -n "username:WebDAV:password" | md5sum # 假设用户名 username,认证域 WebDAV,密码 password,主要还是不喜欢用
sudo htdigest -c /etc/apache2/webdav.passwd "WebDAV" username
来创建,还要安装apache2-utils
5f4dcc3b5aa765d61d8327deb882cf99 - # 得到这样的输出 echo "username:WebDAV:5f4dcc3b5aa765d61d8327deb882cf99" | sudo tee -a /etc/apache2/webdav.passwd # 用户密码写入webdav.passwd
文件 systemctl restart nginx
第六步:Nginx身份认证
确定可以正常访问后,说明Apache2已经配置好了,接下来要配置Nginx的反向代理了,先配置Nginx的身份认证,直接用auth_basic
认证方式就行,使用上面的auth_digest
认证方式还要安装第三方模块,没必要。
sudo openssl passwd -6 <你的密码>
得到以 $6$
开头的密码字符串。
echo "<你的用户名>:<生成的密码字符串>" | sudo tee -a /etc/nginx/webdav.htpasswd
第七步:Nginx反向代理
编辑WebDav配置文件:
# /etc/nginx/site-enable/webdav.conf
# HTTP配置
server {
listen 80;
listen [::]:80;
server_name yourdomain.com;
location / {
# 启用 Basic Authentication
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/webdav.htpasswd;
proxy_pass http://10.0.0.11:8080/; # 反代 Apache WebDAV
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# HTTPS配置
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name _;
ssl_certificate /path/to/your-domain/certs/fullchain.pem;
ssl_certificate_key /path/to/your-domain/certs/privkey.key;
location / {
# 启用 Basic Authentication
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/webdav.htpasswd;
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
重启Nginx:systemctl restart nginx
。
结尾
经过我测试下来,这种方法完美地支持网页端以及应用端,不管是使用网页直接浏览、Infuse或者nPlayer播放音视频、Windows磁盘映射以及MacOS直接连接,都能正常使用。
不过使用这种方法稍显复杂,对初学者来说有点挑战,建议提前备份,避免造成资料误删。