ubuntu 18.04官方源的rTorrent 0.9.6会导致误报上传,故从源码编译0.9.7。

更新

20230320

自Ubuntu 20.04起,直接安装rtorrent即可:sudo apt install rtorrent

自2020年起,python2停止支持。不想在新系统装python2折腾依赖的可直接使用docker版pyrocore

pt客户端比较

qBittorrent

👍GUI实用美观
👍自带web ui且可设密码权限
👎体积稍大
👎内存占用稍高
👎无原生命令行控制
由上可知,qB更适合桌面图形环境使用。我的win10 htpc和笔记本装的就是它,必要时还可临时开启web界面远程控制。

Transmission

👍资源占用较低
👍Web Control使用方便(批量改tracker)
👎无法针对单种限流
👎辅种时无法跳过哈希校验
👎树莓派下transmission-daemon2.94带700+种子在公网IP改变情况下有机率崩溃
主要缺点还是只能全局限流,无法单种限流。

rTorrent

👍资源占用低
👍带800+占5T的种子运行稳定
👍辅种时可跳过哈希校验
👍第三方web界面ruTorrent操作方便(批量改tracker,批量限流)
👍配置选项多,可定制程度高
👎配置稍复杂

rtorrent

安装依赖

1
sudo apt-get install -y build-essential subversion autoconf screen g++ gcc ntp curl comerr-dev pkg-config cfv libtool libssl-dev libncurses5-dev ncurses-term libsigc++-2.0-dev libcppunit-dev libcurl4-openssl-dev git zlib1g-dev

编译安装xmlrpc-c

1
2
3
4
5
svn co https://svn.code.sf.net/p/xmlrpc-c/code/stable ~/src/xmlrpc-c
cd ~/src/xmlrpc-c
./configure --disable-libwww-client --disable-wininet-client --disable-abyss-server --disable-cgi-server
make -j4
sudo make install

编译安装libtorrent-0.13.7

这里有个坑,官方发布的包没有加入对openssl1.1的支持,需要根据这个commit手动打补丁。也可以在这里下载改好的2个文件

1
2
3
4
5
6
7
cd ~/src
curl http://rtorrent.net/downloads/libtorrent-0.13.7.tar.gz | tar xz
cd libtorrent-0.13.7
./autogen.sh
./configure
make -j4
sudo make install

编译安装rtorrent-0.9.7

1
2
3
4
5
6
7
8
cd ~/src
curl http://rtorrent.net/downloads/rtorrent-0.9.7.tar.gz | tar xz
cd rtorrent-0.9.7
./autogen.sh
./configure --with-xmlrpc-c
make -j4
sudo make install
sudo ldconfig

配置rtorrent

创建相关文件夹,注意按需修改路径和用户名,用户组。

1
2
sudo mkdir -p /path/to/pt/rtorrent/{log,.session,~watch}
sudo chown -R user:group /path/to/pt

修改~/.rtorrent.rc配置文件。一般来说,推荐先用默认配置,参数保守,若出了问题再微调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
### START of rtorrent.rc ###
method.insert = cfg.basedir, private|const|string, (cat,"/path/to/pt/rtorrent/")
method.insert = cfg.download, private|const|string, (cat,"/path/to/pt/")
method.insert = cfg.logs, private|const|string, (cat,(cfg.basedir),"log/")
method.insert = cfg.logfile, private|const|string, (cat,(cfg.logs),"rtorrent-",(system.time),".log")
method.insert = cfg.session, private|const|string, (cat,(cfg.basedir),".session/")
method.insert = cfg.watch, private|const|string, (cat,(cfg.basedir),"watch/")

execute.throw = sh, -c, (cat,\
"mkdir -p \"",(cfg.download),"\" ",\
"\"",(cfg.logs),"\" ",\
"\"",(cfg.session),"\" ",\
"\"",(cfg.watch),"/load\" ",\
"\"",(cfg.watch),"/start\" ")

network.port_range.set = 51400-51400
network.port_random.set = no

dht.mode.set = disable
protocol.pex.set = no

trackers.use_udp.set = no

protocol.encryption.set = allow_incoming,try_outgoing,enable_retry

pieces.preload.type.set = 2

session.path.set = (cat, (cfg.session))
directory.default.set = (cat, (cfg.download))
log.execute = (cat, (cfg.logs), "execute.log")
execute.nothrow = sh, -c, (cat, "echo >",\
(session.path), "rtorrent.pid", " ",(system.pid))

encoding.add = utf8
system.umask.set = 0022
system.cwd.set = (directory.default)

network.http.dns_cache_timeout.set = 25

schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))
pieces.hash.on_completion.set = no

network.http.ssl_verify_peer.set = 0

method.insert = system.startup_time, value|const, (system.time)
method.insert = d.data_path, simple,\
"if=(d.is_multi_file),\
(cat, (d.directory), /),\
(cat, (d.directory), /, (d.name))"
method.insert = d.session_file, simple, "cat=(session.path), (d.hash), .torrent"

schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "load/*.torrent")))

schedule2 = watch_start, 10, 10, ((load.start_verbose, (cat, (cfg.watch), "start/*.torrent")))

scgi_port = 127.0.0.1:5000

print = (cat, "Logging to ", (cfg.logfile))
log.open_file = "log", (cfg.logfile)
log.add_output = "info", "log"

schedule2 = session_save, 1200, 28800, ((session.save))

system.file.allocate.set = 1

### END of rtorrent.rc ###

我用来挂PT的机器是J1900+8G内存的ubuntu server,参考CONFIG-TemplatePerformance-Tuning稍作修改。注意按需修改路径和内存占用选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#############################################################################
# A minimal rTorrent configuration that provides the basic features
# you want to have in addition to the built-in defaults.
#
# See https://github.com/rakshasa/rtorrent/wiki/CONFIG-Template
# for an up-to-date version.
#############################################################################


## Instance layout (base paths)
method.insert = cfg.basedir, private|const|string, (cat,"/path/to/pt/rtorrent/")
method.insert = cfg.download, private|const|string, (cat,"/path/to/pt/")
method.insert = cfg.logs, private|const|string, (cat,(cfg.basedir),"log/")
method.insert = cfg.logfile, private|const|string, (cat,(cfg.logs),"rtorrent-",(system.time),".log")
method.insert = cfg.session, private|const|string, (cat,(cfg.basedir),".session/")
method.insert = cfg.watch, private|const|string, (cat,(cfg.basedir),"watch/")


## Create instance directories
execute.throw = sh, -c, (cat,\
"mkdir -p \"",(cfg.download),"\" ",\
"\"",(cfg.logs),"\" ",\
"\"",(cfg.session),"\" ",\
"\"",(cfg.watch),"/load\" ",\
"\"",(cfg.watch),"/start\" ")


## Listening port for incoming peer traffic (fixed; you can also randomize it)
network.port_range.set = 51400-51400
network.port_random.set = no


## Tracker-less torrent and UDP tracker support
## (conservative settings for 'private' trackers, change for 'public')
dht.mode.set = disable
protocol.pex.set = no

trackers.use_udp.set = no


## Peer settings
# Global upload and download rate in KiB, `0` for unlimited (`download_rate`, `upload_rate`)
throttle.global_down.max_rate.set_kb = 0
throttle.global_up.max_rate.set_kb = 0

# Maximum number of simultaneous downloads and uploads slots (global slots!) (`max_downloads_global`, `max_uploads_global`)
throttle.max_downloads.global.set = 300
throttle.max_uploads.global.set = 300

# Maximum and minimum number of peers to connect to per torrent while downloading (`min_peers`, `max_peers`) Default: `100` and `200` respectively
throttle.min_peers.normal.set = 99
throttle.max_peers.normal.set = 100

# Same as above but for seeding completed torrents (seeds per torrent), `-1` for same as downloading (`min_peers_seed`, `max_peers_seed`) Default: `-1` for both
throttle.min_peers.seed.set = -1
throttle.max_peers.seed.set = -1

# Maximum number of simultaneous downloads and uploads slots per torrent (`max_uploads`) Default: `50` for both
throttle.max_downloads.set = 50
throttle.max_uploads.set = 100

# Set the numwant field sent to the tracker, which indicates how many peers we want.
# A negative value disables this feature. Default: `-1` (`tracker_numwant`)
trackers.numwant.set = 100

protocol.encryption.set = allow_incoming,try_outgoing,enable_retry


## Limits for file handle resources, this is optimized for
## an `ulimit` of 1024 (a common default). You MUST leave
## a ceiling of handles reserved for rTorrent's internal needs!
network.http.max_open.set = 99
network.max_open_files.set = 600
network.max_open_sockets.set = 999

## Memory resource usage (increase if you have a large number of items loaded,
## and/or the available resources to spend)
pieces.memory.max.set = 4096M
# Max packet size using xmlrpc. Default: `524288` (xmlrpc_size_limit)
network.xmlrpc.size_limit.set = 4M

# Send and receive buffer size for socket. Disabled by default (`0`), this means the default is used by OS
# (you have to modify the system wide settings!) (`send_buffer_size`, `receive_buffer_size`)
# Increasing buffer sizes may help reduce disk seeking, connection polling as more data is buffered each time
# the socket is written to. It will result higher memory usage (not visible in rtorrent process!).
network.receive_buffer.size.set = 4M
network.send_buffer.size.set = 12M

# Preloading a piece of a file. Default: `0` Possible values: `0` (Off) , `1` (Madvise) , `2` (Direct paging).
pieces.preload.type.set = 2
#pieces.preload.min_size.set = 262144
#pieces.preload.min_rate.set = 5120

# TOS of peer connections. Default: `throughput`. If the option is set to `default` then the system default TOS
# is used. A hex value may be used for non-standard settings. (`tos`)
# Possible values: `[default|lowdelay|throughput|reliability|mincost]` or a hex value.
#network.tos.set = throughput


## Basic operational settings (no need to change these)
session.path.set = (cat, (cfg.session))
directory.default.set = (cat, (cfg.download))
log.execute = (cat, (cfg.logs), "execute.log")
#log.xmlrpc = (cat, (cfg.logs), "xmlrpc.log")
execute.nothrow = sh, -c, (cat, "echo >",\
(session.path), "rtorrent.pid", " ",(system.pid))


## Other operational settings (check & adapt)
encoding.add = utf8
system.umask.set = 0022
system.cwd.set = (directory.default)

# CURL option to lower DNS timeout. Default: `60`.
network.http.dns_cache_timeout.set = 25

schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))
pieces.hash.on_completion.set = no
#view.sort_current = seeding, greater=d.ratio=
#keys.layout.set = qwerty
#network.http.capath.set = "/etc/ssl/certs"

# CURL options to add support for nonofficial SSL trackers and peers
network.http.ssl_verify_peer.set = 0
#network.http.ssl_verify_host.set = 0


## Some additional values and commands
method.insert = system.startup_time, value|const, (system.time)
method.insert = d.data_path, simple,\
"if=(d.is_multi_file),\
(cat, (d.directory), /),\
(cat, (d.directory), /, (d.name))"
method.insert = d.session_file, simple, "cat=(session.path), (d.hash), .torrent"


## Watch directories (add more as you like, but use unique schedule names)
## Add torrent
schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "load/*.torrent")))
## Add & download straight away
schedule2 = watch_start, 10, 10, ((load.start_verbose, (cat, (cfg.watch), "start/*.torrent")))


## Run the rTorrent process as a daemon in the background
## (and control via XMLRPC sockets)
#system.daemon.set = true
#network.scgi.open_local = (cat,(session.path),rpc.socket)
#execute.nothrow = chmod,770,(cat,(session.path),rpc.socket)
scgi_port = 127.0.0.1:5000

## Logging:
## Levels = critical error warn notice info debug
## Groups = connection_* dht_* peer_* rpc_* storage_* thread_* tracker_* torrent_*
print = (cat, "Logging to ", (cfg.logfile))
log.open_file = "log", (cfg.logfile)
log.add_output = "info", "log"
#log.add_output = "tracker_debug", "log"


# Save all the sessions in every 8 hours instead of the default 20 minutes.
schedule2 = session_save, 1200, 28800, ((session.save))

# Prune file status in every 24 hours, this is the default setting.
#schedule2 = prune_file_status, 3600, 86400, ((system.file_status_cache.prune))

# Whether to allocate disk space for a new torrent. Default: `0`
system.file.allocate.set = 1


### END of rtorrent.rc ###

修改后运行rtorrent测试配置文件,无问题后Ctrl+Q退出。

设置服务开机运行

创建/etc/systemd/system/rtorrent.service。注意将/path/to/pt/改成rtorrent配置目录,另外若不是编译的位置可能不同(如/usr/bin/rtorrent),可通过which rtorrent确定路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description = rTorrent Daemon
After = network.target
After = mnt-downloads.mount

[Service]
Type=simple
KillMode=process
User=yourname
ExecStartPre=/bin/bash -c "if test -e /path/to/pt/rtorrent/.session/rtorrent.lock && test -z `pidof rtorrent`; then rm -f /path/to/pt/rtorrent/.session/rtorrent.lock; fi"
ExecStart=/usr/local/bin/rtorrent -o system.daemon.set=true
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

启用。

1
2
sudo systemctl enable rtorrent.service
sudo systemctl start rtorrent.service

另外官方文档有tmux的方案,好处是可以通过命令行交互,但在20.04下运行不稳定。

ruTorrent

安装配置apache

选择apache是因为其对SCGI的支持比较好,且个人网站没有处理高并发的需求,故没选Nginx。
安装依赖。

1
2
sudo apt-get install apache2 libapache2-mod-php7.2
sudo apt-get install php7.2-gd php7.2-json php7.2-curl php7.2-mbstring php7.2-intl php-imagick php7.2-xml php7.2-zip libapache2-mod-scgi

启用.htaccess。修改/etc/apache2/apache2.conf

1
2
<Directory /var/www/>
AllowOverride All

开启headers模块。

1
sudo a2enmod headers

复制默认https站点配置并在此基础上修改。

1
2
sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/example.com.conf
sudo vi /etc/apache2/sites-available/example.com.conf

设置HSTS。

1
2
3
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
</IfModule>

启动ssl,禁用默认站点,启用本站配置。

1
2
3
4
sudo a2enmod ssl
sudo a2ensite example.com.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2

修改php上传文件大小上限

以apache为例,修改/etc/php/7.2/apache2/php.ini

1
2
3
upload_max_filesize = 64M
max_file_uploads = 200
post_max_size = 128M

重启apache服务。

1
sudo service apache2 restart

安装web界面rutorrent

安装依赖。

1
sudo apt-get install zip unzip zlib1g-dev ffmpeg mediainfo unrar sox

下载ruTorrent并解压。
复制到网页文件夹并修改权限。

1
2
sudo cp -r ruTorrent /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com/ruTorrent

禁用不用的插件,修改ruTorrent/conf/plugins.ini

1
2
[_cloudflare]
enabled = no

启用访问密码。

1
sudo htpasswd -c /etc/apache2/.htpasswd yourname
1
2
sudo mv /var/www/example.com/ruTorrent/htaccess-example /var/www/example.com/ruTorrent/.htaccess
sudo vi /var/www/example.com/ruTorrent/.htaccess
1
2
3
4
AuthType Basic
AuthName "yourname"
AuthUserFile "/etc/apache2/.htpasswd"
require valid-user

通过samba共享下载文件夹

安装samba。

1
sudo apt-get install samba samba-common-bin

编辑/etc/samba/smb.conf

1
2
3
4
5
6
7
8
9
[pt]
Comment = pt download folder
Path = /path/to/pt
Browseable = yes
Writeable = Yes
only guest = no
create mask = 0775
directory mask = 0775
Public = yes

设置访问密码。

1
sudo smbpasswd -a yourname

重启服务。

1
sudo service smbd restart

pyrocore(可选)

强大的种子修改命令行工具集。需要python2的运行环境。

安装conda

1
2
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

改为国内源,修改~/.condarc

1
2
3
4
5
6
7
8
channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
- defaults

show_channel_urls: true

创建python2环境。

1
conda create -n py2 python=2

安装pyroscope

安装依赖和创建安装文件夹。

1
2
sudo apt-get install python python-dev python-virtualenv python-pip python-setuptools python-pkg-resources git build-essential
mkdir -p ~/bin ~/.local

修改~/.bashrc,末尾添加此句。

1
export PATH=$PATH:/home/yourname/bin

克隆源码,激活py2环境,安装。

1
2
3
git clone "https://github.com/pyroscope/pyrocore.git" ~/.local/pyroscope
source activate py2
~/.local/pyroscope/update-to-head.sh

运行pyroadmin --version以检查是否安装成功。

常用任务

批量改tracker

左下角Trackers栏右键需要更改的网站,选中所有该站种子后停止,编辑种子,在弹出的窗口中修改新网址保存即可。

辅种时跳过哈希校验

一般来说,添加种子时选中Fast resume即可跳过。但其使用的rtorrent_fast_resume.pl有Bug,如果有文件夹为纯数字则无法正常跳过校验。
这时就需要用到前面安装的pyroscope工具集中的chtor来制作可跳过检验的种子。以某个无法用perl脚本跳过的IMDB大包为例子:

1
chtor -H '/path/to/pt/movie/IMDb.2017.09.29.Top.250.BluRay.1080p.x265.10bit.MNHD-FRDS'  *.torrent -o ./new

上述命令将把工作目录下所有的种子添加校验部分,并在’new’文件夹下生成新种子。没有’-o’选项则会直接修改种子。由于是和指定路径下文件简单比较大小,故比计算哈希值快得多。

修改已制作种子校验值和tracker方便多站发布

1
chtor --reannounce-all=https://pt.site.com/announce.php *.torrent

上述命令将把工作目录下所有的种子更改tracker并修改哈希值以免pt软件认为是同样的种子,直接跳过而无法辅种。方便在多个站点同时发布种子而不用重复制作种子。

手动保存session信息

注意前面给出的配置文件中,为了避免频繁读取硬盘所以将保存session的间隔是设为8小时。但有时也会碰到刚下完种子没多久需要重启维护的情况,这时需要手动保存session信息以免丢失刚下的种子进度信息而需要重新校验。
通过tmux a -t rtorrent进入rtorrent界面。用Ctrl+x调出命令行,输入session.save=并回车(别漏了最后的等号),稍等即可完成保存session信息。

debug

Tracker: [Peer certificate cannot be authenticated with given CA certificates]

原因是该pt站的ssl证书有问题,想跳过检验可在配置文件’~/.rtorrent.rc’添加这句:

1
network.http.ssl_verify_peer.set = 0

No connection to rTorrent. Check if it is really running. Check $scgi_port and $scgi_host settings in config.php and scgi_port in rTorrent configuration file.

首先,运行tmux ls以确定rTorrent服务是否正常运行。若没有相关进程,则执行rtorrent并查看error信息。

rtorrent: Could not lock session directory

这种情况通常发生在rtorrent非正常退出的情况。比如通过rutorrent删除大种子及文件。解决办法:

1
2
3
cd /path/to/pt/rtorrent/.session
rm -rf rtorrent.lock
sudo systemctl restart rtorrent.service

删除内容较多的大种子建议先通过rutorrent仅删除种子,再通过sshsamba删除文件。