Avvolgere un socket SOCKS con TLS in Node.js
Avvolgi il flusso di destinazione restituito dal pacchetto socks con tls.connect e conserva il nome host del sito per SNI e la verifica del certificato.
SocksClient.createConnection restituisce un flusso connesso alla destinazione richiesta. Per HTTPS quel flusso ha ancora bisogno di un handshake TLS prima di trasportare la richiesta HTTP.
import { SocksClient } from 'socks';
import tls from 'node:tls';
const targetHost = 'service.example';
const info = await SocksClient.createConnection({
proxy: { host: 'proxy.example', port: 1080, type: 5 },
command: 'connect',
destination: { host: targetHost, port: 443 },
timeout: 10000,
});
const secure = tls.connect({
socket: info.socket,
servername: targetHost,
});
secure.on('error', onTransportError);
secure.on('data', onResponseBytes);
secure.once('secureConnect', () => {
secure.write(
`GET /data HTTP/1.1\r\nHost: ${targetHost}\r\nConnection: close\r\n\r\n`
);
});
L'elenco dei proxy SOCKS5 fornisce candidati per l'host e la porta del proxy. onTransportError e onResponseBytes appartengono all'applicazione esistente; il secondo deve analizzare il flusso di risposta HTTP. I blocchi di dati TLS non sono messaggi HTTP completi in modo autonomo.
Il servername è il nome DNS della destinazione. Il tls.connect di basso livello di Node non abilita SNI per impostazione predefinita, e il nome host del proxy non è l'identità del certificato del sito.
Lascia attiva la verifica del certificato. Fornire il socket connesso evita di aprire una connessione diretta separata verso il sito e ne preserva l'identità TLS.
Il timeout SOCKS limita quella negoziazione. Lo scambio TLS e applicativo successivo richiede comunque il timeout, la cancellazione e la politica di pulizia previsti dal chiamante.