17

示例代码:

#!/usr/bin/python
import socks
import socket
import urllib2

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, "127.0.0.1", 9050, True)
socket.socket = socks.socksocket

print urllib2.urlopen("http://almien.co.uk/m/tools/net/ip/").read()

TOR 在端口 9050(默认)上运行 SOCKS 代理。该请求通过 TOR,出现在我自己以外的 IP 地址上。但是,TOR 控制台会发出警告:

“Feb 28 22:44:26.233 [警告] 您的应用程序(使用 socks4 到端口 80)只给 Tor 一个 IP 地址。执行 DNS 解析的应用程序可能会泄漏信息。考虑使用 Socks4A(例如通过 privoxy 或 socat)。有关更多信息,请参阅 https://wiki.torproject.org/TheOnionRouter/TorFAQ#SOCKSAndDNS。”

即DNS 查找不通过代理。但这就是 setdefaultproxy 的第四个参数应该做的,对吧?

来自http://socksipy.sourceforge.net/readme.txt

setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])

rdns - 这是一个布尔标志,用于修改有关 DNS 解析的行为。如果设置为 True,DNS 解析将在服务器上远程执行。

选择 PROXY_TYPE_SOCKS4 和 PROXY_TYPE_SOCKS5 的效果相同。

它不能是本地 DNS 缓存(如果 urllib2 甚至支持它),因为它发生在我将 URL 更改为该计算机以前从未访问过的域时。

4

3 回答 3

21

问题是httplib.HTTPConnection使用socket模块的create_connection帮助函数,该函数getaddrinfo在连接套接字之前通过通常的方法进行 DNS 请求。

解决方案是创建自己的create_connection函数并在导入之前将其猴子修补到socket模块中urllib2,就像我们对socket类所做的那样。

import socks
import socket
def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)

# patch the socket module
socket.socket = socks.socksocket
socket.create_connection = create_connection

import urllib2

# Now you can go ahead and scrape those shady darknet .onion sites
于 2012-12-17T03:32:33.080 回答
5

问题是您urllib2在设置 socks 连接之前正在导入。

试试这个:

import socks
import socket

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, '127.0.0.1', 9050, True)
socket.socket = socks.socksocket

import urllib2
print urllib2.urlopen("http://almien.co.uk/m/tools/net/ip/").read()

手动请求示例:

进口袜子                                                         
导入网址解析                                                      

SOCKS_HOST = '本地主机'                                             
袜子端口 = 9050                                                    
SOCKS_TYPE = socks.PROXY_TYPE_SOCKS5                                 

url = 'http://www.whatismyip.com/automation/n09230945.asp'           
解析 = urlparse.urlparse(url)                                      


套接字 = socks.socksocket()                                          
socket.setproxy(SOCKS_TYPE, SOCKS_HOST, SOCKS_PORT)                  
socket.connect((parsed.netloc, 80))                                  
socket.send('''GET %(uri)s HTTP/1.1                                  
主机:%(主机)s                                                       
连接:关闭                                                    

''' % 字典(                                                          
    uri=parsed.path,                                                 
    主机=解析的.netloc,                                              
))                                                                   

打印 socket.recv(1024)                                              
socket.close()
于 2011-02-28T23:05:40.923 回答