Додайте TLS після того, як Perl відкрив з'єднання SOCKS
Накладіть IO::Socket::SSL на з'єднання IO::Socket::Socks і перевірте ім'я хоста призначення.
З'єднання SOCKS і з'єднання TLS виконують різні завдання. Спочатку отримайте потік байтів до призначення через SOCKS. Потім запустіть TLS поверх цього потоку, ідентифікуючи цільовий сайт, а не проксі.
Для кінцевої точки TLS у стилі HTTPS схема може бути такою:
use IO::Socket::Socks;
use IO::Socket::SSL;
my $target = 'example.com';
my $socket = IO::Socket::Socks->new(
SocksVersion => 5,
ProxyAddr => '127.0.0.1',
ProxyPort => 1080,
ConnectAddr => $target,
ConnectPort => 443,
) or die $!;
IO::Socket::SSL->start_SSL(
$socket,
SSL_hostname => $target,
SSL_verifycn_name => $target,
SSL_verifycn_scheme => 'http',
SSL_verify_mode => SSL_VERIFY_PEER,
) or die IO::Socket::SSL::errstr();
Для публічної цілі HTTPS на дозволеному маршруті публічного проксі список проксі SOCKS5 пропонує кандидатів для ProxyAddr і ProxyPort. Фрагмент вибудовує транспортні рівні; застосунок усе одно має надіслати протокол, якого очікує призначення, і закрити сокет після завершення.
Зберігайте передбачене ім'я вузла
Кінцева точка проксі належить першому з'єднанню. TLS SNI і перевірка імені хоста стосуються example.com. Використання імені хоста проксі на цьому етапі може запитати або перевірити неправильну ідентичність.
Налаштування сховища довіри — ще одна незалежна вимога. Використовуйте передбачену застосунком конфігурацію CA, а не скопійований із діагностичного прикладу зворотний виклик, що довіряє всьому.
Якщо крок SOCKS не вдався, зміна параметрів TLS це не виправить. Якщо SOCKS успішний, а TLS ні, збережіть помилку сертифіката та імені хоста як доказ, замість того щоб вважати це загальним збоєм проксі.
Імена модулів теж важливі: IO::Socket::Socks і IO::Socket::SSL надають різні конструктори та поведінку оновлення. Необроблений TCP-сокет, який лише досяг проксі, ще не завершив узгодження призначення SOCKS.