自建Tracker服务器

上次驯兽师联盟的一台做种服务器因为连接的Tracker被服务商认定为有害域名导致不少状况。为了更好的加快公网分发驯兽师联盟种子以及保护驯兽师联盟做种服务器的需要,于是打算自建Tracker服务器。

2020年3月22日注:
经一段时间的试运营后发现本Tracker项目性能较差,在每小时8万请求的情况下就已使得1C1G的服务器负载将近1以上。因此目前已换用Chihaya,Chihaya使用Golang编写,经测试在同等情况下服务器系统负载在0.1以下,完全凌驾在bittorrent-tracker项目之上。因此如果预计tracker的使用用户较多,建议使用Chihaya或Opentracker,稍后将提供Chihaya相关教程。
2020年2月22日注:
由于Tracker服务器被Github的某个TrackerList项目收录,导致访客激增。因此如果有意作为公共Tracker使用的话,建议设置较低的上报频率(默认上报间隔是600000,即10分钟),可以在运行命令中添加 --interval 1200000 (即20分钟上报一次)来提高上报时间间隔,可以根据实际需要设置更长的时间,但是如果仅仅是自用,则不需要设置过长的间隔,不然会影响做种效率。另外建议使用-q参数关闭Log输出,Log输出会严重影响Tracker的整体性能。

Tracker Server 软件

目前开源的Tracker Server 实现有不少,比较大众的是Opentracker,不过因为某些原因,我们放弃了这一项目。经过考量,决定使用另一个开源项目webtorrent/bittorrent-tracker ,该项目使用Node.js编写,比较易于部署,且支持HTTP(s)、UDP以及WebSocket等多种方式,同时支持IPV4和IPV6。

本文使用的操作系统为Ubuntu 18.04 LTS,其他操作系统的实现方式大致一致,只是安装Nodejs的方式略有不同(具体请自行查阅Nodejs官网获取相应的安装指南)。

由于该开源项目使用Nodejs编写,于是就必须先安装Nodejs及包管理器NPM

curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
sudo apt-get update
sudo apt-get install -y nodejs
sudo apt-get install npm

安装 bittorrent-tracker

npm install -g bittorrent-tracker

其中-g为全局安装,安装后可以使用以下命令直接运行

bittorrent-tracker

此时http、udp、websocket将会同时监听8000端口,在操作系统放通该端口即可运行。

以下为官方的-help指南

$ bittorrent-tracker --help
  bittorrent-tracker - Start a bittorrent tracker server

  Usage:
    bittorrent-tracker [OPTIONS]

  If no --http, --udp, or --ws option is supplied, all tracker types will be started.

  Options:
    -p, --port [number]  change the port [default: 8000]
        --trust-proxy    trust 'x-forwarded-for' header from reverse proxy
        --interval       client announce interval (ms) [default: 600000]
        --http           enable http server
        --udp            enable udp server
        --ws             enable websocket server
    -q, --quiet          only show error output
    -s, --silent         show no output
    -v, --version        print the current version

但是如此运行进程,进程会在Ctrl+C或者关闭SSH窗口后停止,虽然可以使用nohub来后台运行,为了长期运行以及出错自动重启,可以使用systemd来生成服务。

# 新建systemd配置文件,将以下代码一起复制到SSH运行
sudo cat > /lib/systemd/system/tracker.service <<EOF
[Unit]
Description=bittorrent-tracker server

[Service]
User=root
ExecStart=/usr/bin/bittorrent-tracker -p 8000
Restart=on-abort
LimitCORE=1000000
LimitNOFILE=1000000
LimitNPROC=1000000

[Install]
WantedBy=multi-user.target
EOF

# 以上为命令的全部内容

# 设置开机启动
sudo systemctl enable tracker
# 启动服务
sudo systemctl start tracker
# 查看服务状态
sudo systemctl status tracker
# 停止服务
sudo systemctl stop tracker
# 重启服务
sudo systemctl restart tracker

注:这里 -p 8000为端口号,可以根据自己需要修改。

使用Nginx反向代理同时开启HTTPS加密传输

虽然直接就能运行了,但是为了安全考虑,我们使用 Nginx 反向代理 HTTP 请求,同时使用 HTTPS 加密所有连接。

当然首先使用HTTPS加密就必须得要有一个域名和对应的证书,我一般用ACME.SH签发和续签免费的Let’s encrypt证书。下文中将以tracker.example.com代替我使用的域名。

首先安装 Nginx,为了使用TLS1.3等新特性,建议使用主线版本的NGINX,建议先更新系统软件

sudo apt-get update && sudo apt-get dist-upgrade -y

添加软件源

sudo apt-get install software-properties-common -y
sudo add-apt-repository ppa:ondrej/nginx-mainline -y

如果是国内主机,建议在添加源后使用USTC代理来解决连接过慢的问题

find /etc/apt/sources.list.d/ -type f -name "*.list" -exec  sed  -i.bak -r  's#deb(-src)?\s*http(s)?://ppa.launchpad.net#deb\1 https://launchpad.proxy.ustclug.org#ig' {} \;

更新并安装NGINX

sudo apt-get update
sudo apt-get install nginx -y

编辑NGINX配置文件

sudo vim /etc/nginx/sites-available/tracker
# 以下为配置文件的内容
server {
    listen *:443 ssl http2; # 监听IPV4端口
    listen [::]:443 ssl http2; # 监听IPV6端口
    ssl_certificate /etc/nginx/certs/example.com/fullchain;   #SSL证书
    ssl_certificate_key /etc/nginx/certs/example.com/key; #SSL密钥

    server_name tracker.example.com; # Tracker域名

    client_header_buffer_size 8k;
    client_max_body_size 68m;

    # 以下为HTTPS设置,强制开启HTTPS,这里设置已满足绝大多数BT客户端的要求
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_session_cache shared:le_nginx_SSL:1m;
    ssl_session_timeout 1440m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; # 如果Tracker域名的主域名有HTTP站点,请删除此行。
    add_header Referrer-Policy "origin";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";

    access_log /var/log/nginx/tracker.access.log;  # 访问日志
    error_log /var/log/nginx/tracker.error.log; # 错误日志

    root /var/www/html; # 站点目录(因为使用了反向代理所以这项其实是无效的)
    index index.html index.htm index.php;

    # 反向代理
    location / {
        proxy_pass http://127.0.0.1:8000; #这里8000对应tracker里设置的端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
	proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        add_header X-Cache $upstream_cache_status;
        add_header Cache-Control no-cache;
    }

    # 连接的种子及客户端统计(为了提升浏览体验,使用NGINX的sub_filter功能添加了部分HTML标签)
    location /stats {
	proxy_pass http://127.0.0.1:8000/stats; #这里8000对应tracker里设置的端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
	add_header Content-Type 'text/html; charset=utf-8';
        add_header X-Cache $upstream_cache_status;
        add_header Cache-Control no-cache;
	sub_filter '

' 'Tracker Stats

'; sub_filter '' ''; sub_filter_types *; sub_filter_once off; } # 连接的种子及客户端统计JSON版 location /stats.json { proxy_pass http://127.0.0.1:13000/stats.json; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header Content-Type 'text/json; charset=utf-8'; add_header X-Cache $upstream_cache_status; add_header Cache-Control no-cache; } } # 配置HTTP重定向至HTTPS server { return 301 https://$host$request_uri; listen 80; listen [::]:80; server_name tracker.example.com; } # 以上为配置文件的全部内容 # 修改完成后保存,并且使用以下命令启用配置 sudo ln -s /etc/nginx/sites-available/tracker /etc/nginx/sites-enabled/tracker # 检查配置是否正确 sudo nginx -t # 显示以下内容即说明正确 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

修改tracker服务的的systemd

sudo vim /lib/systemd/system/tracker.service
# 修改这一行
ExecStart=/usr/bin/bittorrent-tracker -p 8000
# 修改为
ExecStart=/usr/bin/bittorrent-tracker -p 8000 --trust-proxy --http --http-hostname 127.0.0.1
# 这里的意思是改成只使用http,且只监听本地环回IP(127.0.0.1),且接受NGINX转发的X-Forwarded-For里的IP(如果需要添加其他参数也可以在这一行添加),修改完成后保存。

配置完成后重启NGINX,并重载tracker服务的内容,最后重启tracker服务即可。

sudo systemctl restart nginx
sudo systemctl daemon-reload
sudo systemctl restart tracker

接入CloudFlare CDN

有时候出于安全和全球访问稳定性考虑,需要将服务器真实 IP 通过 CDN 隐藏起来,通过 CDN 转发所有请求到服务端。对于一般用户来说, Cloudflare 的免费套餐是一个好选择。但是 CDN 在转发请求时会导致 NGINX 将 CDN 服务器地址一并加入X-Forwarded-For字段转发给 Tracker 服务端,导致错误的记录。这时可以使用 NGINX 的 Realip 模块来将 CDN 的 IP 排除:

CloudFlare CDN的IP段来自:https://www.cloudflare.com/ips/

sudo vim /etc/nginx/sites-available/tracker
# 以下为配置文件的内容
server {
    listen *:443 ssl http2; # 监听IPV4端口
    listen [::]:443 ssl http2; # 监听IPV6端口
    ssl_certificate /etc/nginx/certs/example.com/fullchain;   #SSL证书
    ssl_certificate_key /etc/nginx/certs/example.com/key; #SSL密钥

    server_name tracker.example.com; # Tracker域名

    client_header_buffer_size 8k;
    client_max_body_size 68m;

    # 以下为HTTPS设置,强制开启HTTPS,这里设置已满足绝大多数BT客户端的要求
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_session_cache shared:le_nginx_SSL:1m;
    ssl_session_timeout 1440m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; # 如果Tracker域名的主域名有HTTP站点,请删除此行。
    add_header Referrer-Policy "origin";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";

    access_log /var/log/nginx/tracker.access.log;  # 访问日志
    error_log /var/log/nginx/tracker.error.log; # 错误日志

    root /var/www/html; # 站点目录(因为使用了反向代理所以这项其实是无效的)
    index index.html index.htm index.php;

    # 反向代理
    location / {
        #设置来自CDN的可信IP段,以Cloudflare为例
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        set_real_ip_from 104.16.0.0/12;
        set_real_ip_from 172.64.0.0/13;
        set_real_ip_from 131.0.72.0/22;
        set_real_ip_from 2400:cb00::/32;
        set_real_ip_from 2606:4700::/32;
        set_real_ip_from 2803:f800::/32;
        set_real_ip_from 2405:b500::/32;
        set_real_ip_from 2405:8100::/32;
        set_real_ip_from 2a06:98c0::/29;
        set_real_ip_from 2c0f:f248::/32;
        
        real_ip_header    X-Forwarded-For; #从X-Forwarded-For检索IP地址。
        real_ip_recursive on; #递归去除可信IP
        
        proxy_pass http://127.0.0.1:8000; #这里8000对应tracker里设置的端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
	proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        add_header X-Cache $upstream_cache_status;
        add_header Cache-Control no-cache;
    }

    # 连接的种子及客户端统计(为了提升浏览体验,使用NGINX的sub_filter功能添加了部分HTML标签)
    location /stats {
	proxy_pass http://127.0.0.1:8000/stats; #这里8000对应tracker里设置的端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
	add_header Content-Type 'text/html; charset=utf-8';
        add_header X-Cache $upstream_cache_status;
        add_header Cache-Control no-cache;
	sub_filter '

' 'Tracker Stats

'; sub_filter '' ''; sub_filter_types *; sub_filter_once off; } # 连接的种子及客户端统计JSON版 location /stats.json { proxy_pass http://127.0.0.1:13000/stats.json; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header Content-Type 'text/json; charset=utf-8'; add_header X-Cache $upstream_cache_status; add_header Cache-Control no-cache; } } # 配置HTTP重定向至HTTPS server { return 301 https://$host$request_uri; listen 80; listen [::]:80; server_name tracker.example.com; } # 以上为配置文件的全部内容 # 修改完成后保存并检查配置是否正确 sudo nginx -t # 显示以下内容即说明正确 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

配置完成后重启NGINX即可。

sudo systemctl restart nginx
点赞

发表评论

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