Kembali ke blog

WebSocket melalui proxy: panduan lengkap untuk pemrosesan koneksi WS dan WSS

Koneksi WebSocket bekerja berbeda dari permintaan HTTP biasa — dan proxy standar sering memutuskan mereka. Kami membahas cara yang benar untuk memproxy lalu lintas WS dan WSS tanpa kehilangan koneksi.

📅7 Agustus 2026
```html

WebSocket bukanlah permintaan HTTP biasa. Setelah "jabat tangan" awal (handshake), koneksi tetap terbuka, dan data mengalir dua arah secara terus-menerus. Itulah sebabnya proxy HTTP standar sering memutuskan koneksi WS atau bahkan tidak dapat memprosesnya sama sekali. Dalam artikel ini, kita akan membahas cara yang benar untuk memproxy trafik WebSocket: jenis proxy yang sesuai, cara mengaturnya, dan kesalahan yang paling umum terjadi.

Cara kerja WebSocket dan mengapa sulit untuk proxy

Untuk memahami masalahnya, kita perlu memahami mekanismenya. Koneksi WebSocket dimulai seperti permintaan HTTP biasa — klien mengirimkan header Upgrade: websocket dan Connection: Upgrade. Server merespons dengan kode 101 Switching Protocols — dan sejak saat itu koneksi tidak lagi menjadi HTTP. Ini berubah menjadi saluran dua arah yang permanen, di mana data mengalir dalam bingkai.

Proxy HTTP/1.1 standar, yang hanya dapat meneruskan permintaan dan respons, menghadapi masalah: ia tidak tahu apa yang harus dilakukan dengan koneksi setelah respons 101. Banyak server proxy hanya menutup koneksi pada saat itu atau mengembalikan kesalahan 502 Bad Gateway. Yang lain mempertahankan koneksi, tetapi tidak dapat meneruskan bingkai WebSocket dengan benar, yang menyebabkan pemutusan atau distorsi data.

Berikut adalah perbedaan kunci antara WebSocket dan HTTP biasa dari sudut pandang proxy:

Parameter HTTP WebSocket
Tipe koneksi Permintaan → Respons → Penutupan Permanen, dua arah
Waktu hidup Detik (satu permintaan) Menit, jam, hari
Inisiator data Hanya klien Klien dan server
Protokol setelah handshake HTTP Khusus (RFC 6455)
Port 80, 443 80 (WS), 443 (WSS)

Karena perubahan protokol setelah handshake, sebagian besar solusi proxy sederhana tidak dapat menangani WebSocket. Anda perlu menggunakan proxy yang secara eksplisit mendukung tunneling atau menggunakan SOCKS5 — protokol yang bekerja pada tingkat yang lebih rendah dan tidak menganalisis konten trafik.

Jenis proxy apa yang mendukung WebSocket

Tidak semua proxy sama bergunanya untuk WebSocket. Mari kita bahas setiap jenis:

Tipe proxy Dukungan WS Mekanisme Kesulitan
Proxy HTTP ⚠️ Sebagian Melalui tunnel CONNECT Sedang
Proxy HTTPS ✅ Ya CONNECT + TLS Sedang
SOCKS4 ⚠️ Terbatas TCP tunnel tanpa auth Rendah
SOCKS5 ✅ Penuh TCP/UDP transparan Rendah
Proxy Transparan ❌ Tidak Hanya HTTP

Kesimpulan: untuk tugas WebSocket, pilihan yang optimal adalah SOCKS5. Protokol ini bekerja pada tingkat transportasi dan hanya men-tunnel koneksi TCP, tanpa menganalisis konten trafik. Ia tidak peduli apakah di dalamnya ada HTTP, WebSocket, SSH, atau yang lainnya. Proxy HTTP juga dapat bekerja dengan WS, tetapi hanya melalui metode CONNECT — dan ada nuansa yang akan kita bahas di bawah ini.

Metode CONNECT: bagaimana proxy HTTP men-tunnel WebSocket

Metode HTTP CONNECT adalah mekanisme khusus yang memungkinkan proxy HTTP membuat tunnel "buta" ke server tujuan. Proxy tidak menganalisis trafik di dalam tunnel, hanya meneruskan byte. Inilah cara HTTPS bekerja melalui proxy HTTP — dan inilah cara kita dapat memproxy WebSocket.

Prosesnya terlihat sebagai berikut:

  1. Klien mengirimkan permintaan ke proxy: CONNECT example.com:443 HTTP/1.1
  2. Proxy membuat koneksi TCP dengan example.com:443
  3. Proxy merespons klien: 200 Connection Established
  4. Sejak saat itu, proxy hanya meneruskan byte bolak-balik — tanpa menganalisisnya
  5. Klien melakukan TLS-handshake langsung dengan server melalui tunnel
  6. Kemudian — WebSocket-handshake di atas TLS

Pembatasan kunci: metode CONNECT biasanya hanya diizinkan untuk port 443. Jika server WebSocket Anda berjalan di port non-standar (misalnya, 8080 atau 9000), proxy dapat menolak koneksi. Dalam hal ini, SOCKS5 lebih disukai — ia tidak memiliki batasan port.

Juga penting untuk dicatat bahwa beberapa proxy HTTP perusahaan (misalnya, Squid dalam konfigurasi standar) secara eksplisit memblokir metode CONNECT untuk port tertentu atau memerlukan otentikasi. Jika Anda bekerja dengan penyedia proxy komersial, sebagian besar dari mereka mendukung CONNECT tanpa batasan.

# Contoh permintaan CONNECT melalui curl (untuk pengujian)
curl -v -x http://proxy_host:proxy_port \
  --proxytunnel \
  https://echo.websocket.org

# Jika proxy mendukung CONNECT — Anda akan melihat:
# * CONNECT tunnel established, response 200

SOCKS5 dan WebSocket: mengapa ini adalah pilihan terbaik

SOCKS5 adalah protokol proxy pada tingkat koneksi TCP/UDP. Berbeda dengan proxy HTTP, SOCKS5 tidak mengetahui apa pun tentang protokol aplikasi yang ada di dalamnya. Ia hanya membuat tunnel antara klien dan server tujuan, dan itu saja. Ini menjadikannya ideal untuk WebSocket karena beberapa alasan:

  • Tidak ada batasan protokol: SOCKS5 men-tunnel semua trafik TCP, termasuk WS, WSS, SSH, FTP, dll.
  • Tidak ada batasan port: bekerja dengan port mana pun, tidak hanya 443 atau 80
  • Tidak ada pemutusan saat perubahan protokol: proxy tidak "melihat" transisi dari HTTP ke WebSocket
  • Dukungan otentikasi: SOCKS5 mendukung login/password, yang nyaman untuk proxy komersial
  • Dukungan UDP: jika aplikasi Anda menggunakan WebRTC atau UDP bersamaan dengan WS — SOCKS5 dapat menangani

Hampir semua pustaka modern untuk bekerja dengan WebSocket mendukung SOCKS5 baik secara langsung maupun melalui paket tambahan. Di bawah ini kita akan melihat contoh konkret untuk Python dan Node.js.

💡 Kapan memilih SOCKS5, dan kapan HTTP CONNECT?

Gunakan SOCKS5, jika: port non-standar, perlu dukungan UDP, ingin pengaturan minimal.
Gunakan HTTP CONNECT, jika: penyedia proxy tidak mendukung SOCKS5, atau Anda bekerja melalui proxy perusahaan.

Contoh kode: WebSocket melalui proxy di Python

Mari kita lihat beberapa skenario untuk Python. Pustaka paling populer untuk WebSocket di Python adalah websockets dan websocket-client.

Pilihan 1: websocket-client melalui proxy HTTP

import websocket

# Pengaturan proxy HTTP
proxy_host = "proxy.example.com"
proxy_port = 8080
proxy_user = "username"
proxy_pass = "password"

ws = websocket.WebSocket()

ws.connect(
    "wss://echo.websocket.org",
    http_proxy_host=proxy_host,
    http_proxy_port=proxy_port,
    http_proxy_auth=(proxy_user, proxy_pass),
    proxy_type="http"  # atau "socks5"
)

ws.send("Hello, WebSocket!")
result = ws.recv()
print(f"Diterima: {result}")

ws.close()

Pilihan 2: websocket-client melalui SOCKS5

import websocket

# Untuk SOCKS5 diperlukan paket: pip install PySocks
ws = websocket.WebSocket()

ws.connect(
    "wss://echo.websocket.org",
    http_proxy_host="socks5_proxy.example.com",
    http_proxy_port=1080,
    http_proxy_auth=("username", "password"),
    proxy_type="socks5"
)

ws.send("Pesan uji")
print(ws.recv())
ws.close()

Pilihan 3: pustaka websockets (asyncio) melalui SOCKS5

Pustaka websockets (asyncio) tidak memiliki dukungan bawaan untuk proxy, jadi kita menggunakan python-socks untuk membuat tunnel:

# pip install websockets python-socks[asyncio]
import asyncio
import websockets
from python_socks.async_.asyncio import Proxy

async def connect_via_socks5():
    proxy = Proxy.from_url("socks5://username:[email protected]:1080")
    
    # Membuat koneksi TCP melalui proxy
    sock = await proxy.connect(
        dest_host="echo.websocket.org",
        dest_port=443
    )
    
    # Mengirimkan soket ke websockets
    async with websockets.connect(
        "wss://echo.websocket.org",
        sock=sock
    ) as ws:
        await ws.send("Hello via SOCKS5!")
        response = await ws.recv()
        print(f"Respons: {response}")

asyncio.run(connect_via_socks5())

Pilihan 4: patch global melalui PySocks

Jika Anda ingin mengarahkan semua trafik aplikasi Python melalui SOCKS5 tanpa mengubah setiap panggilan — gunakan socks.setdefaultproxy():

# pip install PySocks
import socks
import socket
import websocket

# Mem-patch socket secara global
socks.set_default_proxy(
    socks.SOCKS5,
    "proxy.example.com",
    1080,
    username="user",
    password="pass"
)
socket.socket = socks.socksocket

# Sekarang semua koneksi berjalan melalui SOCKS5
ws = websocket.WebSocket()
ws.connect("wss://echo.websocket.org")
ws.send("Proxy SOCKS5 Global!")
print(ws.recv())
ws.close()

Contoh kode: WebSocket melalui proxy di Node.js

Dalam ekosistem Node.js, pustaka paling populer untuk WebSocket adalah ws. Untuk memproxy melalui HTTP/SOCKS5, digunakan paket https-proxy-agent atau socks-proxy-agent.

Pilihan 1: WSS melalui proxy HTTP CONNECT

// npm install ws https-proxy-agent
const WebSocket = require('ws');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:[email protected]:8080';
const agent = new HttpsProxyAgent(proxyUrl);

const ws = new WebSocket('wss://echo.websocket.org', { agent });

ws.on('open', () => {
  console.log('Koneksi terjalin melalui proxy HTTP');
  ws.send('Hello dari Node.js!');
});

ws.on('message', (data) => {
  console.log(`Diterima: ${data}`);
  ws.close();
});

ws.on('error', (err) => {
  console.error('Kesalahan:', err.message);
});

Pilihan 2: WSS melalui SOCKS5

// npm install ws socks-proxy-agent
const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');

const proxyUrl = 'socks5://username:[email protected]:1080';
const agent = new SocksProxyAgent(proxyUrl);

const ws = new WebSocket('wss://echo.websocket.org', { agent });

ws.on('open', () => {
  console.log('Koneksi melalui SOCKS5 terjalin');
  ws.send(JSON.stringify({ type: 'ping', data: 'test' }));
});

ws.on('message', (data) => {
  console.log('Respons:', data.toString());
});

ws.on('close', (code, reason) => {
  console.log(`Ditutup: ${code} - ${reason}`);
});

Pilihan 3: WS (tanpa TLS) melalui proxy HTTP secara manual

Untuk WS yang tidak terenkripsi (port 80) melalui proxy HTTP, Anda perlu mengirimkan permintaan CONNECT secara manual, karena agen standar sering hanya bekerja dengan HTTPS:

const net = require('net');
const WebSocket = require('ws');

function createTunnel(proxyHost, proxyPort, targetHost, targetPort) {
  return new Promise((resolve, reject) => {
    const socket = net.connect(proxyPort, proxyHost, () => {
      const connectReq = 
        `CONNECT ${targetHost}:${targetPort} HTTP/1.1\r\n` +
        `Host: ${targetHost}:${targetPort}\r\n` +
        `Proxy-Authorization: Basic ${Buffer.from('user:pass').toString('base64')}\r\n` +
        `\r\n`;
      
      socket.write(connectReq);
    });

    socket.once('data', (data) => {
      if (data.toString().includes('200')) {
        resolve(socket);
      } else {
        reject(new Error(`Proxy menolak CONNECT: ${data.toString()}`));
      }
    });

    socket.on('error', reject);
  });
}

async function main() {
  const socket = await createTunnel(
    'proxy.example.com', 8080,
    'echo.websocket.org', 80
  );

  const ws = new WebSocket('ws://echo.websocket.org', { socket });
  
  ws.on('open', () => {
    ws.send('Tunnel CONNECT manual!');
  });

  ws.on('message', (data) => {
    console.log('Diterima:', data.toString());
    ws.close();
  });
}

main().catch(console.error);

WSS (WebSocket Secure): fitur proxy dengan TLS

WSS adalah WebSocket di atas TLS (mirip dengan HTTPS untuk HTTP). Saat memproxy WSS melalui SOCKS5 atau HTTP CONNECT, ada nuansa penting: Enkripsi TLS ditetapkan antara klien dan server akhir, bukan antara klien dan proxy. Ini berarti:

  • Server proxy tidak melihat konten trafik WSS — hanya alamat IP dan port tujuan
  • Sertifikat server diperiksa oleh klien secara langsung
  • Proxy tidak dapat "mengganti" atau "menangkap" data tanpa memasang sertifikat CA-nya sendiri

Ini adalah kabar baik dari sudut pandang keamanan. Namun, ada juga nuansa praktis saat pengaturan:

Pemeriksaan sertifikat melalui proxy

Terkadang saat menggunakan proxy perusahaan (yang melakukan inspeksi SSL), Anda mungkin mendapatkan kesalahan pemeriksaan sertifikat. Dalam hal ini, proxy mengganti sertifikat server dengan miliknya. Untuk bekerja dalam lingkungan seperti itu, Anda perlu menambahkan sertifikat CA proxy ke dalam daftar yang dipercaya:

# Python: mengirimkan sertifikat CA proxy perusahaan
import ssl
import websocket

ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations("/path/to/corporate-ca.crt")

ws = websocket.WebSocket(sslopt={"context": ssl_context})
ws.connect(
    "wss://internal.example.com",
    http_proxy_host="corp-proxy.company.com",
    http_proxy_port=8080,
    proxy_type="http"
)

# Di lingkungan pengujian (TIDAK untuk produksi!) Anda dapat menonaktifkan pemeriksaan:
ws_test = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws_test.connect("wss://test.example.com", http_proxy_host="proxy", http_proxy_port=8080)

⚠️ Penting

Menonaktifkan pemeriksaan sertifikat TLS (CERT_NONE) hanya diperbolehkan di lingkungan pengujian. Di produksi, ini menciptakan kerentanan terhadap serangan MITM (man-in-the-middle).

SNI (Server Name Indication) melalui proxy

Saat menggunakan SOCKS5, klien dapat menyelesaikan DNS sendiri atau mendelegasikannya ke proxy. Mode socks5h (SOCKS5 dengan resolusi hostname) berarti bahwa permintaan DNS dilakukan di sisi server proxy. Ini penting untuk WSS, karena header SNI dalam TLS-handshake harus sesuai dengan nama host:

# socks5  — DNS diselesaikan secara lokal (oleh klien)
# socks5h — DNS diselesaikan oleh server proxy (direkomendasikan untuk anonimitas)

from python_socks.async_.asyncio import Proxy

# DNS melalui proxy (direkomendasikan):
proxy = Proxy.from_url("socks5h://user:[email protected]:1080")

# DNS lokal:
proxy = Proxy.from_url("socks5://user:[email protected]:1080")

Kesalahan umum dan cara memperbaikinya

Kami telah mengumpulkan masalah yang paling umum saat memproxy WebSocket beserta solusinya:

Kesalahan 1: 407 Proxy Authentication Required

Proxy memerlukan otentikasi, tetapi Anda tidak mengirimkan kredensial atau mengirimkannya dengan salah.

# ❌ Salah — tidak ada otorisasi
ws.connect("wss://example.com", http_proxy_host="proxy.example.com", http_proxy_port=8080)

# ✅ Benar — mengirimkan login dan password
ws.connect(
    "wss://example.com",
    http_proxy_host="proxy.example.com",
    http_proxy_port=8080,
    http_proxy_auth=("username", "password")
)

Kesalahan 2: Connection reset by peer / 502 Bad Gateway

Proxy tidak mendukung WebSocket atau metode CONNECT. Solusi: beralih ke SOCKS5 atau periksa apakah penyedia Anda mendukung trafik WebSocket.

Kesalahan 3: Koneksi terputus setelah 30-60 detik

Banyak server proxy menutup koneksi TCP "tidak aktif" setelah waktu tertentu. Koneksi WebSocket dapat terlihat tidak aktif jika tidak ada pertukaran data. Solusi — aktifkan ping/pong:

# Python — aktifkan ping keepalive setiap 20 detik
import websocket
import threading

def run():
    ws = websocket.WebSocketApp(
        "wss://echo.websocket.org",
        on_message=lambda ws, msg: print(msg),
        on_error=lambda ws, err: print(f"Kesalahan: {err}"),
        on_close=lambda ws, c, m: print("Ditutup")
    )
    ws.run_forever(
        ping_interval=20,   # kirim ping setiap 20 detik
        ping_timeout=10,    # tunggu pong tidak lebih dari 10 detik
        http_proxy_host="proxy.example.com",
        http_proxy_port=8080,
        proxy_type="socks5"
    )

thread = threading.Thread(target=run)
thread.start()

Kesalahan 4: SSL: CERTIFICATE_VERIFY_FAILED

Kesalahan ini paling sering terjadi saat menggunakan proxy perusahaan dengan inspeksi SSL. Solusi: tambahkan sertifikat CA proxy ke dalam daftar yang dipercaya (lihat bagian di atas) atau gunakan SOCKS5 sebagai pengganti proxy HTTP — SOCKS5 tidak melakukan inspeksi SSL.

Kesalahan 5: Handshake status 403 Forbidden

Server tujuan memblokir koneksi. Alasan: IP proxy terdaftar dalam daftar hitam, header yang diperlukan hilang (Origin, User-Agent), atau server memblokir trafik dari pusat data. Solusi: gunakan proxy residensial dengan IP nyata dari pengguna rumah — mereka jauh lebih sulit untuk diblokir.

Kesalahan 6: [Errno 111] Connection refused

Server proxy tidak tersedia: host/port salah, atau proxy tidak berjalan. Periksa data koneksi dan ketersediaan proxy melalui permintaan HTTP sederhana sebelum menguji WebSocket.

Jenis proxy apa yang harus dipilih untuk tugas WebSocket

Pemilihan jenis proxy tergantung pada tugas tertentu. Berikut adalah panduan praktis:

Tugas Tipe yang direkomendasikan Mengapa
Pengambilan data melalui WS (bursa, data keuangan) Proxy pusat data Kecepatan tinggi, latensi rendah, koneksi stabil
Menghindari pemblokiran layanan WebSocket Proxy residensial IP nyata, risiko pemblokiran minimal
Aplikasi seluler dengan WS (bekerja dengan API seluler) Proxy seluler IP dari operator seluler — kepercayaan tinggi dari layanan
Pengujian beban server WS Proxy pusat data Murah, cepat, banyak koneksi simultan
Pengujian geolokasi WS Proxy residensial Beragam pilihan negara dan kota

Parameter penting proxy untuk WebSocket

Saat memilih penyedia proxy untuk tugas WebSocket, perhatikan parameter berikut:

  • Dukungan SOCKS5: pastikan penyedia menyediakan SOCKS5, bukan hanya HTTP
  • Durasi sesi (session duration): untuk WebSocket, sesi "sticky" penting — satu IP untuk waktu yang lama. Proxy yang berotasi akan memutuskan koneksi
  • Timeout koneksi: proxy harus mendukung koneksi TCP yang bertahan lama (dari beberapa menit hingga jam)
  • Bandwidth: untuk WebSocket streaming (video, data bursa) bandwidth tinggi tanpa batasan sangat penting
  • Latensi: untuk aplikasi keuangan dan bot trading, latensi minimal sangat penting — pilih proxy dengan server yang lebih dekat ke layanan target

💡 Memeriksa dukungan WebSocket oleh penyedia proxy

Sebelum membeli proxy untuk tugas WebSocket, uji mereka melalui server echo gratis: wss://echo.websocket.org atau wss://ws.postman-echo.com/raw. Jika koneksi terjalin dan pesan kembali — proxy bekerja dengan WebSocket dengan benar.

Pengaturan sesi sticky untuk WebSocket

Sebagian besar penyedia proxy residensial menggunakan rotasi IP secara default. Untuk WebSocket, ini tidak dapat diterima — setiap perubahan IP berarti pemutusan koneksi. Pastikan Anda menggunakan mode sticky session (IP tetap). Ini biasanya dilakukan melalui format URL proxy khusus:

# Contoh format sticky session (tergantung penyedia):
# Rotasi (TIDAK cocok untuk WebSocket):
socks5://user:[email protected]:1080

# Sticky session (cocok untuk WebSocket):
socks5://user-session-abc123:[email protected]:1080

# Atau melalui parameter negara dan sesi:
socks5://user-country-us-session-12345:[email protected]:1080

Kesimpulan

WebSocket bukan hanya "HTTP dengan koneksi panjang". Ini adalah protokol terpisah yang memerlukan pendekatan khusus saat memproxy. Kesimpulan utama dari artikel ini:

  • SOCKS5 — pilihan optimal untuk WebSocket: bekerja pada tingkat transportasi, tidak menganalisis protokol, mendukung semua port
  • Proxy HTTP melalui CONNECT juga berfungsi, tetapi dengan batasan port dan kemungkinan masalah dengan inspeksi SSL
  • Sesi sticky wajib: proxy yang berotasi akan memutus koneksi WebSocket pada setiap perubahan IP
  • Ping/pong keepalive diperlukan untuk mencegah pemutusan koneksi karena timeout proxy
  • WSS melalui proxy aman: enkripsi TLS ditetapkan langsung antara klien dan server, proxy tidak melihat konten

Jika Anda mengembangkan aplikasi yang bekerja dengan WebSocket melalui proxy — mulai dengan SOCKS5 dan sesi sticky. Ini akan menghemat jam debugging Anda. Untuk tugas di mana kecepatan tinggi dan stabilitas koneksi penting (bot trading, streaming data), proxy pusat data dengan latensi rendah sangat cocok. Namun, jika layanan target secara aktif memblokir IP pusat data — pertimbangkan proxy residensial: mereka memiliki IP nyata dari pengguna rumah dan jauh lebih jarang diblokir bahkan dalam sesi WebSocket yang panjang.

```