文章
技术

Win10下使用Tor创建.onion域名网站的可行性分析笔记

我在发了

https://2049bbs.xyz/t/4017

这个帖子后,打算自己在电脑上搭建一个onion网站。

经过Google,发现都是在Linux下的。我不想重装系统,就测试下win10下的可能性。

第一步,我按照Linux的方法,修改torrc文件,重启tor,报错!

一头黑线。。。

想想也是,既然需要生成公钥和私钥,肯定需要openssl啊!我win10下没装openssl,当然会报错!

但是除了openssl,onion还需要什么呢?下次估计我就没有这么好运气能猜出来缺什么了

我当然知道你们Linux下工具都是齐全的,不像我是windows,需要自己安装开源工具加到path环境变量

菜单
  1. 张怀义  

    第二步,我开始看源码!为什么看源码?因为不看源码,我不知道缺什么东西!!!

    C:\Users\张怀义\tor-alpha-3.04.1\src\feature\hs\hs_config.c

    如果是版本2,看函数rend_config_service

    如果是版本3,看函数config_service_v3

    一头黑线。。。

    默认是什么版本啊?算了,我强制用配置项设置为版本3吧,怎么想都是版本3更好一些

  2. 张怀义  

    第三步,根据第二步,我们知道了配置项有哪些。现在开始看服务具体做什么。

    C:\Users\张怀义\tor-alpha-3.04.1\src\feature\hs\hs_service.c

    hs_service_init 会new一个smartlist

    service_free_all会free刚才的smartlist

    hs_service_load_all_keys 加载或生成key

    我感觉我就是卡在上面这个函数

    hs_check_service_private_dir 创建目录并修改权限???Windows下这段代码是不是有问题,因为用户权限

    ed_key_init_from_file 这个应该会生成公钥和私钥,但是看源码,不是用的openssl,而是自己实现了!

    hs_build_address 会生成我们的onion地址

    write_address_to_file 最后写到网上说的两个文件,一个是公钥和私钥文件,一个是hostname文件

    load_client_keys载入代码,完成服务注册,注册服务代码是register_service

    hs_service_map_has_changed通知服务map发生了变化

  3. 张怀义  

    被打脸了,不是缺少openssl造成的。。。

    而且从代码看,使用的是椭圆曲线算法,而不是我以为的RSA算法

    意外收获是这里居然还有DoS防御等相关代码,我继续研究下为什么win10无法创建onion

  4. 张怀义  

    ed25519_keypair_generate生成了公钥和私钥的密钥对

    然后调用tor_cert_create传入刚才的公钥,得到证书

    TOR作者是真心大神中的大神啊,全能型天才啊

    先用ed25519_secret_key_generate产生了私钥

    再用ed25519_public_key_generate产生了公钥

    有两个实现impl_donna 或者 impl_ref10

    不管是哪个实现,我们只看ed25519_ref10_seckey_expand和ed25519_ref10_pubkey

    或者ed25519_donna_seckey_expand和ed25519_donna_pubkey

    我自己的理解,TOR的onion只需要做数字签名,不分发公钥,因为不需要交换AES密钥!

    所以在修改torrc的时候,增加一个User 你的用户名,就可以在windows下创建onion域名了

    到此,win10下,建立onion站点是可行的!

  5. 张怀义  

    说了这么多,干脆把TOR代码讲一遍好了。。。

    入口函数叫tor_run_main,在

    C:\Users\张怀义\tor-alpha-3.04.1\src\app\main\main.c

    C:\Users\张怀义\tor-alpha-3.04.1\src\app\main\subsystem_list.c 遍历这文件里所有的子系统,调用子系统的initialize函数和add_pubsub函数。和linux内核的子系统类似,使用了订阅发布模式,golang用的是CSP模型,这里是actor模型!

    我假设你们学过actor模型,现在只看mainloop_event_new和mainloop_event_postloop_new相关代码!

  6. 张怀义  

    列个提纲:

    TOR如何去连目录服务器?

    TOR如何建立环路?环路三要素【守卫节点】【中间节点】【出口节点】

    【可选】网桥是什么?meek,obfs4等

    onion站点,DNS处理逻辑

    自己喜欢的讲解内容方向

    1.TOR 启动监听端口9150 等【HS服务会启动其他端口】

    2.TOR的监听端口accept以后,通知readable,调用了read handle函数

    3.TOR的read以后,去调用对应的write handle

    4.把得到的数据,按link返回

    5.如果涉及到了onion域名,如何访问的呢?

  7. 张怀义  

    说了这么多,干脆把TOR代码讲一遍好了。。。

    入口函数叫tor_run_main,在

    C:\Users\张怀义\tor-alpha-3.04.1\src\app\main\main.c

    C:\Users\张怀义\tor-alpha-3.04.1\src\app\main\subsystem_list.c 遍历这文件里所有的子系统,调用子系统的initialize函数和add_pubsub函数。和linux内核的子系统类似,使用了订阅发布模式,golang用的是CSP模型,这里是actor模型!

    我假设你们学过actor模型,现在只看mainloop_event_new和mainloop_event_postloop_new相关代码!

  8. 张怀义  

    参考资料:https://tor.stackexchange.com/questions/672/how-do-onion-addresses-exactly-work

    1.服务器通过ed25519算法得到一对密钥【非对称加密算法】

    2.服务器随机选取n个tor节点作为介绍点

    3.服务器通过TOR回路,告诉这些节点自己的公钥【介绍点没法知道服务器地址】

    4.服务器把自己的公钥和这些介绍点打包成一个匿名服务描述符

    5.服务器用自己的私钥签名这个描述符

    6.服务器上传描述符到目录服务器【DHT】

    7.客户端,从其他途径知道了具体的onion地址

    8.客户端发送请求给DHT

    9.如果这个hash存在,返回服务器的公钥和介绍点IP

    10.客户端随机选择一个tor节点作为会和点,并告诉这个汇合点一次性密钥。

    11.客户端创建一个介绍信,包含汇合点的地址 和一次性密钥并用服务器的公钥加密

    12.客户端通过TOR回路,发给介绍点,并要求它转发给服务器【介绍点不能知道客户端地址,会和点IP】

    13.服务器收到介绍信,用自己的私钥解密,知道会和点地址和一次性密钥。

    14.服务器通过TOR回路,发送一次性密钥给会合点【汇合点即不知道客户端IP,也不知道服务器IP】

    15.汇合点告诉客户端,连接完成

    16.客户端和服务端可以互相通信了【一共6跳,服务器和客户端互相不知道对方的IP】

    思考题:如果介绍点都挂了,不在线怎么办?

    如果服务器重启的话,介绍点是不是就找不到服务器地址,需要重新生成.onion了?

  9. 张怀义  

    以上就是onion地址如何工作的

  10. 张怀义  

    参考资料:https://github.com/Yawning/obfs4/blob/master/doc/obfs4-spec.txt

    obfs4网桥协议规范

    重点看第四节和第五节,分别是握手阶段和传输阶段,整个过程类似TLS1.3协议,我不再啰嗦了

    大致过程讲下,

    客户端和服务端通过curve25519椭圆曲线算法,计算PSK得到对称密钥secretInput,

    通过HKDF 算法计算secretInput, 得到对称加密的密钥 记作sec_key,

    数据传输阶段,使用了secretbox加密,使用密钥 sec_key

    只需要看代码 https://github.com/Yawning/obfs4/blob/master/transports/obfs4/obfs4.go 就可以了

    从 newObfs4ClientConn函数看起,clientHandshake函数会发起握手

    hs.generateHandshake()生成握手请求,发送给服务端

    服务端收到请求hs.parseClientHandshake得到PSK 也就是seed

    okm := ntor.Kdf(seed, framing.KeyLength*2) 根据seed 计算HKDF,作为对称加密的密钥

    返回severhello,客户端解析n, seed, err := hs.parseServerHandshake(conn.receiveBuffer.Bytes()) 得到相同的seed,并和上面一样计算HKDF,作为对称加密的密钥

  11. 张怀义  

    参考资料:https://trac.torproject.org/projects/tor/wiki/doc/meek

    meek网桥协议规范

    大致原理讲下,通过CDN来隐藏自己的真实IP,用CDN来转发我的代理请求。在外界看来,就是普通的https浏览网页。

    重点看下Amazon CloudFront 这个章节,根据这个章节配置服务端

    ClientTransportPlugin meek exec ./meek-client --url=https://d111111abcdef8.cloudfront.net/ --front=d36cz9buwru1tt.cloudfront.net --log meek-client.log

    记得最后要执行这样的一句话!!!并把生成的meek 网桥信息,填入客户端,看 How to change the front domain 这个章节,客户端需要修改网桥为自定义网桥!!!

  12. 张怀义  

    @2read #11 谢谢,我在研究.onion的工作机制和相关代码实现而已,不需要自己发布一个网站

  13. 张怀义  

    onion域名的官方文档规范V3

    https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt

    tor的资料很少有中文的,我都是在tor的wiki上自己大概翻译了一下

    好像也没有翻译多少,更多是告诉大家,哪些是重点,没必要一行行去读了

  14. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    后生可畏。。。

    看了这么多?

  15. 张怀义  

    @立紗Lisa #16 谢谢lisa大神的夸奖!!!

  16. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)

    只要配置torrc加一个本地的webserver就可以了。

    HiddenServiceDir “用来放置key” HiddenServicePort 80 127.0.0.1:9001--用来把本地端口(这里是80)映射到TOR网络上

    有了这两个东西就可以了,如果你没有key,这样设置后,第一次运行TOR,TOR软件会自动算出hostname, public key 和secret key

    hostname是对外服务的onion name,例如本站是: terminus2xc2nnfk6ro5rmc5fu7lr5zm7n4ucpygvl5b6w6fqap6x2qd

    secret key是你的密钥,用来解开hostname的必备物品,删掉secret key之后你这个onion地址就报废了,没有人能够配置到这个onion地址来对外服务。

    本机可以用apache, nginx或者任意的http服务,注意不要https,Onion服务不需要https,onion自己就是强加密,再加个SSL多此一举。

  17. MrAnderson  

    草我以为张怀义复活了。

  18. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)

    TORRC file:

    # This file was generated by Tor; if you edit it, comments will not be preserved
    # The old torrc file was renamed to torrc.orig.1, and Tor will ignore it
    
    ClientOnionAuthDir *\Tor Browser\Browser\TorBrowser\Data\Tor\onion-auth
    ClientTransportPlugin meek_lite,obfs2,obfs3,obfs4,scramblesuit exec TorBrowser\Tor\PluggableTransports\obfs4pr
    ClientTransportPlugin snowflake exec TorBrowser\Tor\PluggableTransports\snowflake-client.exe -url https://snowflake-broker.torproject.net.global.prod.fastly.net/ -front cdn.sstatic.net -ice stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478
    DataDirectory *\Tor Browser\Browser\TorBrowser\Data\Tor
    GeoIPFile *\Tor Browser\Browser\TorBrowser\Data\Tor\geoip
    GeoIPv6File *\Tor Browser\Browser\TorBrowser\Data\Tor\geoip6
    HiddenServiceDir *
    HiddenServicePort 80 127.0.0.1:9001
    #Socks5Proxy *