How to change Tor identity in Python?

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.


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

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)))

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.