用Python连接.onion网络
我想让Python通过控制台访问.onion网站,下面的例子可以在Python中使用Tor,但当我尝试连接到.onion网站时,它会出现“名称或服务未知”的错误,我该怎么解决这个问题呢?
示例代码:
import socket
import socks
import httplib
def connectTor():
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5,"127.0.0.1",9050,True)
socket.socket = socks.socksocket
print "Connected to tor"
def newIdentity():
HOST = '127.0.0.1'
socks.setdefaultproxy()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,9051))
s.send("AUTHENTICATE\r\n")
response = s.recv(128)
if response.startswith("250"):
s.send("SIGNAL NEWNYM\r\n"),
s.close()
connectTor()
def readPage(page):
conn = httplib.HTTPConnection(page)
conn.request("GET","/")
response = conn.getresponse()
print (response.read())
def main():
connectTor()
print "Tor Ip Address :"
readPage("my-ip.heroku.com")
print "\n\n"
readPage("od6j46sy5zg7aqze.onion")
return 0
if __name__ == '__main__':
main()
2 个回答
你可以在洋葱地址后面加上80这个端口号,这样就可以避免进行DNS查找。
比如说,你可以这样写:readPage("od6j46sy5zg7aqze.onion:80")
如果你使用的是urllib2库,还需要指定协议,也就是http。
例如:
import urllib2
print urllib2.urlopen("http://od6j46sy5zg7aqze.onion:80").read()
我觉得这可能是你的问题,但我也可能错了。
你依赖于一种叫做“猴子补丁”的技术来修改 socket.socket
,目的是让 HTTPConnection
使用你的 SOCKS5 代理与 TOR 通信。但是 HTTPConnection
会调用 socket.create_connection
,而这个函数又会调用 socket.getaddrinfo
来解析名字,然后才会调用 socket.socket
来创建连接。而 getaddrinfo
并不使用 socket
,所以它没有被修改,因此它并没有通过你的 SOCKS5 代理进行通信,而是使用了你默认的名字解析器。
这样做对于普通的互联网主机代理连接是没问题的,因为 TOR 会返回和你正常名字解析器一样的 DNS 结果,比如“my-ip.heroku.com”。但对于“od6j46sy5zg7aqze.onion”就不行了,因为你的正常名字解析器没有 .onion 这个顶级域名。
如果你感兴趣,可以查看 HTTPConnection.connect
、socket.create_connection
和 getaddrinfo
的源码(最后一个是用 C 写的,具体内容会根据你的平台分散在模块中)。
那么,如何解决这个问题呢?看一下两个叫 socks
的 SOCKS5 模块,其中一个有一个函数可以直接替代 create_connection
(它的接口虽然不完全相同,但对 HTTPConnection
来说足够用了);另一个没有,但你可以很容易地写一个(只需调用 socks.socksocket
,然后调用它的 connect
方法)。或者你也可以修改 HTTPConnection
,让它创建一个 socket.socket
并调用它的 connect
方法。
最后,你可能会想知道为什么大多数不同的 socks
模块都有一个叫 setdefaultproxy
的函数,里面有一个名为 remote_dns
的参数,声称可以让 DNS 解析在远程进行,但实际上并不奏效。其实,如果你使用 socks.socksocket
,它是有效的,但如果你使用 socket.getaddrinfo
,就不可能有效。
顺便说一下,如果你还没读过 DnsResolver 和 TorifyHOWTO,在继续之前最好先读一下,因为仅仅试图拼凑出能工作的代码而不理解为什么它能工作,几乎肯定会导致你(或你的用户)在以为自己是匿名的情况下泄露信息。