Якщо потрібно виконувати HTTP-запити через мережу Tor із Java-застосунку, найкраще використовувати окремий системний сервіс Tor, а не Tor Browser. Системний Tor працює у фоновому режимі, підтримує SOCKS-проксі, ControlPort та дозволяє програмно змінювати IP-адресу за допомогою команди SIGNAL NEWNYM.
У цій інструкції розглянемо встановлення Tor на Ubuntu, налаштування SOCKS-проксі та інтеграцію зі Spring Boot через RestTemplate.
Встановлення Tor
Оновіть список пакетів та встановіть Tor:
sudo apt update
sudo apt install tor
Переконайтеся, що сервіс працює:
systemctl status tor
Якщо сервіс не запущений:
sudo systemctl start tor
sudo systemctl enable tor
Налаштування Tor
Основний файл конфігурації знаходиться за адресою:
/etc/tor/torrc
Додайте до нього наступні параметри:
# SOCKS-проксі
SocksPort 9052
# Порт керування
ControlPort 9051
# Використовуємо пароль
CookieAuthentication 0
HashedControlPassword 16:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
У цьому прикладі використовується порт 9052, щоб не конфліктувати з Tor Browser, який зазвичай займає порт 9150.
Створення пароля для ControlPort
Пароль зберігається у вигляді хешу.
Згенеруйте його командою:
tor --hash-password "myStrongPassword"
Приклад результату:
16:6D4A0E3F3A1E22A427ADFA1F79CC4721E8BCDC7B5D1A25D6A3E45
Скопіюйте отриманий рядок у параметр HashedControlPassword.
Перезапуск Tor
sudo systemctl restart tor
Перевірка відкритих портів
Переконайтеся, що Tor слухає потрібні порти.
ss -tln | grep 905
Приклад результату:
LISTEN 0 4096 127.0.0.1:9051
LISTEN 0 4096 127.0.0.1:9052
Перевірка ControlPort
Підключіться через telnet:
telnet 127.0.0.1 9051
Виконайте команди:
AUTHENTICATE "myStrongPassword"
SIGNAL NEWNYM
QUIT
У відповідь повинно бути:
250 OK
250 OK
Налаштування RestTemplate
Для роботи через Tor використовується Apache HttpClient.
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder)
throws Exception {
System.setProperty("socksProxyHost", "127.0.0.1");
System.setProperty("socksProxyPort", "9052");
System.setProperty("jdk.net.socks.allowRemoteResolve", "true");
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (certificate, authType) -> true)
.build();
SSLConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(
sslContext,
NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry =
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslSocketFactory)
.build();
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(registry);
CloseableHttpClient httpClient =
HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return builder
.requestFactory(() -> factory)
.build();
}
Перевірка роботи
Найпростіше перевірити IP-адресу через спеціальний сервіс.
String ip = restTemplate.getForObject(
"https://api.ipify.org",
String.class);
System.out.println(ip);
Якщо все налаштовано правильно, буде виведена IP-адреса вихідного вузла Tor, а не реальна адреса комп'ютера.
Програмна зміна IP
Tor дозволяє створити новий маршрут командою SIGNAL NEWNYM.
public void renewTorIp() throws IOException {
try (Socket socket = new Socket("127.0.0.1", 9051);
PrintWriter writer =
new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
writer.println("AUTHENTICATE \"myStrongPassword\"");
String response = reader.readLine();
if (!response.startsWith("250")) {
throw new IOException(response);
}
writer.println("SIGNAL NEWNYM");
response = reader.readLine();
if (!response.startsWith("250")) {
throw new IOException(response);
}
}
}
Особливості зміни IP
Команда SIGNAL NEWNYM не гарантує миттєву зміну IP. Tor лише повідомляється про необхідність побудувати новий маршрут. Якщо вже існують відкриті TCP-з'єднання, вони можуть продовжувати використовувати старий маршрут.
Якщо використовується PoolingHttpClientConnectionManager, після зміни IP бажано закрити існуючі з'єднання або створити новий екземпляр HttpClient, щоб наступний HTTP-запит відкрив нове з'єднання через новий Tor-ланцюг.
Поширені проблеми
Tor Browser не запускається.
Причина найчастіше полягає в конфлікті портів. Якщо системний Tor займає порт 9150, Tor Browser також намагатиметься використати його. Рекомендується використовувати інший SOCKS-порт для системного Tor, наприклад 9052.
RestTemplate використовує реальний IP.
Необхідно переконатися, що застосунок дійсно використовує SOCKS-проксі Tor. Для перевірки достатньо виконати запит до сервісу визначення IP.
Після SIGNAL NEWNYM IP не змінюється.
Найчастіше причина полягає у використанні пулу HTTP-з'єднань. Після зміни маршруту необхідно закрити існуючі з'єднання або створити новий HttpClient.
Комбінація системного Tor, ControlPort та RestTemplate забезпечує гнучке рішення для анонімного виконання HTTP-запитів і може бути інтегрована практично в будь-який Java-проєкт.
Коментарі
Дописати коментар