如何让Tor流量走自建的链路


有个问题困扰了我很久,情景如下:

我们使用“嵌入”的方式在Tor启动前运行一段基于stem库Python代码,用于选择我们自主部署的节点并建立circuit,但在测试中发现,只要将Tor作为proxy并有流量传输时,Tor会自动建立新的链路用以中转流量,而我们自建的链路却始终被晾在一旁。

首先我在stem库中寻找方法,确实有将特定流量导入自定义链路的例子:https://stem.torproject.org/tutorials/to_russia_with_love.html#custom-path-selection

它的关键是配置了Tor的一个配置项__LeaveStreamsUnattached,如果该配置项设为1,除了被捕捉并导入到我们链路的数据流之外,其他数据流都会被丢弃。核心代码如下:

circuit_id = controller.new_circuit(path, await_build = True)

def attach_stream(stream):
  if stream.status == 'NEW':
    controller.attach_stream(stream.id, circuit_id)

controller.add_event_listener(attach_stream, stem.control.EventType.STREAM)

try:
  controller.set_conf('__LeaveStreamsUnattached', '1')  # leave stream management to us
    # 通过tor代理访问页面
  check_page = query('https://check.torproject.org/')
  ...
finally:
  controller.remove_event_listener(attach_stream)
  controller.reset_conf('__LeaveStreamsUnattached')

但是这样实现有很大的局限性,就是代理操作只能写死在python代码中,python代码运行完毕,add_event_listener也随即失效,用户通过将Tor设置为代理后产生的流量仍然不会导入自建链路。

于是我猜测可能是我们自主部署的节点的问题。

我们选节点构建链路有个原则,就是Guard和Exit必须是自主可控的,而我们自主部署的节点都没有配置ExitPolicy,也没有Exit这个标识符。很可能是这个原因,导致Tor的Path Selection Algorithm觉得链路的Exit节点不安全,所以直接选择新建一条安全链路来中转数据流。

根据这个猜想,我查了Tor节点获得Exit标识符的条件:

A router is called an ‘Exit’ iff it allows exits to at least two of the ports 80, 443, and 6667 and allows exits to at least one /8 address space.

所以我为每个节点都设置了ExitPolicy并修改了相应的端口(在torrc中):

DirPort 80
ORPort 443
ExitRelay 1
ExitPolicy reject 0.0.0.0/8:*
ExitPolicy reject 169.254.0.0/16:*
ExitPolicy reject 127.0.0.0/8:*
ExitPolicy reject 192.168.0.0/16:*
ExitPolicy reject 10.0.0.0/8:*
ExitPolicy reject 172.16.0.0/12:*
ExitPolicy accept *:20-21
ExitPolicy accept *:22
ExitPolicy accept *:23
ExitPolicy accept *:43
ExitPolicy accept *:53
ExitPolicy accept *:79
ExitPolicy accept *:80-81
ExitPolicy accept *:88
ExitPolicy accept *:110
ExitPolicy accept *:143
ExitPolicy accept *:194
ExitPolicy accept *:220
ExitPolicy accept *:389
ExitPolicy accept *:443
ExitPolicy accept *:464
ExitPolicy accept *:531
ExitPolicy accept *:543-544
ExitPolicy accept *:554
ExitPolicy accept *:563
ExitPolicy accept *:636
ExitPolicy accept *:706
ExitPolicy accept *:749
ExitPolicy accept *:853
ExitPolicy accept *:873
ExitPolicy accept *:902-904
ExitPolicy accept *:981
ExitPolicy accept *:989-990
ExitPolicy accept *:991
ExitPolicy accept *:992
ExitPolicy accept *:993
ExitPolicy accept *:994
ExitPolicy accept *:995
ExitPolicy accept *:1194
ExitPolicy accept *:1220
ExitPolicy accept *:1293
ExitPolicy accept *:1500
ExitPolicy accept *:1533
ExitPolicy accept *:1677
ExitPolicy accept *:1723
ExitPolicy accept *:1755
ExitPolicy accept *:1863
ExitPolicy accept *:2082
ExitPolicy accept *:2083
ExitPolicy accept *:2086-2087
ExitPolicy accept *:2095-2096
ExitPolicy accept *:2102-2104
ExitPolicy accept *:3128
ExitPolicy accept *:3389
ExitPolicy accept *:3690
ExitPolicy accept *:4321
ExitPolicy accept *:4643
ExitPolicy accept *:5050
ExitPolicy accept *:5190
ExitPolicy accept *:5222-5223
ExitPolicy accept *:5228
ExitPolicy accept *:5900
ExitPolicy accept *:6660-6669
ExitPolicy accept *:6679
ExitPolicy accept *:6697
ExitPolicy accept *:8000
ExitPolicy accept *:8008
ExitPolicy accept *:8074
ExitPolicy accept *:8080
ExitPolicy accept *:8082
ExitPolicy accept *:8087-8088
ExitPolicy accept *:8232-8233
ExitPolicy accept *:8332-8333
ExitPolicy accept *:8443
ExitPolicy accept *:8888
ExitPolicy accept *:9418
ExitPolicy accept *:9999
ExitPolicy accept *:10000
ExitPolicy accept *:11371
ExitPolicy accept *:19294
ExitPolicy accept *:19638
ExitPolicy accept *:50002
ExitPolicy accept *:64738
ExitPolicy reject *:*
RunAsDaemon 1

当然为了配置更安全的ExitPolicy可以参考如下四项配置:

  1. Passive ExitPolicy
  2. Browser Only ExitPolicy
  3. NON-EXIT (RELAY ONLY) Policy
  4. Bridge Only (Unlisted Bridge) Policy

配置完后等待一段时间,发现节点已经拥有Exit标识符,再次测试流量中转,发现流量已经可以正常走我们自建的链路,这也验证了我前面的猜想是正确的。

节点获得Exit标识符


文章作者: 玄霄
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 玄霄 !
评论
 上一篇
Tor Hidden Service原理初探 Tor Hidden Service原理初探
Tor开发了Hidden Service技术为暗网的实现提供了技术条件。本文将对Tor Hidden Service技术进行初步探索。
2019-12-05
下一篇 
Go基本语法 Go基本语法
变量声明声明变量一般使用var关键字,变量声明的标准格式如下: var name type // example var a,b *int Go 中变量的基本类型有: bool string int、int8、int16、int32、int
2019-09-29