I'm starting to provide Chinese / English versions of some articles, switch with the Language menu above. 我开始提供部分文章的中文、英文翻译,请使用顶部语言菜单切换。

树莓派 3B 折腾笔记:BT 下载与策略路由

这次就直接进入正题。(其实是不知道该拿什么开头)

安装 Transmission 挂 PT

作为一个可以自由连接各种传感器的小型电脑,树莓派的可玩性相当高。即使你不想在 GPIO 上接一大堆传感器(或者像我一样觉得另外的传感器暂时没什么用),你也可以利用它低功耗的特点,让它 24 小时运行,做一些不需要大量 CPU 运算,但是因为其它因素需要较长时间才能完成的任务,例如…… 挂机下载。

我所在的大学有一个内网的 PT(Private Tracker)站。PT 站就是一个 BT 种子的发布网站,但是它在传统 BT 的基础上增加了用户管理功能,并且通过限制客户端种类、强制要求上传率等方式,解决了传统 BT 下各类客户端吸血(只下载不上传,例如迅雷)和种子很快失效(因为一段时间后就没人继续上传了)的问题。

但因为有了这些要求,PT 站用户往往需要长时间挂机上传下载,而这刚好是树莓派擅长的事。

上篇文章里,我弄好了一个简单的 NAS。在此基础上装一个 BT 下载软件就可以挂 PT 了。这个 PT 站在 Linux 下仅允许 Deluge,Rufus,Transmission 和 rTorrent。我一开始准备用 Deluge,但是 PT 站提示不允许使用 Raspbian 软件源内最新的 Deluge 1.3.13。该站推荐旧版本的 Deluge 1.3.3,可以在 Debian 7 软件源内找到,但是可能是因为 Debian 9 基于 systemd,我装上旧版后无法启动。

总之我选择了 Transmission。首先 apt-get:

apt-get install transmission-daemon

然后编辑 /etc/transmission-daemon/settings.json

# 屏蔽吸血客户端
"blocklist-enabled": true,
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
# 修改默认下载位置
"download-dir": "/mnt/usb/Transmission",
# 用 PT 站一定要把这几项都关掉,如果用传统 BT 这里不用改
"dht-enabled": false,
"lpd-enabled": false,
"pex-enabled": false,
# 远程 Web 管理
"rpc-enabled": true,
"rpc-authentication-required": true,
"rpc-username": "用户名",
"rpc-password": "密码,启动 Transmission 后会被自动加密",

最后 service transmission-daemon start 启动后,访问 [树莓派 IP]:9091 可以查看 Web 管理界面,可以上传种子、调整限速等。

针对学校网络环境的调整

上篇文章中我提到过,学校提供了一个有线网和两个 Wi-Fi,它们各自有如下特点:

  1. 有线网,限速 1.5M,网页方式登录,其它设备局域网内可访问
  2. 无线网,限速 1.5M,网页方式登录,其它设备若通过无线网连接则无法访问(Wi-Fi 设备隔离,通过有线网仍可访问)
  3. eduroam,不限速,WPA2 企业级登录,其它设备若通过无线网连接则无法访问(Wi-Fi 设备隔离,通过有线网仍可访问)

由于树莓派有一个有线网卡和一个无线网卡,因此最佳的方案是,树莓派平时通过 eduroam 进行 PT 下载,我用自己电脑访问树莓派有线网卡的 IP 进行管理和访问文件。

但是如果你直接把有线网和无线网都连上,你会发现只有一张网卡有流量,另外一张网卡甚至无法 ping 通。这是因为 Linux 内核在收到连接请求(例如 TCP SYN)时,并不是 “从哪来回哪去”,直接从连接请求来源网卡继续建立连接(TCP ACK)。相反,Linux 会根据内核的路由表来确定从哪张网卡回复。这样就会造成从有线网卡进入的请求被从无线网卡回复,然后回复因为设备隔离策略或是来源 IP 与网卡 IP 不符而被丢弃。

因此我们需要设置一下 Linux 的策略路由功能,做到 “从哪来回哪去”。策略路由可以指定符合某些条件的数据包(例如从某张网卡进入的数据包)不经主路由表处理,而是单独开一张路由表处理它。这个功能早在《OpenVZ 配置 Hurricane Electric IPv6 隧道,开启整个地址池并与原生 IPv6 共同使用》里我就用过了。虽然当时是用在了 IPv6 地址上,但是 Linux 下 IPv4 和 IPv6 的网络命令都大致相同,因此稍微改一下就可以使用。

首先输入 route 命令查看路由表,你会看到这样的输出:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.106.65.1     0.0.0.0         UG    202    0        0 eth0
default         10.107.128.1    0.0.0.0         UG    303    0        0 wlan0
10.106.65.0     0.0.0.0         255.255.255.0   U     400    0        0 eth0
10.107.128.0    0.0.0.0         255.255.240.0   U     303    0        0 wlan0

此处可以看到,有两条 Destination(目标)为 default(默认)的路由,一条对应有线网卡(eth0),一条对应无线网卡(wlan0)。它们的网关分别是 10.106.65.1 和 10.107.128.1,记录好它们。

再输入 ip addr 看一下现在的 IP。你会看到类似如下输出:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
   link/ether b8:27:eb:7c:5b:07 brd ff:ff:ff:ff:ff:ff
   inet 10.106.65.213/24 brd 10.106.65.255 scope global eth0
      valid_lft forever preferred_lft forever
   inet6 fe80::62f6:bc87:f1f5:533a/64 scope link
      valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
   link/ether b8:27:eb:29:0e:52 brd ff:ff:ff:ff:ff:ff
   inet 10.107.134.208/20 brd 10.107.143.255 scope global wlan0
      valid_lft forever preferred_lft forever
   inet6 fe80::f013:e96e:8451:7a94/64 scope link
      valid_lft forever preferred_lft forever

很长?其实重要的就几句话。我们只关心各张网卡的地址:

2: eth0: [...]
    inet 10.106.65.213/24 [...]
3: wlan0: [...]
    inet 10.107.134.208/20 [...]

这样就可以清楚地看到,有线网卡的地址是 10.106.65.213/24。因为 IPv4 的地址用 32 bit 表示,所以把最后(32-24=)8 bit 清零,获得 10.106.65.0/24。也就是说,你 DHCP 自动获取到的 IP 必然在 10.106.65.0/24 这个 IP 段以内。同理,无线网卡的地址是 10.107.134.208/20,清掉最后(32-20=)12 bit,获得 10.107.128.0/20。记好,等会也要用。

然后修改 /etc/iproute2/rt_tables,这里记录了路由表的列表,我们需要在这里加两张路由表,分别给两张网卡使用:

#
# reserved values
#
255    local
254    main
253    default
0    unspec
#
# local
#
#1    inr.ruhep

# 上面的都是 Raspbian 默认的设置,在文件末尾添加这两行:
100    university_eth
101    university_wlan

然后设置策略路由:

# 对于 university_eth 这张路由表,设置流量默认从 10.106.65.1(就是有线网卡的网关)走
ip route add default via 10.106.65.1 dev eth0 table university_eth
# 对于 university_wlan 这张路由表,设置默认走 10.107.128.1(无线网卡网关)
ip route add default via 10.107.128.1 dev wlan0 table university_wlan
# 对于来自 10.106.65.0/24(也就是刚才算出的有线网卡的 IP 段),走 university_eth 路由表
ip rule add from 10.106.65.0/24 table university_eth
# 对于来自 10.107.128.0/20(也就是刚才算出的无线网卡的 IP 段),走 university_wlan 路由表
ip rule add from 10.107.128.0/20 table university_wlan

输完这些命令,你的两张网卡就都能 ping 通了,“从哪来到哪去” 完工。你可以把上面这四条命令加入 /etc/rc.local 以开机自动设置。如果开机时没有生效,在四行命令上面再加一行 sleep 5 就可以了 —— 开机的时候有可能 Linux 网络功能还没启动完,因此先等 5 秒让网络功能启动了再继续设置。

最后一个问题,在同时连接了有线和无线的情况下,Linux 的 DHCP 客户端会给有线网卡设置更低的 Metric,使得流量优先从有线网卡走。Metric 就是 Linux 下每条路由的优先级,Metric 越低,优先级越高。但是我希望优先使用无线网卡,因此就要修改 DHCP 客户端的设置,给有线网卡更高的 Metric。

编辑 /etc/dhcpcd.conf

interface eth0    # 对于网卡 eth0(有线网卡)
metric 400        # 将它的 Metric 设置成 400(无线网卡默认是 303,任何比 303 大的数都可以)

保存重启,然后网络请求就都优先通过无线网卡发送了。

最终效果

树莓派下所有的下载软件均通过不限速的 eduroam Wi-Fi 进行下载。我用自己的电脑通过连接较慢的有线网卡的 IP 操作 SSH、Transmission,访问共享等,不影响 Wi-Fi 的传输速度,同时 1.5M 的限速也足以观看 1080p 分辨率的视频(特别高清的除外)。

树莓派 3B 折腾笔记
下一篇文章 »

本站使用运行在 Vercel 上的 Waline 评论系统,中国大陆访问可能不稳定。