A conexão SOCKS e a conexão TLS têm funções diferentes. Primeiro obtenha um fluxo de bytes até o destino por meio do SOCKS. Depois inicie o TLS sobre esse fluxo, identificando o site de destino e não o proxy.

Para um endpoint TLS no estilo HTTPS, a disposição pode ser:

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

Para um alvo HTTPS público em uma rota de proxy público permitida, a lista de proxies SOCKS5 oferece candidatos para ProxyAddr e ProxyPort. O trecho estabelece as camadas de transporte; a aplicação ainda precisa enviar o protocolo esperado pelo destino e fechar o socket ao terminar.

Mantenha o nome de par pretendido

O endpoint do proxy pertence à primeira conexão. O SNI do TLS e a verificação do nome do host dizem respeito a example.com. Usar o nome do host do proxy nessa etapa pode solicitar ou verificar uma identidade errada.

A configuração do armazenamento de confiança é outro requisito independente. Use a configuração de CA pretendida pela aplicação em vez de um callback que confia em tudo, copiado de um exemplo de diagnóstico.

Se a etapa SOCKS falhar, alterar parâmetros de TLS não resolverá. Se o SOCKS funcionar e o TLS falhar, guarde o erro de certificado e de nome do host como evidência em vez de tratá-lo como uma falha genérica do proxy.

Os nomes dos módulos também importam: IO::Socket::Socks e IO::Socket::SSL expõem construtores e comportamentos de atualização diferentes. Um socket TCP bruto que apenas alcançou o proxy ainda não concluiu a negociação de destino do SOCKS.

Artigos relacionados