تغليف مقبس SOCKS بـ TLS في Node.js
غلّف تدفق الوجهة الذي تعيده حزمة socks باستخدام tls.connect واحتفظ باسم مضيف الموقع من أجل SNI والتحقق من الشهادة.
تعيد SocksClient.createConnection تدفقًا متصلًا بالوجهة المطلوبة. أما في HTTPS فيظل ذلك التدفق بحاجة إلى مصافحة TLS قبل أن يحمل طلب 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`
);
});
توفّر قائمة وكلاء SOCKS5 مرشحين لمضيف الوكيل ومنفذه. تنتمي onTransportError و onResponseBytes إلى التطبيق القائم، ويحتاج الثاني إلى تحليل تدفق استجابة HTTP. قطع بيانات TLS ليست رسائل HTTP كاملة بشكل مستقل.
servername هو اسم DNS الخاص بالوجهة. ولا يفعّل tls.connect منخفض المستوى في Node خاصية SNI افتراضيًا، كما أن اسم مضيف الوكيل ليس هوية شهادة الموقع.
أبقِ التحقق من الشهادة مفعّلًا. فتقديم المقبس المتصل يتجنب فتح اتصال مباشر منفصل بالموقع مع الحفاظ على هويته في TLS.
يحدّ مهلة SOCKS من تلك المفاوضة. أما تبادل TLS والتطبيق اللاحق فيحتاج إلى المهلة والإلغاء وسياسة التنظيف المقصودة لدى المستدعي.