Win10下使用Tor创建.onion域名网站的可行性分析笔记
我在发了
https://2049bbs.xyz/t/4017
这个帖子后,打算自己在电脑上搭建一个onion网站。
经过Google,发现都是在Linux下的。我不想重装系统,就测试下win10下的可能性。
第一步,我按照Linux的方法,修改torrc文件,重启tor,报错!
一头黑线。。。
想想也是,既然需要生成公钥和私钥,肯定需要openssl啊!我win10下没装openssl,当然会报错!
但是除了openssl,onion还需要什么呢?下次估计我就没有这么好运气能猜出来缺什么了
我当然知道你们Linux下工具都是齐全的,不像我是windows,需要自己安装开源工具加到path环境变量
张怀义 第二步,我开始看源码!为什么看源码?因为不看源码,我不知道缺什么东西!!!
C:\Users\张怀义\tor-alpha-3.04.1\src\feature\hs\hs_config.c
如果是版本2,看函数rend_config_service
如果是版本3,看函数config_service_v3
一头黑线。。。
默认是什么版本啊?算了,我强制用配置项设置为版本3吧,怎么想都是版本3更好一些
张怀义 被打脸了,不是缺少openssl造成的。。。
而且从代码看,使用的是椭圆曲线算法,而不是我以为的RSA算法
意外收获是这里居然还有DoS防御等相关代码,我继续研究下为什么win10无法创建onion
张怀义 第三步,根据第二步,我们知道了配置项有哪些。现在开始看服务具体做什么。
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发生了变化
张怀义 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站点是可行的!
张怀义 说了这么多,干脆把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相关代码!
张怀义 说了这么多,干脆把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相关代码!
张怀义 列个提纲:
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域名,如何访问的呢?
张怀义 参考资料: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了?
张怀义 以上就是onion地址如何工作的
张怀义 参考资料: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,作为对称加密的密钥
张怀义 参考资料: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 这个章节,客户端需要修改网桥为自定义网桥!!!
霏艺Faye图书管理员 后生可畏。。。
看了这么多?
张怀义 onion域名的官方文档规范V3
https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt
tor的资料很少有中文的,我都是在tor的wiki上自己大概翻译了一下
好像也没有翻译多少,更多是告诉大家,哪些是重点,没必要一行行去读了
邹韬奋虽然韬光养晦,亦当奋起而争(拜登永不为奴: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多此一举。
MrAnderson 草我以为张怀义复活了。
邹韬奋虽然韬光养晦,亦当奋起而争(拜登永不为奴: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 *