平时在动漫花园等 BT 站用磁力链接下资源时总是遇到因为所有 Tracker 服务器都连不上而需要等待很久才能开始下载的情况,就萌生了自己搭建 Tracker 服务器念头。
Tracker Server
首先准备 Linux Server 一台,本文中使用的系统为 Ubuntu 16.04。
网上开源的 Tracker Server 实现有不少,经过对比,我们采用 bittorrent-tracker 这一项目作为我们的服务端。因为其同时支持 IPv4 和 IPv6 和 http、udp、websocket 等多种上报方式,且部署简单。
首先安装 nodejs 和包管理器 npm:
1 2 3
| $curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash - $sudo apt-get install -y nodejs $sudo apt-get install npm
|
安装 bittorrent-tracker:
1
| $npm install -g bittorrent-tracker
|
若只想搭建一个简单的 tracker,安装完毕后运行$bittorrent-tracker
即可开始使用,更多参数请自行探索。
TLS over nginx
个人比较常用 http 向 tracker 进行上报,但是现在已经到了 8102 年末了,http 这种明文协议不应该成为我们的选择。
所以我们使用 nginx 进行反向代理来反代 http 请求,同时使用 TLS 加密所有连接。
当然首先你需要有一个域名和对应的证书,推荐使用 Let’s encrypt 的免费证书。我使用它们家的证书 bot 来自动签发和管理 nginx 配置文件 TLS 部分内容。为了便于说明,下文中以TRACKER_DOMAIN
替代我使用的域名。
首先安装 nginx,因为后续需要使用一些特性,我们安装完整版的 nginx:
1
| $sudo apt install nginx-full
|
编辑 nginx 配置文件:
1
| $sudo vim /etc/nginx/sites-enabled/tracker
|
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
| server { server_name TRACKER_DOMAIN;#监听域名 #同时监听ipv4和ipv6 listen 443 ssl; listen [::]:443 ssl; root /var/www/tracker;
location / {
proxy_pass http://127.0.0.1:8000/; #8000为bittorrent-tracker默认端口,请根据自己设置修改 proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #以下为 Let's encrypt certbot 自行配置完成,请根据证书情况自行修改 ssl_certificate /etc/letsencrypt/live/TRACKER_DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/TRACKER_DOMAIN/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
} # 配置http端口重定向至https server { if ($host = TRACKER_DOMAIN) { return 301 https://$host$request_uri; }
listen 80; listen [::]:80; server_name TRACKER_DOMAIN; return 404; }
|
配置完成后重启 nginx,并启动 bittorrent-tracker 即可:
1 2
| $service nginx restart $bittorrent-tracker -p 8000 --trust-proxy --http --http-hostname 127.0.0.1
|
注意因为 http 请求由 nginx 处理,所以服务端仅需要监听在127.0.0.1
即可。--trust-proxy
参数必须打开,用于保证服务端从X-Forwarded-For
字段获取客户端真实IP。
CDN Support
有时候出于安全和全球访问稳定性考虑,需要将服务器真实 IP 通过 CDN 隐藏起来,通过 CDN 转发所有请求到服务端。对于一般用户来说, Cloudflare 的免费套餐是一个好选择。但是 CDN 在转发请求时会导致 nginx 将 CDN 服务器地址一并加入X-Forwarded-For
字段转发给 Tracker 服务端,导致错误的记录。这需要使用 nginx 的 Realip 模块来将 CDN 的 IP 排除:
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
| server { server_name TRACKER_DOMAIN;#监听域名 #同时监听ipv4和ipv6 listen 443 ssl; listen [::]:443 ssl; root /var/www/tracker;
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 2405:b500::/32; set_real_ip_from 2606:4700::/32; set_real_ip_from 2803:f800::/32; set_real_ip_from 2c0f:f248::/32; set_real_ip_from 2a06:98c0::/29;
real_ip_header X-Forwarded-For; #从X-Forwarded-For检索IP地址。 real_ip_recursive on; #递归去除可信IP
proxy_pass http://127.0.0.1:8000/; #8000为bittorrent-tracker默认端口,请根据自己设置修改 proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #以下为 Let's encrypt certbot 自行配置完成,请根据证书情况自行修改 ssl_certificate /etc/letsencrypt/live/TRACKER_DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/TRACKER_DOMAIN/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
} # 配置http端口重定向至https server { if ($host = TRACKER_DOMAIN) { return 301 https://$host$request_uri; }
listen 80; listen [::]:80; server_name TRACKER_DOMAIN; return 404; }
|