Stay Hungry. Stay Foolish.

为什么我自建网盘和下载机

一个接一个国内网盘停止服务,以及百度云辣鸡的限速和8秒让我意识到,国内的网盘真的是越来越不安全和麻烦了,再加上本人木有钱续费辣鸡的迅雷会员了,(而且就算有睾贵的会员,某些你懂得资源也下不动了),于是试用了一圈网盘和下载机方案,包括但不限于 Owncloud,FileRun,BeDrive,Veno File Manager,Seafile,芒果云等等,玩了一圈,发现最合我意的是 NextCloud。

NextCloud 安装

Nextcloud 的安装可以说是非常的麻烦了,如果不是老司机的话很有可能被各种奇怪的错误给气死,这边介绍一种简单的安装方式。
系统还是以 Debian 9 为例。

Oneinstack 的安装

  • 首先先老规矩更新系统并安装一些必要软件
apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y
apt-get install curl vim wget git sudo unzip apt-transport-https screen lsb-release ca-certificates python python3 build-essential -y
  • 然后下载 oneinstack 并安装
git clone https://github.com/lj2007331/oneinstack.git
cd oneinstack && screen -S oneinstack

screen 会打开一个新的窗口,在这个窗口中的所有内容都可以在 ssh 退出后保存并通过 screen -r oneinstack 恢复
输入 ./install.sh 进行安装,安装的模块有,Nginx(不安装 ApacheTomcat),安装 Percona 5.7 数据库并选择 install from binary package,安装 php-7.1 以及 Zend OPcache 模块,安装 Redis 模块。

这个时候你就可以坐和放宽等待他安装完毕了。

添加 vhost 并安装 NextCloud

添加 vhost 完毕以后,我们进入到网站目录,假设你的域名是 pan.com,下载 NextCloud 并设置目录权限(非常重要)。

cd /data/wwwroot/pan.com/
wget -c https://download.nextcloud.com/server/releases/nextcloud-13.0.5.zip && unzip nextcloud-13.0.5.zip && rm nextcloud-13.0.5.zip && mv nextcloud/* ./
chown -R www.www /data/wwwroot/
find /data/wwwroot/ -type d -exec chmod 755 {} \;
find /data/wwwroot/ -type f -exec chmod 644 {} \;
  • 接着编辑 Nginx 的 vhost 配置文件
vim /usr/local/nginx/conf/vhost/pan.com.conf

参考配置如下,记得修改域名:

server {
    listen 443 ssl http2;
    ssl_certificate /etc/ssl/ssl.crt;
    ssl_certificate_key /etc/ssl/ssl.key;
    # ssl_dhparam /etc/ssl/dhparams.pem;
    ssl_protocols TLSv1.2;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 10m;
    ssl_session_cache builtin:1000 shared:SSL:10m;
    ssl_buffer_size 1400;

    server_name pan.com www.pan.com;
    access_log off;
    index index.html index.htm index.php;
    root /data/wwwroot/pan.com;
    if ($host != 'pan.com') { rewrite  ^/(.*)$  https://pan.com/$1 permanent; }
    include /usr/local/nginx/conf/rewrite/other.conf;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
    location = /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
    return 301 $scheme://$host/remote.php/dav;
    }
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
    location / {
    rewrite ^ /index.php$uri;
    }
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
    deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
    deny all;
    }
    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param modHeadersAvailable true;
    fastcgi_param front_controller_active true;
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    fastcgi_intercept_errors on;
    fastcgi_request_buffering off;
    include fastcgi.conf;
    }
    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
    try_files $uri/ =404;
    index index.php;
    }
    location ~ \.(?:css|js|woff|svg|gif)$ {
    try_files $uri /index.php$uri$is_args$args;
    add_header Cache-Control "public, max-age=15778463";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    access_log off;
    }
    location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
    try_files $uri /index.php$uri$is_args$args;
    access_log off;
    }
    location ~ [^/]\.php(/|$) {
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    }
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
    expires 30d;
    access_log off;
    }
    location ~ .*\.(js|css)?$ {
    expires 7d;
    access_log off;
    }
    location ~ /\.ht {
    deny all;
    }
}
server {
    server_name pan.com www.pan.com;
    server_tokens off;
    location / { return 301 https://pan.com$request_uri; }
}

然后需要修改 Opcache 的配置

vim /usr/local/php/etc/php.d/ext-opcache.ini

参考配置如下,最重要的是修改opcache.save_comments一项

php_flag opcache.enable 1
php_flag opcache.enable_cli 1
php_flag opcache.interned_strings_buffer 8
php_flag opcache.max_accelerated_files 10000
php_flag opcache.memory_consumption 128
php_flag opcache.save_comments 1
php_flag opcache.revalidate_freq 1

配置改好以后重启 php 和 nginx

service nginx restart && service php-fpm restart

装好了以后就可以进入 http://<yourip>/phpmyadmin/ 新建一个对应的数据库,然后就可以访问你的域名并且进行安装了。

Redis 缓存和 Cron 后台

Redis

Redis 缓存能显著提高运行效率,在配置文件 /data/wwwroot/pan.com/config/config.php 最后添加内容

'memcache.local' => '\OC\Memcache\Redis',
'redis' => array(
     'host' => 'localhost',
     'port' => 6379,
      ),
'memcache.locking' => '\OC\Memcache\Redis',

Cron 任务

NextCloud 默认采取的后台刷新模式是 Ajax 模式,也就是打开一次网页刷新一次,这显然是不合适的,所以我们

vi /etc/systemd/system/nextcloudcron.service
[Unit]
Description=Nextcloud cron.php job

[Service]
User=www
ExecStart=/usr/local/php/bin/php -f /data/wwwroot/pan.com/cron.php

[Install]
WantedBy=basic.target
vi /etc/systemd/system/nextcloudcron.timer
[Unit]
Description=Run Nextcloud cron.php every 15 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=nextcloudcron.service

[Install]
WantedBy=timers.target

然后启动 cron

systemctl enable nextcloudcron.timer
systemctl start nextcloudcron.timer

Aria2 安装和整合

Aria2 编译安装

  • 安装依赖
apt-get update && apt-get install libgnutls28-dev nettle-dev libgmp-dev libssh2-1-dev libc-ares-dev libxml2-dev zlib1g-dev libsqlite3-dev pkg-config libcppunit-dev autoconf automake autotools-dev autopoint libtool libxml2-dev make quilt -y
  • 下载源码
git clone https://github.com/aria2/aria2.git && cd aria2
quilt new 64Threads
quilt add ./src/OptionHandlerFactory.cc
sed -i s"/1\, 16\,/1\, 64\,/" ./src/OptionHandlerFactory.cc
  • 编译安装
autoreconf -i
./configure
screen make
cp ~/aria2/src/aria2c /usr/local/bin/
  • 创建配置文件
sudo mkdir /etc/aria2
sudo touch /etc/aria2/aria2.session
sudo chmod 777 /etc/aria2/aria2.session
sudo vi /etc/aria2/aria2.conf
  • 配置文件可以参考下面的配置
## 文件保存相关 ##
# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
# dir=/downloads
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=none
# 断点续传
continue=true
 
## 下载连接相关 ##
# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurent-downloads=10
# 同一服务器连接数, 添加时可指定, 默认:1
max-connection-per-server=10
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
split=20
# 整体下载速度限制, 运行时可修改, 默认:0
# max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
max-overall-upload-limit=1
# 单个任务上传速度限制, 默认:0
max-upload-limit=1
# 禁用IPv6, 默认:false
disable-ipv6=true

## 进度保存相关 ##
# 从会话文件中读取下载任务
input-file=/etc/aria2/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
save-session=/etc/aria2/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=60

## RPC相关设置 ##
# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
# event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
# rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
# rpc-secret=<TOKEN>
# 设置的RPC访问用户名, 此选项新版已废弃, 建议改用 --rpc-secret 选项
# rpc-user=<USER>
# 设置的RPC访问密码, 此选项新版已废弃, 建议改用 --rpc-secret 选项
# rpc-passwd=<PASSWD>

## BT/PT下载相关 ##

# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
# follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51200
# 单个种子最大连接数, 默认:55
# bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
enable-dht=true
# 打开IPv6 DHT功能, PT需要禁用
# enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
# dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
# bt-enable-lpd=true
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=true
# 每个种子限速, 对少种的PT很有用, 默认:50K
# bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.77
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=0.01
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
force-save=false
# BT校验相关, 默认:true
# bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=false
  • 创建启动脚本
vi /etc/init.d/aria2c

脚本内容如下:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          aria2
# Required-Start:    $remote_fs $network
# Required-Stop:     $remote_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Aria2 Downloader
### END INIT INFO

case "$1" in
start)

echo -n "Starting aria2c\n"
sudo -u www aria2c --conf-path=/etc/aria2/aria2.conf -D
;;
stop)

echo -n "Shutting down aria2c\n"
killall aria2c
;;
restart)

killall aria2c
sudo -u www aria2c --conf-path=/etc/aria2/aria2.conf -D
;;
esac
exit
  • 赋予脚本权限:
sudo chmod 755 /etc/init.d/aria2c
  • 启动、关闭、重启方式
sudo /etc/init.d/aria2c start
sudo /etc/init.d/aria2c stop
sudo /etc/init.d/aria2c restart

开机启动

sudo update-rc.d aria2c defaults

Aria2 与 NextCloud 整合

在 NextCloud 后台面板上搜索 OcDownloader 插件,默认就连接了 Aria2 可以用来下载 http(s)/ftp 链接和 BT 文件,但是我们这里不建议使用这个来下载 Bt 文件,一个是因为 ocDownloader 默认做种一星期才下载完毕,这显然太长了,第二个 Aria2 下载速度不是那么的快,所以下面就介绍一个专门用来 BT/磁力下载的软件。

Cloud Torrent 安装与整合

Cloud Torrent 就是我要介绍的专门下种子的软件啦。安装其实是非常方便的,直接使用官方提供的一键安装脚本就好啦。

curl https://i.jpillora.com/cloud-torrent! | bash

然后利用 systemd 来管理,创建一个脚本,具体内容自己修改一下:

vim /etc/systemd/system/cloud-torrent.service

脚本内容如下:

[Unit]
Description=cloud-torrent
[Service]
User=www
WorkingDirectory=/data/wwwroot/pan.com/data/<USERNAME>/files
ExecStart=/usr/local/bin/cloud-torrent --port <PORT> --config-path /root/cloud-torrent.json --title "Cloud Torrent" --log --auth "<USER>:<PASSWD>"
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
  • 然后就可以方便的使用啦:
启用:
systemctl enable cloud-torrent
开启、关闭、重启、查看状态
systemctl [start/stop/restart/status] cloud-torrent

但是你会发现,下载好的东西并没有进入 NextCloud 文件夹!即使我们把文件下载到了 NextCloud 存储目录下,这是因为 NextCloud 基于数据库存储,光把文件放在目录下是不行的,要把文件信息手动写入数据库。

手动多麻烦呀,我们可以写一个脚本自动写入文件到数据库。和 Nextcloud 的 cron 任务一样,创建定时任务,时间为一小时,可以适当增加时间间隔。

  • 创建脚本
vi /etc/systemd/system/cloudtorrentcron.service
[Unit]
Description=Nextcloud Cloud-Torrent job

[Service]
User=www
ExecStart=/usr/local/php/bin/php /data/wwwroot/pan.com/occ files:scan --all --quiet

[Install]
WantedBy=basic.target
  • 创建计时器
vi /etc/systemd/system/cloudtorrentcron.timer
[Unit]
Description=Run Nextcloud CloudTorrent every 60 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=60min
Unit=cloudtorrentcron.service

[Install]
WantedBy=timers.target
  • 启动任务
systemctl enable nextcloudcron.timer
systemctl start nextcloudcron.timer