28

I have the following script:

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket
import urllib2

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

which uses tor and SocksiPy

Now I want to change tor identity with each request, for example:

for i in range(0, 10):
   #somehow change tor identity
   print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

How can I do this?

nedim
  • 1,767
  • 1
  • 18
  • 20
user873286
  • 7,799
  • 7
  • 30
  • 38

7 Answers7

35

Tor wrote a new TOR control library in Python, stem. It can be found on PyPI. They provide some nice tutorials how to work with it, one of them explains how to change your identity:

from stem import Signal
from stem.control import Controller

with Controller.from_port(port = 9051) as controller:
  controller.authenticate()
  controller.signal(Signal.NEWNYM)

Make sure your config is correct.

OrangeTux
  • 11,142
  • 7
  • 48
  • 73
22

Today, I have searched a lot about this question, and finally managed to answer myself. But before I need to say that pirvoxy and tor should be configured correctly. First script, then a little bit about configuration:

import urllib2
from TorCtl import TorCtl

proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"})
opener = urllib2.build_opener(proxy_support) 

def newId():
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="your_password")
    conn.send_signal("NEWNYM")

for i in range(0, 10):
    print "case "+str(i+1)
    newId()
    proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"})
    urllib2.install_opener(opener)
    print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

Above script gets new IP and checks it from ifconfig.me web site. About configuration: We need Privoxy. to use TOR with HTTP connections, privoxy should work with tor. We can do it by adding thi to /etc/privoxy/config file:

forward-socks5 / localhost:9050 . #dot is important at the end

then we configure ControlPort in /etc/tor/torrc file. We need just uncomment this line:

ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C

then we just restart tor:

/etc/init.d/tor restart
user873286
  • 7,799
  • 7
  • 30
  • 38
  • Thank you for this solution but I have a small question: why do we need Privoxy here? Why can not I use SocksiPy as in your question? – Mik May 09 '12 at 18:06
  • 1
    I had problems which I also asked here: http://stackoverflow.com/questions/9925381/python-script-exception-with-tor – user873286 May 09 '12 at 18:29
  • @MikhailD There is no problem. For future readers: Just use SOCKS directly (without Privoxy). – Navin Dec 11 '13 at 07:29
  • What type of hash is used above? – Adrian B Mar 16 '14 at 14:51
  • 1
    Sorry for bumping this. For those searching for the hash password details, you can generate a different hash for a password different than `'your_password'` by executing the command `tor --hash-password ""` and noting the new hash from the resulting output. – shad0w_wa1k3r Nov 23 '15 at 15:52
15

Another simple solution, no external libraries required, works for both IPv4 and IPv6:

import socket

try:
    tor_c = socket.create_connection((TOR_CTRL_HOST, TOR_CTRL_PORT))
    tor_c.send('AUTHENTICATE "{}"\r\nSIGNAL NEWNYM\r\n'.format(TOR_CTRL_PWD))
    response = tor_c.recv(1024)
    if response != '250 OK\r\n250 OK\r\n':
        sys.stderr.write('Unexpected response from Tor control port: {}\n'.format(response))
except Exception, e:
    sys.stderr.write('Error connecting to Tor control port: {}\n'.format(repr(e)))
nedim
  • 1,767
  • 1
  • 18
  • 20
  • 2
    The socket class does have a connect() method that accepts a tuple, call socket.create_connection() instead. My code looks like tor_ctrl = socket.create_connection(('127.0.0.1', '9151')) tor_ctrl.send('AUTHENTICATE "{}"\r\nSIGNAL NEWNYM\r\n'.format('tor_control_pass')) # control password – mdubez Apr 20 '14 at 18:01
  • I have tried this but get this error: Error connecting to Tor control port: error(61, 'Connection refused'). Any ideas? – kflaw Jan 23 '17 at 08:17
  • I tried this and get following error--"Unexpected response from Tor control port: 515 Authentication failed: Password did not match HashedControlPassword *or* authentication cookie.". I type in the password as following format--"16:7FA1766AE1DC149A603309B1BF8EBBAAA3F44C237898EF82D19908BD9‌​2" – StereoMatching Jun 12 '17 at 16:47
  • I also tried this and getting `Error connecting to Tor control port: TypeError("a bytes-like object is required, not 'str'")` – Wildhammer May 13 '22 at 16:44
4

This is a video where im using STEM, SockSipy, Tor 100% working :)

#!/usr/bin/python
import socks
import socket
import time
from stem.control import Controller
from stem import Signal
import urllib2
import sys

def info():
    print "[*] Welcome to Chart-Cheat Script"
    print "[*] This script works with running TOR only"
    print "[*] usage is chartcheat.py domain"
    print "[*] argument domain must be in format www.example.com"
    print "[*] Example: chartcheat.py www.example.com"
    return

if len(sys.argv)==2:
    info();
    counter = 0
    url = str(sys.argv[1]);
    with Controller.from_port(port = 9051) as controller:
        controller.authenticate()
        socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
        socket.socket = socks.socksocket
        #visiting url in infinite loop      
        while True:
            urllib2.urlopen("http://"+url)
            counter=counter+1
            print "Page " + url + " visited = " + str(counter)
            #wait till next identity will be available
            controller.signal(Signal.NEWNYM)
            time.sleep(controller.get_newnym_wait())            
else:
    info();

In case you are running python3, urllib package in python3 will be the same as urllib2 package in python2.

anonymous
  • 1,372
  • 1
  • 17
  • 22
Edgar
  • 51
  • 1
0

You can enable tor control server by uncommenting few lines in

/etc/tor/torrc

And use stem library to send NEWNYM signal to change circuit.

controller.signal(Signal.NEWNYM)

You can read tutorial here.

shicky
  • 1,193
  • 14
  • 21
0

you can write something like this :

def renew_connection():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='password')
        controller.signal(Signal.NEWNYM)
        controller.close()

def request_tor(url, headers):
    renew_connection()
    session = requests.session()
    session.proxies = {}
    session.proxies['http'] = 'socks5h://localhost:9050'
    print((session.get(url)).text)

Lashgari
  • 41
  • 11
  • Could you help to make this answer more useful by clarifying on why this would fix the issue? – Simas Joneliunas Jul 12 '21 at 00:46
  • Each time you send a new request, the signal gives you a new ip and after every 4 seconds you can add a time.sleep(4) to have a new ip for each request and you can use the fake_useragent library to create fake agents for you randomly. @SimasJoneliunas – Lashgari Jul 12 '21 at 05:01
-2

The following could work:

for i in range(0, 10):
   #somehow change tor identity
   socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050+i)
   socket.socket = socks.socksocket

   print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

You basically set set the proxy prior to making each connection. I am asuming that you have different proxies for different IPs since you have not stated how you intend to change the IP

plaisthos
  • 6,255
  • 6
  • 35
  • 63
  • I just want to make request with different IP using tor, I mean in random time interval, I need to use changeTorIdentity() function. I need this changeTorIdentity() function. – user873286 Mar 29 '12 at 15:08