TOR NEWNYM – автоматическая смена IP в TOR
Время от времени использую в качестве прокси сеть TOR, недавно вот пригодилось при проверке готовности загранпаспорта через интернет, когда постоянно получал ошибку о превышении числа запросов к серверу – пришлось сделать макрос на lynx, который через TOR периодически проверял готовность загранпаспорта (Автоматическая проверка готовности загранпаспорта). Удобство TOR не только в том, что это рабочий бесплатный прокси (с шифрованием трафика кстати) – TOR это сеть и прокси-серверы, а значит и IP-адреса, можно легко менять при необходимости, даже автоматически.
Под Windows сменить прокси и IP-адрес совершенно несложно – в составе дистрибутива TOR для Windows присутствует графическая оболочка Vidalia и для получения нового IP-адреса достаточно нажать в ней кнопку “Новый Ним / Новая личина / New NYM“. Под Linux всё не так очевидно, хотя тоже несложно, как выяснилось – сделать автоматическую смену IP в TOR можно при помощи простого скрипта.
Когда мне в очередной раз надо было поменять “ним” в TOR из-под Linux, я решил попробовать разобраться в вопросе, поскольку привычное /etc/init.d/tor restart перестало устраивать: во-первых нужно постоянно использовать root-доступ, во-вторых на время перезагрузки сервиса TOR он становится недоступен, а в-третьих – это просто как-то неправильно – перезагружать весь сервис ради получения новго IP-адреса.
Полез в документацию к TOR и выяснил, что демон может открывать управляющий порт, на который возможно подключение при помощи telnet с последующей отправкой команд демону TOR.
Смена НИМа / IP в TOR при помощи telnet
Чтобы передавать команды демону TOR (и в частности – команду на смену “нима”/IP-адреса), нужно раскомментировать в /etc/tor/torrc следующие строки:
## controller applications, as documented in control-spec.txt.
ControlPort 9051
После чего перезагружаем TOR, подключаемся к нему: telnet 127.0.0.1 9051, вводим команду AUTHENTICATE и затем signal NEWNYM. В Windwos действия по смене IP аналогичные (при создании скрипта для автоматической смены IP в TOR нужно помнить, что перевод строки для Windows будет выглядеть как \r\n). Дополнение из комментариев: после AUTHENTICATE нужно ввести команду SETEVENTS SIGNAL, чтобы демон кодом 650 сообщал о завершении смены цепочки серверов (и соответственно – IP-адреса. Команда работает с версии Tor 0.2.3.1-alpha, на более старых при необходимости контроля смены IP придется использовать внешние средства).
Несложно заметить, что способ не самый безопасный – подключиться может любой локальный пользователь. Конечно на домашней машине это не так страшно, но лучше сразу сделать правильно, без скидок на “тепличные условия”. Я выбрал вариант подключения к TOR с авторизацией по паролю (telnet-трафик впрочем никак не шифруется, так что под Windows вряд ли это вообще имеет смысл – практически всегда у пользователя там есть административные права, а значит и возможность использовать сниффер).
Для авторизации по паролю там же в torrc нужно сделать вот такие изменения:
## authentication methods, to prevent attackers from accessing it.
HashedControlPassword 16:B55A3F6B52F34E55609F6676DDBCEF4FD2BA7E318D9AF45AF878DB8A30
#CookieAuthentication 1
## Включение CookieAuthentication заставит tor создавать служебный файл,
## а подключаться на управляющий порт смогут только процессы, знающие содержимое этого файла.
Хэш-сумма пароля получается следующим образом: необходимо выполнить команду tor --hash-password 'new_tor_password' – в ответ получим сгенерированный хэш-код пароля
May 04 19:29:14.173 [notice] Tor v0.2.1.29 (r318f470bc5f2ad43). This is experimental software. Do not rely on it for strong anonymity. (Running on Linux i686)
16:B55A3F6B52F34E55609F6676DDBCEF4FD2BA7E318D9AF45AF878DB8A30
Теперь процесс подключения на управляющий порт TOR через telnet и получения нового “нима”/IP-адреса будет выглядеть следующим образом:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
AUTHENTICATE "new_tor_password"
250 OK
signal NEWNYM
250 OK
quit
А в случае использования Tor старше, чем 0.2.3.1-alpha, с применением SETEVENTS SIGNAL, смена цепочки серверов может выглядеть так:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
AUTHENTICATE "new_tor_password"
250 OK
SETEVENTS SIGNAL
250 OK
SIGNAL NEWNYM
250 OK
650 SIGNAL NEWNYM
quit
Строка 650 SIGNAL NEWNYM как раз и сообщает об успешном завершении смены сервера.
Shell скрипт для автоматической смены IP в TOR
Конечно, постоянно руками лазать и менять “ним” – не очень интересно. Упростить и автоматизировать этот процесс можно при помощи скрипта, выполнение которого в дальнейшем повесить например на alias для bash или кнопку-ярлык в Gnome. Скрипт использует утилиту для автоматизации интерактивных приложений expect (я воспользовался empty-expect чтобы не ставить еще и tcl вдобавок):
# Автоматическая смена НИМа в TOR
empty -f -i torin -o torout telnet 127.0.0.1 9051
empty -s -o torin "AUTHENTICATE \"new_tor_password\"\n"
empty -s -o torin "signal NEWNYM\n"
empty -s -o torin "quit\n"
Perl скрипты для автоматической смены IP в TOR
Такой же скрипт можно реализовать на Perl с использованием модуля Expect (поскольку лично у меня ни этот модуль, ни утилита empty в системе установлены не были – особой разницы, что поставить, нет):
# запуск команды в процессе-потомке
my $exp = Expect->spawn("telnet 127.0.0.1 9051");
# таймаут на отстутствие действий = 3 сек.
$exp->expect(3,
[ qr/Escape \s char .* \n/x => sub {
$exp->send('AUTHENTICATE "new_tor_password"'."\n");
exp_continue;
},
],
[ qr/250 \s OK/x => sub {
$exp->send("signal NEWNYM\n");
$exp->send("quit\n");
exp_continue;
},
],
);
Аналогичным образом можно воспользоваться например модулем Net::Telnet, который опять же не является core-модулем Perl, – он не тянет за собой никаких зависимостей, в отличает от Expect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | use Net::Telnet; my $tnet = Net::Telnet->new( # Host указывать не обязательно # по умолчанию исп. localhost Host => '127.0.0.1', Port => '9051', Timeout => 3, # Раскомментировать чтобы получать # сообщения на станд. вывод #Input_log => *STDOUT, #Output_log => *STDOUT, ); # Вариант первый - использовать методы print # (для отправки команд) и waitfor (для получения # ответов). $tnet->print(q/AUTHENTICATE "new_tor_password"/); $tnet->waitfor('/^ 250 \s OK $/x'); $tnet->print(q/signal NEWNYM/); $tnet->waitfor('/250 \s OK $/x'); $tnet->print(q/quit/); $tnet->waitfor('/250 \s closing \s connection $/x'); # Вариант второй - передавать команды каждый раз, # как получено приглашение на ввод (prompt). # Prompt можно определить при создании $tnet $tnet->prompt('//'); $tnet->cmd(q/AUTHENTICATE "new_tor_password"/); $tnet->cmd(q/signal NEWNYM/); $tnet->cmd(q/quit/); |
В качестве заключения – ссылка на (на английском), приведенная в комментариях к заметке.
Рубрики: Linux, Windows, Интернет |
Метки: how-to, linux, perl, proxy, tor |
7 комментариев
мая 5, 2011 | Автор: dimio 

Как по мне, вариант с Net::Telnet более очевиден.
Но есть одно НО: signal NEWNYM не меняет IP
Отдельно IP – не меняет. Он меняет сервер, в числе прочего меняется и IP при этом.
Не совсем то имел в виду.
Команда “SIGNAL NEWNYM” просто сообщает демону, что пора сменить сервер.
Демон сразу же выдаёт “250 OK”, сервер при этом остаётся тот же.
Вот и выходит, что до смены сервера десятки запросов могут уйти через старый шлюз.
Нашёл правильный алгоритм:
AUTHENTICATE
250 OK
SETEVENTS SIGNAL
250 OK
SIGNAL NEWNYM
250 OK
650 SIGNAL NEWNYM
То есть, нужно ждать ответа “650 SIGNAL NEWNYM”, который говорит о том, что новая цепочка создана. “SETEVENTS SIGNAL” нужен для включения асинхронных сообщений.
Исправьте, если не трудно.
Добавлю, только укажите пожалуйста версию tor, для которой это работает.
Например Tor v0.2.2.35 (git-73ff13ab3cc9570d) такого не умеет:
552 Unrecognized event "signal"
Тогда это проблема.
Раздел “4.1.17. Signal received”: [First added in 0.2.3.1-alpha]
У меня 0.2.3.11-alpha
Добавлю со ссылкой на версию в таком случае, вещь-то полезная.