使用 Caddy+AriaNg 搭建私人网盘

更新:

本文已过时.请阅读用"更现代的"方法,建立基于 aria2c 的下载服务器.

本来是挺简单个事, ownCloud 装上去随便配置两下就搞定的,没想到花了我这么多时间.还是写篇文章记录一下吧.

尝试了 ownCloud 和 Pydio, 都很不满意,遂萌生了自行搭建网盘的想法.最终的效果还是很不错的.文件的浏览/上传/下载用 Caddy 的 filemanager 插件实现,离线下载用 aria2 做后端, AriaNg 做前端.大概是这个样子:

第一张图是离线下载,第二张图是文件管理,都是在线的.

我是将网盘分成两部分来做的,一部分是文件管理,成品是 https://dl.nota.moe/; 另一部分是离线下载,成品是 https://aria.nota.moe/.那么就具体说说我的做法吧.

首先你得用 Caddy 做服务器,其次你的 Caddy 要装上 filemanager 这个插件.方法我就不赘述了,假定你已经成功地安装了 Caddy. 然后在 Caddyfile 中这么写:

dl.nota.moe { #这里替换为你的域名
	root /var/www/some_path #这里替换为你的文件储存目录
	log /var/www/log/dl.nota.moe.log #这两行是日志文件的位置
	errors /var/www/log/dl.nota.moe.log
	filemanager / {
	show           /var/www/some_path #这行的内容应该与上面的 root 一致
	allow_new      true
	allow_edit     true
	allow_commands true
	}
#	browse #如果你没装 filemanager,可以把上面的删了改用自带的 browse
	basicauth / *** *** #肯定要设置密码呀

}

这里有一个坑. Caddy 给的示例代码里写的都是 show ./ ,然而据我测试, filemanager 总会把当前用户的 HOME 目录作为自己的根目录,因此 show ./ 就直接把你的 HOME 目录暴露出来了.所以这里应该改成你存储文件的目录的绝对路径.

这样以后你就已经完成了文件管理的功能.访问你的域名,就可以看到一个功能比较完善的文件管理器界面了.如果你给的权限够的话,可以直接在这个界面里进行上传,重命名,移动,删除,新建文件(夹)等操作,而且还自带了 git/svn 同步文件的功能,可谓是相当实用了.

你可以自行研究 filemanager 文档: https://caddyserver.com/docs/filemanager.

下一步,实现离线下载的功能.一直以来, aria2+YAAW 都是个人网盘的首选,然而我发现了一个比 YAAW 更好的 aria2 前端: AriaNg(https://github.com/mayswind/AriaNg) 功能比 YAAW 多,而且界面也很清爽,我推荐使用.

首先安装 aria2, 直接用包管理器下就是了.然后需要写配置文件,提供一份我自己的 aria2.conf 供参考:

#设置加密的密钥
rpc-secret= #############请自行填写
#允许rpc
enable-rpc=true
#允许所有来源, web界面跨域权限需要
rpc-allow-origin-all=true
#允许外部访问,false的话只监听本地端口
rpc-listen-all=true
#RPC端口, 仅当默认端口被占用时修改
#rpc-listen-port=6800
#最大同时下载数(任务数), 路由建议值: 3
max-concurrent-downloads=5
#断点续传
continue=true
#同服务器连接数
max-connection-per-server=5
#最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
min-split-size=10M
#单文件最大线程数, 路由建议值: 5
split=10
#下载速度限制
max-overall-download-limit=0
#单文件速度限制
max-download-limit=0
#上传速度限制
max-overall-upload-limit=0
#单文件速度限制
max-upload-limit=0
#断开速度过慢的连接
#lowest-speed-limit=0
#验证用,需要1.16.1之后的release版本
#referer=*
#文件保存路径, 默认为当前启动位置
dir= #############请自行填写
#文件缓存, 使用内置的文件缓存, 如果你不相信Linux内核文件缓存和磁盘内置缓存时使用, 需要1.16及以上版本
#disk-cache=0
#另一种Linux文件缓存方式, 使用前确保您使用的内核支持此选项, 需要1.15及以上版本(?)
#enable-mmap=true
#文件预分配, 能有效降低文件碎片, 提高磁盘性能. 缺点是预分配时间较长
#所需时间 none < falloc ? trunc << prealloc, falloc和trunc需要文件系统和内核支持
file-allocation=falloc
# 从会话文件中读取下载任务
input-file=/etc/aria2/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
save-session=/etc/aria2/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=60

/etc/aria2/aria2.session 这个文件需要你自己建好, aria2 不会自己建立的.

(接下来的步骤可能有些匪夷所思,稍后我会解释原因的)

然后我们要让 aria2 像一个"服务"那样运行,使之拥有开机自启和自动重启的能力.我之前有篇文章讨论过这个问题:在 GNU screen 中优雅地运行 Caddy, 依葫芦画瓢即可.

建立 3 个 Shell 脚本(别吐槽Linux 萌新只会这么整):

aria2c_init.sh

aria2c --conf-path=/path/to/aria2.conf --rpc-certificate=/path/to/aria2cert/server.pem --rpc-private-key=/path/to/aria2cert/server.key --rpc-secure

(这里需要 SSL 证书,稍后我会介绍方法的)

aria2c_check.sh

aria2c_pids="$($_CMD pgrep aria2c)"
if [ ! $aria2c_pids ]; then
        screen -dmS aria2c /path/to/aria2c_init.sh
fi

aria2c_reload.sh

killall aria2c
sleep 5
/path/to/aria2c_check.sh

(让它睡 5 秒的原因是杀完进程立即重启经常会失败)

然后把这个加入 crontab:

*/1 * * * * /path/to/aria2c_check.sh

这样就实现了开机自启和自动重启.接下来我们需要 SSL 证书.首先,你得再加一条 DNS 记录 (A 或 CNAME 均可)指向你的服务器 IP. 注意,这个新加的域名不绑定 80/443 端口,不运行 web 服务,仅用于 aria2 的 RPC 连接.这是因为 SSL 证书只能签发给域名而不能签发给 IP 地址.下文以 aria2c.nota.moe 为例.

2018 年 1 月 7 日更新

是可以给裸 IP 签发 SSL 证书的,但 Let's Encrypt! 并不支持.事实上,只有极少数 CA 能提供这类证书.

SSL 证书自然选择 Let's Encrypt! 方案.证书签发工具我没有使用 certbot (因为似乎 certbot 验证域名所有权时要求域名必须运行 web 服务),而是使用 acme.sh (因为可以通过 TXT 解析记录验证域名).

安装 acme.sh:

curl  https://get.acme.sh | sh

如果没有自动添加 alias, 则运行:

alias acme.sh="~/.acme.sh/acme.sh"

然后需要验证域名,我们只能选择 TXT 解析记录的方式. acme.sh 支持大多数 DNS 的 API 服务,阅读文档详细了解: https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md. 以我使用的 CloudXNS 为例,运行:

export CX_Key=***
export CX_Secret=***
acme.sh --issue --dns dns_cx -d aria2c.nota.moe

这样即可完成域名验证和证书签发.

然后需要为 aria2c 安装证书.我建立了 aria2cert 目录用于存放证书(上边启动 aria2c 的脚本就是从这个目录读取证书的).运行:

acme.sh --installcert -d aria2c.nota.moe \
--certpath      /path/to/aria2cert/server.pem  \
--keypath       /path/to/aria2cert/server.key  \
--reloadcmd     "/path/to/aria2c_reload.sh"

会把签发的证书复制到 aria2cert 目录中,同时重新启动 aria2c.

acme.sh 是一个一劳永逸的工具,完成上述步骤后它会自动给证书续期,而且每次续期都会使用保存的 DNS API 信息,并按照初次安装证书时指定的证书目录和重启命令执行.

acme.sh 的文档:
https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E
https://github.com/Neilpang/acme.sh/blob/master/README.md

终于到了最后一步,配置 AriaNg. 从 AriaNg 的 GitHub 页面 下载到服务器上,放到 web 根目录. AriaNg 其实是纯粹的 HTML 单页应用,不需要 PHP 之类的东西.访问你的域名,看到 AriaNg 的主界面,然后点击 AriaNg 设置 -> RPC, 在下方填入相关信息.其中, "Aria2 RPC 主机" 应该填写为我们新注册的域名(比如 aria2c.nota.moe), 协议请务必选择 HTTPS 或 WSS. 刷新页面,查看 "Aria2 状态",如果一切操作无误的话,应该会显示"已连接".恭喜,现在你可以享受无比稳定的离线下载服务了!

按照我给出的 Caddyfile ,aria2 会直接把文件下载到你的在线文件管理器的根目录中.这样,我们就完美地实现了私人网盘的功能.

刚才我提到了上述一些操作是"匪夷所思"的,现在来解释下.我原来是直接把服务器的 IP 地址作为 RPC 地址使用的,这样存在一个严重问题: Caddy 默认使用 HTTPS (而且这也是大势所趋了),也就是说我们的 AriaNg 必定是 HTTPS 连接的;而我之前也提到了,裸 IP 是没法签发 SSL 证书的,那么我们让 HTTPS 下的 AriaNg 与 HTTP 下的 aria2 RPC 通讯,必定会触发浏览器的 mixed-content 警告,使得 AriaNg 完全没法工作(我看了控制台的错误信息, AriaNg 与 aria2 RPC 之间是 XHR 方式通讯).在绝大多数现代浏览器中都有这个限制.因此,为了让 AriaNg 正常工作,也为了提升安全性,我不得不为 RPC 单独设置一个域名,并为之签发 SSL 证书.

在这个过程中,我读了不少关于 aria2 前端的资料,很少有人提到 mixed-content 这个问题,希望我的上述文字能给你带来帮助. YAAW 也已经加入了 HTTPS 的支持,你也可以使用.

最终, NOTA.MOE 多了 3 个子域名,分别是:

dl.nota.moe    在线文件管理器
aria.nota.moe    AriaNg 前端
aria2c.nota.moe    aria2c RPC 接口

虽然有些令人迷惑,但好歹是自己亲手搭出来的网盘,用起来确实舒服(车技也大幅度提升了).

文章最后吐槽一下 ownCloud, 妈的,做得倒挺精致的,关键是屁事太多,安装过程中就状况连连,装完后第一次登陆,直接告诉我代码被篡改,自动刷新,我擦,进设置一看,一大堆警告,原来这玩意还有个代码签名校验,真他妈是食屎了,开源软件搞代码校验是怎么想的?而且一直告诉我缺少 .htaccess ,麻痹,劳资又没用 Apache, 哪来的 .htaccess ?登陆的时候还时不时来个 CSRF failed, 日,简直没法用.之后尝试的 Pydio 做工也太粗糙了,而且 url rewrite 在 Caddy 上始终有问题,也放弃了.不过最后自己捣鼓出来这么个玩意,也是很满意的了.

以上.

请继续阅读:解决从 Caddy 服务器下载文件时出现的网络错误.

13 thoughts on “使用 Caddy+AriaNg 搭建私人网盘

  1. aria2的配置
    # 启用加密后 RPC 服务需要使用 https 或者 wss 协议连接
    rpc-secure=true
    # 在 RPC 服务中启用 SSL/TLS 加密时的证书文件(.pem/.crt)
    rpc-certificate=/.caddy/acme/acme-v01.api.letsencrypt.org/sites/aria2.resnj.cf/aria2.resnj.cf.crt
    # 在 RPC 服务中启用 SSL/TLS 加密时的私钥文件(.key)
    rpc-private-key=/.caddy/acme/acme-v01.api.letsencrypt.org/sites/aria2.resnj.cf/aria2.resnj.cf.key

    caddy的配置
    aria2.resnj.cf {
    root /usr/local/caddy/www/aria2
    timeouts none
    gzip
    tls [email protected]
    log /tmp/aria2_access.log
    }

    aria2.resnj.cf域名用CDN解析到IP。

    目前可以访问aira2.resnj.cf,但是ariang的前端使用https连接后端中出了问题
    aria2 rpc地址是https://aria2.resnj.cf:6800/jsonrpc
    协议是https
    http请求方式是post
    密钥也无误。
    始终无法连接上后端

    麻烦给下处理提示?

    • 端口号正确吗?能 ping 通 aria2.xxx.xxx 吗?服务器上的 aria2 有报错信息吗?
      我不清楚是不是 cdn 导致的问题,但使用 cdn 没有必要.不知道你的 cdn 是用在 ariang 网页上还是 aria2c rpc 接口上?对于前者, ariang 是个单页应用,从第二次访问开始,每次加载时浏览器几乎不会向服务器请求页面内容(你可以看到开发者工具的抓包页面上写的全是 from disk cache);对于后者,每次请求返回的数据根本不是网页或其它任何静态资源.所以没有必要用 cdn.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注