2

我想让 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()
4

2 回答 2

1

我认为这是你的问题,但我可能错了。

您依靠猴子补丁socket.socket来强制HTTPConnection使用您的 SOCKS5 代理与 TOR 对话。但是HTTPConnection调用socket.create_connection,它会在调用创建套接字socket.getaddrinfo之前调用解析名称。socket.socket并且getaddrinfo不使用socket. 所以,它没有打补丁,所以它没有和你的 SOCKS5 代理对话,所以它使用你的默认名称解析器。

这对于代理与普通 Internet 主机的连接非常有效,因为 TOR 将为“my-ip.heroku.com”返回与您的普通名称解析器相同的 DNS 结果。但它不适用于“od6j46sy5zg7aqze.onion”,因为您的普通名称解析器中没有 .onion TLD。

如果您好奇,可以查看 、 和 的源代码HTTPConnection.connectsocket.create_connectionCgetaddrinfo中的最后一个,根据您的平台分散在整个模块中)。

那么,你如何解决这个问题?好吧,看看两个被调用的 SOCKS5 模块socks,一个有一个可以直接用猴子补丁代替的功能create_connection(它的 API 并不相同,但它已经足够HTTPConnection满足需要了);另一个没有,但你可以很容易地写一个(只需调用socks.socksocket然后调用它的connect方法)。或者你可以修改HTTPConnection创建一个socket.socket并调用它的connect方法。

最后,您可能想知道为什么大多数不同的socks模块都有一个setdefaultproxy函数,该函数带有一个名为的参数,该参数remote_dns专门声称它会导致远程执行 DNS 解析,而实际上这并不起作用。好吧,如果您使用 a ,它确实socks.socksocket有效,但如果您使用socket.getaddrinfo.

顺便说一句,如果您还没有阅读DnsResolverTorifyHOWTO,请在继续阅读之前阅读它们,因为只是试图将有效的代码拼凑在一起却不知道它为什么有效几乎肯定会导致您(或您的用户)在以下情况下泄露信息你以为你是匿名的。

于 2013-02-20T19:16:36.420 回答
0

您可以将端口 80 添加到洋葱地址以避免 DNS 查找。例如 readPage("od6j46sy5zg7aqze.onion:80")

使用 urllib2 您还需要指定协议(即 http),例如

导入 urllib2

打印 urllib2.urlopen(" http://od6j46sy5zg7aqze.onion:80 ").read()

于 2014-03-10T15:29:20.093 回答