Соединение 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.

Похожие статьи