Kod · Protokol · Hata ayıklama

Geliştirici rehberi: HTTP ve SOCKS5 proxy kullanımı

Bir proxy’yi koda bağlamak için gereken her şey tek sayfada: 12 dilde çalışan örnekler, iki protokolün kablo üzerindeki konuşması, ortam değişkenleri, cURL komutları ve hata iletilerinin anlamı.

Resmi SDK yoktur; örnekler standart kütüphanelerle çalışır.

Bazı dillerde o dilin yaygın, açık kaynak HTTP istemcisi kullanılır; gereken kurulum her örneğin altında yazar.

Test adresi
https://api.ipify.org?format=json
Yer tutucular
KULLANICI · PAROLA · PROXY_ADRESI · PORT
Protokoller
HTTP (CONNECT) · SOCKS5 (RFC 1928/1929)

01Kod örnekleri

Aynı istek, 12 dilde.

Her örnek api.ipify.org adresine proxy üzerinden gider ve sunucunun gördüğü çıkış IP’sini yazdırır. Dili seçin, protokolü değiştirin; kurulum satırı ve notlar kodun hemen altında.

FİG. — Aynı istek, 12 dilde · api.ipify.org

PythonPython 3.10+ · requestsHTTP · CONNECT tüneli

proxy_test.py
from urllib.parse import quote

import requests

PROXY_HOST = "PROXY_ADRESI"
PROXY_PORT = "PORT"
PROXY_USER = "KULLANICI"
PROXY_PASS = "PAROLA"

# Kullanıcı adı veya parolada özel karakter varsa URL için kodlanır
proxy_url = f"http://{quote(PROXY_USER, safe='')}:{quote(PROXY_PASS, safe='')}@{PROXY_HOST}:{PROXY_PORT}"
proxies = {"http": proxy_url, "https": proxy_url}

try:
    # (bağlantı, okuma) zaman aşımı, saniye
    yanit = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=(10, 30))
    yanit.raise_for_status()
    print("Çıkış IP’si:", yanit.json()["ip"])
except requests.exceptions.ProxyError as hata:
    print("Proxy’ye bağlanılamadı veya kimlik reddedildi:", hata)
except requests.exceptions.RequestException as hata:
    print("İstek başarısız:", hata)

Kurulum ve çalıştırma

pip install requests && python proxy_test.py

Notlar

  1. HTTPS hedefte requests, proxy ile bir CONNECT tüneli açar; sayfa içeriği hedefle kurulan TLS bağlantısıyla şifreli kalır.
  2. timeout verilmezse requests süresiz bekleyebilir; (10, 30) bağlantı ve okuma sürelerini ayrı sınırlar.
  3. 407 yanıtı kullanıcı adı veya parolanın reddedildiği anlamına gelir; ProxyError olarak yakalanır.
proxy-test.mjs
import { ProxyAgent, fetch } from "undici";

const PROXY_HOST = "PROXY_ADRESI";
const PROXY_PORT = "PORT";
const PROXY_USER = "KULLANICI";
const PROXY_PASS = "PAROLA";

// Kimlik, Proxy-Authorization başlığı olarak gönderilir
const dispatcher = new ProxyAgent({
  uri: "http://" + PROXY_HOST + ":" + PROXY_PORT,
  token: "Basic " + Buffer.from(PROXY_USER + ":" + PROXY_PASS).toString("base64"),
});

try {
  const yanit = await fetch("https://api.ipify.org?format=json", {
    dispatcher,
    signal: AbortSignal.timeout(30_000),
  });
  if (!yanit.ok) {
    throw new Error("HTTP " + yanit.status);
  }
  const veri = await yanit.json();
  console.log("Çıkış IP’si:", veri.ip);
} catch (hata) {
  console.error("İstek başarısız:", hata);
  process.exitCode = 1;
} finally {
  await dispatcher.close();
}

Kurulum ve çalıştırma

npm install undici@6 && node proxy-test.mjs

Notlar

  1. Tarayıcıdaki JavaScript proxy ayarlayamaz; örnekler Node.js içindir.
  2. Node.js’in yerleşik fetch’i HTTP_PROXY ortam değişkenini varsayılan olarak okumaz; proxy, undici ProxyAgent ile dispatcher olarak verilir.
  3. AbortSignal.timeout(30_000) isteği 30 saniyede keser; dispatcher.close() açık bağlantıları kapatıp sürecin hemen bitmesini sağlar.
proxy-test.mts
import { ProxyAgent, fetch } from "undici";

const PROXY_HOST = "PROXY_ADRESI";
const PROXY_PORT = "PORT";
const PROXY_USER = "KULLANICI";
const PROXY_PASS = "PAROLA";

interface IpifyYaniti {
  ip: string;
}

const secenekler: ProxyAgent.Options = {
  uri: "http://" + PROXY_HOST + ":" + PROXY_PORT,
  token: "Basic " + Buffer.from(PROXY_USER + ":" + PROXY_PASS).toString("base64"),
};

async function main(): Promise<void> {
  const dispatcher = new ProxyAgent(secenekler);
  try {
    const yanit = await fetch("https://api.ipify.org?format=json", {
      dispatcher,
      signal: AbortSignal.timeout(30_000),
    });
    if (!yanit.ok) {
      throw new Error("HTTP " + yanit.status);
    }
    const veri = (await yanit.json()) as IpifyYaniti;
    console.log("Çıkış IP’si:", veri.ip);
  } finally {
    await dispatcher.close();
  }
}

main().catch((hata: unknown) => {
  console.error("İstek başarısız:", hata);
  process.exitCode = 1;
});

Kurulum ve çalıştırma

npm install undici@6 && npm install -D tsx @types/node && npx tsx proxy-test.mts

Notlar

  1. Tipler doğrudan undici paketinden gelir (ProxyAgent.Options); ayrı bir @types paketi gerekmez.
  2. tsx dosyayı tip denetimi yapmadan çalıştırır; tip denetimi için typescript paketini ayrıca kurup tsc’yi bir tsconfig.json ile çalıştırın.
  3. yanit.json() unknown döndürür; IpifyYaniti arayüzüyle beklenen biçim açıkça belirtilir.
proxy-test.mjs
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const PROXY_HOST = "PROXY_ADRESI";
const PROXY_PORT = "PORT";
const PROXY_USER = "KULLANICI";
const PROXY_PASS = "PAROLA";

const proxyUrl =
  "http://" + encodeURIComponent(PROXY_USER) + ":" + encodeURIComponent(PROXY_PASS) +
  "@" + PROXY_HOST + ":" + PROXY_PORT;

// proxy: false, axios’un kendi proxy işlemesini kapatır; tünel ajan tarafından kurulur
const httpsAgent = new HttpsProxyAgent(proxyUrl);

axios
  .get("https://api.ipify.org?format=json", { httpsAgent, proxy: false, timeout: 30000 })
  .then((yanit) => {
    console.log("Çıkış IP’si:", yanit.data.ip);
  })
  .catch((hata) => {
    const durum = hata.response ? "HTTP " + hata.response.status : hata.code || hata.message;
    console.error("İstek başarısız:", durum);
    process.exitCode = 1;
  });

Kurulum ve çalıştırma

npm install axios https-proxy-agent@9 && node proxy-test.mjs

Notlar

  1. proxy: false, axios’un kendi proxy ayarını ve ortam değişkenlerindeki (HTTP_PROXY, HTTPS_PROXY) proxy tanımlarını devre dışı bırakır; HTTPS hedef için CONNECT tünelini https-proxy-agent kurar.
  2. Dosya ES modülü (import) biçimindedir; https-proxy-agent ve socks-proxy-agent’in güncel sürümleri yalnızca ES modülü sunar, bu yüzden .mjs uzantısı kullanılır. Bu paketler require ile yüklenmek istenirse Node.js 20.19 ve 22.12 öncesi sürümlerde hata alınır.
  3. Proxy kimliği reddederse https-proxy-agent proxy’nin 407 yanıtını isteğe aktarır; axios bunu “HTTP 407” olarak bildirir.
main.go
package main

import (
    "fmt"
    "io"
    "net"
    "net/http"
    "net/url"
    "os"
    "time"
)

const (
    proxyHost = "PROXY_ADRESI"
    proxyPort = "PORT"
    proxyUser = "KULLANICI"
    proxyPass = "PAROLA"
)

func main() {
    // url.UserPassword değeri ham hâliyle saklar; özel karakterleri elle kodlamayın
    proxyURL := &url.URL{
        Scheme: "http",
        User:   url.UserPassword(proxyUser, proxyPass),
        Host:   net.JoinHostPort(proxyHost, proxyPort),
    }

    client := &http.Client{
        Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
        Timeout:   30 * time.Second,
    }

    resp, err := client.Get("https://api.ipify.org?format=json")
    if err != nil {
        fmt.Fprintln(os.Stderr, "İstek başarısız:", err)
        os.Exit(1)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Fprintln(os.Stderr, "Yanıt okunamadı:", err)
        os.Exit(1)
    }
    fmt.Println(resp.Status, string(body))
}

Kurulum ve çalıştırma

go run main.go

Notlar

  1. Proxy, http.Transport üzerinde açıkça verildiği için HTTP_PROXY ortam değişkeni bu istemciyi etkilemez.
  2. Kimlik bilgisi URL’deki kullanıcı bilgisinden Proxy-Authorization başlığına çevrilir; HTTPS hedefte CONNECT tüneli kurulur.
  3. Client.Timeout bağlantı, tünel ve yanıt gövdesinin okunmasını birlikte 30 saniyeyle sınırlar.
proxy_test.php
<?php
$proxyHost = 'PROXY_ADRESI';
$proxyPort = 'PORT';
$proxyUser = 'KULLANICI';
$proxyPass = 'PAROLA';

$port = filter_var($proxyPort, FILTER_VALIDATE_INT);
if ($port === false) {
    fwrite(STDERR, 'PORT değerini sayıyla değiştirin.' . PHP_EOL);
    exit(1);
}

$ch = curl_init('https://api.ipify.org?format=json');
curl_setopt_array($ch, [
    CURLOPT_PROXY          => $proxyHost,
    CURLOPT_PROXYPORT      => $port,
    CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
    CURLOPT_PROXYUSERPWD   => $proxyUser . ':' . $proxyPass,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);

$govde = curl_exec($ch);
if ($govde === false) {
    fwrite(STDERR, 'İstek başarısız: ' . curl_error($ch) . PHP_EOL);
    exit(1);
}

$kod = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
echo $kod . ' ' . $govde . PHP_EOL;

Kurulum ve çalıştırma

php proxy_test.php

Notlar

  1. HTTPS hedefte cURL, HTTP proxy ile otomatik olarak CONNECT tüneli açar; içerik TLS ile şifreli kalır.
  2. CURLOPT_CONNECTTIMEOUT bağlantı kurulumunu, CURLOPT_TIMEOUT isteğin tamamını saniye cinsinden sınırlar.
  3. curl_exec false dönerse ayrıntı curl_error() ile okunur; proxy kimliği reddederse hata mesajında 407 görülür.
ProxyTest.java
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class ProxyTest {
    static final String PROXY_HOST = "PROXY_ADRESI";
    static final String PROXY_PORT = "PORT";
    static final String PROXY_USER = "KULLANICI";
    static final String PROXY_PASS = "PAROLA";

    public static void main(String[] args) throws Exception {
        // HTTPS tüneli (CONNECT) için Basic doğrulamayı açar; istemci oluşturulmadan önce ayarlanmalı
        System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");

        HttpClient client = HttpClient.newBuilder()
            .proxy(ProxySelector.of(new InetSocketAddress(PROXY_HOST, Integer.parseInt(PROXY_PORT))))
            .authenticator(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    if (getRequestorType() == RequestorType.PROXY) {
                        return new PasswordAuthentication(PROXY_USER, PROXY_PASS.toCharArray());
                    }
                    return null;
                }
            })
            .connectTimeout(Duration.ofSeconds(10))
            .build();

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.ipify.org?format=json"))
            .timeout(Duration.ofSeconds(30))
            .GET()
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}

Kurulum ve çalıştırma

java ProxyTest.java

Notlar

  1. JDK, HTTPS tünelinde Basic doğrulamayı varsayılan olarak kapatır; jdk.http.auth.tunneling.disabledSchemes boş verilmezse 407 alınır.
  2. Özellik komut satırından da verilebilir: java "-Djdk.http.auth.tunneling.disabledSchemes=" ProxyTest.java
  3. Authenticator yalnızca proxy istediğinde (RequestorType.PROXY) kimlik döndürür; hedef siteye parola gönderilmez.
Program.cs
using System.Net;

const string ProxyHost = "PROXY_ADRESI";
const string ProxyPort = "PORT";
const string ProxyUser = "KULLANICI";
const string ProxyPass = "PAROLA";

var proxy = new WebProxy(new Uri("http://" + ProxyHost + ":" + ProxyPort))
{
    Credentials = new NetworkCredential(ProxyUser, ProxyPass)
};

using var handler = new HttpClientHandler { Proxy = proxy, UseProxy = true };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };

try
{
    string body = await client.GetStringAsync("https://api.ipify.org?format=json");
    Console.WriteLine(body);
}
catch (HttpRequestException ex)
{
    // 407 ve bağlantı hataları burada yakalanır
    Console.Error.WriteLine("İstek başarısız: " + ex.Message);
    Environment.ExitCode = 1;
}
catch (TaskCanceledException)
{
    Console.Error.WriteLine("Zaman aşımı (30 sn).");
    Environment.ExitCode = 1;
}

Kurulum ve çalıştırma

dotnet new console -o ProxyTest && cd ProxyTest · Program.cs’yi bu kodla değiştirin · dotnet run

Notlar

  1. Program.cs üst düzey ifadeler (top-level statements) kullanır; dotnet new console şablonundaki örtük using’lerle derlenir.
  2. HttpClient zaman aşımında TaskCanceledException fırlatır; bu yüzden ayrı yakalanır.
  3. Gerçek uygulamada HttpClient bir kez oluşturulup yeniden kullanılmalıdır; her istekte yeni istemci soket tüketir.
main.cpp
#include <curl/curl.h>

#include <iostream>
#include <string>

static size_t yaz(char* veri, size_t boyut, size_t adet, void* hedef) {
    static_cast<std::string*>(hedef)->append(veri, boyut * adet);
    return boyut * adet;
}

int main() {
    const std::string proxyHost = "PROXY_ADRESI";
    const std::string proxyPort = "PORT";
    const std::string proxyUser = "KULLANICI";
    const std::string proxyPass = "PAROLA";

    const std::string proxy = "http://" + proxyHost + ":" + proxyPort;
    const std::string kimlik = proxyUser + ":" + proxyPass;
    std::string govde;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    CURL* curl = curl_easy_init();
    if (curl == nullptr) {
        std::cerr << "libcurl başlatılamadı" << std::endl;
        return 1;
    }

    curl_easy_setopt(curl, CURLOPT_URL, "https://api.ipify.org?format=json");
    curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
    curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, kimlik.c_str());
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, yaz);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &govde);

    const CURLcode sonuc = curl_easy_perform(curl);
    int cikis = 0;
    if (sonuc != CURLE_OK) {
        std::cerr << "İstek başarısız: " << curl_easy_strerror(sonuc) << std::endl;
        cikis = 1;
    } else {
        long kod = 0;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &kod);
        std::cout << kod << " " << govde << std::endl;
    }

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return cikis;
}

Kurulum ve çalıştırma

g++ -std=c++17 main.cpp -o proxy_test -lcurl && ./proxy_test

Notlar

  1. libcurl geliştirme paketi gerekir (Debian/Ubuntu: libcurl4-openssl-dev).
  2. Proxy adresindeki http:// öneki türü belirler; HTTPS hedefte CONNECT tüneli kendiliğinden açılır.
  3. Sayısal seçenekler long beklediği için 10L ve 30L yazılır; düz int bazı platformlarda yanlış okunabilir.
proxy_test.rb
require "net/http"
require "uri"

PROXY_HOST = "PROXY_ADRESI"
PROXY_PORT = "PORT"
PROXY_USER = "KULLANICI"
PROXY_PASS = "PAROLA"

uri = URI("https://api.ipify.org?format=json")

# Proxy bilgileri açıkça verildiği için ortam değişkenleri dikkate alınmaz
http = Net::HTTP.new(uri.host, uri.port, PROXY_HOST, Integer(PROXY_PORT), PROXY_USER, PROXY_PASS)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 30

begin
  yanit = http.request(Net::HTTP::Get.new(uri))
  puts "#{yanit.code} #{yanit.body}"
rescue StandardError => e
  warn "İstek başarısız: #{e.class}: #{e.message}"
  exit 1
end

Kurulum ve çalıştırma

ruby proxy_test.rb

Notlar

  1. net/http standart kütüphanedir; ek gem gerekmez. HTTPS hedefte CONNECT tüneli kendiliğinden kurulur.
  2. open_timeout bağlantı kurulumunu, read_timeout yanıt beklemesini saniye cinsinden sınırlar.
  3. Integer("PORT") port gerçek bir sayıyla değiştirilmezse ArgumentError fırlatır; bu bilinçli bir erken uyarıdır.
src/main.rs
use std::time::Duration;

const PROXY_HOST: &str = "PROXY_ADRESI";
const PROXY_PORT: &str = "PORT";
const PROXY_USER: &str = "KULLANICI";
const PROXY_PASS: &str = "PAROLA";

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let proxy = reqwest::Proxy::all(format!("http://{}:{}", PROXY_HOST, PROXY_PORT))?
        .basic_auth(PROXY_USER, PROXY_PASS);

    let client = reqwest::Client::builder()
        .proxy(proxy)
        .connect_timeout(Duration::from_secs(10))
        .timeout(Duration::from_secs(30))
        .build()?;

    let yanit = client
        .get("https://api.ipify.org?format=json")
        .send()
        .await?
        .error_for_status()?;

    println!("{}", yanit.text().await?);
    Ok(())
}

Kurulum ve çalıştırma

cargo new proxy_test && cd proxy_test · src/main.rs’yi bu kodla değiştirin · cargo add [email protected] && cargo add tokio --features full && cargo run

Notlar

  1. Proxy::all hem http:// hem https:// hedefleri aynı proxy’ye yönlendirir; basic_auth kimliği Proxy-Authorization olarak ekler.
  2. error_for_status() 4xx/5xx yanıtları hataya çevirir; ? operatörü hatayı main’den döndürür.
  3. reqwest varsayılan olarak sistemin TLS kütüphanesini kullanır; Linux’ta OpenSSL geliştirme paketi gerekebilir.
proxy_test.sh
#!/usr/bin/env bash
set -euo pipefail

PROXY_HOST="PROXY_ADRESI"
PROXY_PORT="PORT"
PROXY_USER="KULLANICI"
PROXY_PASS="PAROLA"

# -x: HTTP proxy, -U: proxy kimliği; HTTPS hedef için curl CONNECT tüneli açar
curl --fail --silent --show-error \
  --connect-timeout 10 --max-time 30 \
  -x "http://$PROXY_HOST:$PROXY_PORT" \
  -U "$PROXY_USER:$PROXY_PASS" \
  "https://api.ipify.org?format=json"
echo

Kurulum ve çalıştırma

chmod +x proxy_test.sh && ./proxy_test.sh

Notlar

  1. Tek satır karşılığı: curl -x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" "https://api.ipify.org?format=json"
  2. --fail 4xx/5xx yanıtlarda sıfır olmayan çıkış kodu döndürür; set -e betiği orada durdurur.
  3. Parolayı komut satırına yazmak onu kabuk geçmişinde ve süreç listesinde görünür kılar; ortak makinelerde dikkat edin.

02Protokoller

Protokoller nasıl konuşur?

Hataların çoğu ilk birkaç mesajda doğar. Akışlar RFC metinlerine göre çizildi; baytlar ve durum kodları standartlardaki değerlerdir.

FİG. 01 — HTTP proxy, HTTPS hedef

HTTP proxy: CONNECT ile tünel

HTTPS bir adrese HTTP proxy üzerinden gidildiğinde istemci önce proxy’den bir tünel ister. Tünel açıldıktan sonra TLS doğrudan istemci ile hedef sunucu arasında kurulur.

RFC 9110 §9.3.6RFC 9110 §11.7.2

  1. İstemciden proxy’ye:

    TCP → PROXY_ADRESI:PORT

    İstemci, proxy’nin adresine ve portuna sıradan bir TCP bağlantısı açar.

  2. İstemciden proxy’ye:

    CONNECT api.ipify.org:443 HTTP/1.1

    İstek satırına Host ve Proxy-Authorization: Basic … başlıkları eşlik eder. Basic değeri, KULLANICI:PAROLA çiftinin Base64 ile kodlanmış hâlidir; bir şifreleme değildir.

  3. Proxy’den hedefe:

    TCP → api.ipify.org:443

    Proxy kimlik bilgisini doğrular, hedef adını kendi tarafında DNS ile çözer ve hedefin 443 portuna bağlanır.

  4. Proxy’den istemciye:

    HTTP/1.1 200 Connection established

    Tünel hazırdır. Kimlik bilgisi eksik ya da hatalıysa yanıt 407 Proxy Authentication Required olur ve tünel açılmaz.

  5. İstemci ile hedef arasında, proxy üzerinden:

    TLS ClientHello … Finished

    TLS, istemci ile hedef arasında kurulur; sertifikayı hedef sunucu sunar. Proxy şifreli baytları iki yöne aktarır, içeriği okuyamaz.

  6. İstemci ile hedef arasında, proxy üzerinden:

    GET /?format=json → {"ip":"…"}

    HTTP isteği ve yanıtı TLS içinde akar. Hedef sunucu isteği proxy’nin çıkış IP’sinden gelmiş olarak görür.

Düz http:// adreslerinde CONNECT kullanılmaz: istemci isteği GET http://alan.adi/yol HTTP/1.1 biçiminde tam adresle proxy’ye gönderir ve proxy içeriği açık metin olarak görür.

FİG. 02 — SOCKS5, kullanıcı adı ve parola ile

SOCKS5: el sıkışma, doğrulama, istek

SOCKS5 uygulama protokolünü yorumlamaz; kısa bir ikili el sıkışmadan sonra TCP akışını olduğu gibi aktarır. Baytlar onaltılık (hex) yazılmıştır.

RFC 1928RFC 1929

  1. İstemciden proxy’ye:

    VER 05 · NMETHODS 01 · METHODS 02

    İstemci sürümü ve desteklediği doğrulama yöntemlerini bildirir: 00 doğrulama yok, 02 kullanıcı adı/parola. Pek çok istemci ikisini birden sunar (05 02 00 02).

  2. Proxy’den istemciye:

    VER 05 · METHOD 02

    Sunucu yöntemlerden birini seçer. FF yanıtı kabul edilebilir bir yöntem olmadığını gösterir ve bağlantı kapanır.

  3. İstemciden proxy’ye:

    VER 01 · ULEN · UNAME · PLEN · PASSWD

    RFC 1929 alt müzakeresi: sürüm 01, ardından uzunluk önekli kullanıcı adı ve parola. Bu bilgiler şifrelenmeden iletilir.

  4. Proxy’den istemciye:

    VER 01 · STATUS 00

    00 başarılı demektir; başka her değer hatadır ve sunucu bağlantıyı kapatmalıdır.

  5. İstemciden proxy’ye:

    VER 05 · CMD 01 · RSV 00 · ATYP 03 · 0D api.ipify.org · 01 BB

    Bağlantı isteği: CMD 01 CONNECT, ATYP 03 alan adı, port 443 (01 BB). socks5h:// ile alan adı proxy’ye gider ve DNS’i proxy çözer; socks5:// ile birçok istemci adı yerelde çözüp ATYP 01 (IPv4) gönderir.

  6. Proxy’den hedefe:

    TCP → api.ipify.org:443

    Proxy hedefe kendi çıkış adresinden bağlanır.

  7. Proxy’den istemciye:

    VER 05 · REP 00 · RSV 00 · ATYP 01 · BND.ADDR · BND.PORT

    REP 00 başarılıdır. Hata kodları da bu alanda döner; örneğin 05 bağlantı reddedildi, 04 ana bilgisayara ulaşılamıyor anlamına gelir.

  8. İstemci ile hedef arasında, proxy üzerinden:

    TLS … GET /?format=json

    Bundan sonra proxy akışı olduğu gibi aktarır. HTTPS isteği yine istemci ile hedef arasında TLS ile şifrelidir.

RFC 1928 ayrıca BIND (CMD 02) ve UDP ASSOCIATE (CMD 03) komutlarını tanımlar; bir hizmetin bunları destekleyip desteklemediği sağlayıcıya bağlıdır.

03Ortam değişkenleri

Kod yazmadan yapılandırma

Pek çok araç proxy adresini koddan değil ortamdan okur. Hangi aracın hangi değişkeni dikkate aldığı aşağıda; Node.js’in yerleşik fetch’i varsayılan olarak hiçbirini okumaz.

HTTP_PROXY
Düz http:// adreslerine giden isteklerin proxy’si.
http://KULLANICI:PAROLA@PROXY_ADRESI:PORT
HTTPS_PROXY
https:// adreslerinin proxy’si. Değer çoğunlukla yine http:// ile başlar: tünel CONNECT ile açılır, TLS uçtan uca kalır.
http://KULLANICI:PAROLA@PROXY_ADRESI:PORT
ALL_PROXY
Protokole özel değişken yoksa kullanılan genel proxy; SOCKS5 adresi vermek için en yaygın yol.
socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT
NO_PROXY
Proxy’siz gidilecek adlar ve adresler, virgülle ayrılır. .ornek.com biçimi alt alan adlarını kapsar; eşleşme ayrıntıları araca göre biraz değişir.
localhost,127.0.0.1,.ornek.com

Hangi araç hangi değişkeni okur?

  • curl · komut satırı

    HTTP_PROXY
    Kısmen
    HTTPS_PROXY
    Evet
    ALL_PROXY
    Evet
    NO_PROXY
    Evet

    Düz HTTP için yalnızca küçük harfli http_proxy okunur; büyük harfli HTTP_PROXY güvenlik nedeniyle yok sayılır.

  • Python requests · trust_env varsayılan

    HTTP_PROXY
    Evet
    HTTPS_PROXY
    Evet
    ALL_PROXY
    Evet
    NO_PROXY
    Evet

    SOCKS5 adresleri için pip install "requests[socks]" gerekir. İsteğe proxies= ile verilen sözlük ortam değişkenlerinin önüne geçer.

  • Python urllib · urllib.request

    HTTP_PROXY
    Evet
    HTTPS_PROXY
    Evet
    ALL_PROXY
    Hayır
    NO_PROXY
    Evet

    Varsayılan ProxyHandler ortamdaki HTTP/HTTPS proxy’lerini kullanır; SOCKS desteği yoktur.

  • Go net/http · DefaultTransport

    HTTP_PROXY
    Evet
    HTTPS_PROXY
    Evet
    ALL_PROXY
    Hayır
    NO_PROXY
    Evet

    http.ProxyFromEnvironment büyük ve küçük harfli adları okur; socks5:// değeri de kabul edilir. localhost istekleri proxy’ye gitmez.

  • git · HTTP(S) depolar

    HTTP_PROXY
    Kısmen
    HTTPS_PROXY
    Evet
    ALL_PROXY
    Evet
    NO_PROXY
    Evet

    libcurl üzerinden curl ile aynı kuralları izler; kalıcı ayar için git config http.proxy de kullanılabilir.

  • Node.js · fetch, http, https

    HTTP_PROXY
    Hayır
    HTTPS_PROXY
    Hayır
    ALL_PROXY
    Hayır
    NO_PROXY
    Hayır

    Yerleşik fetch ve http modülü bu değişkenleri varsayılan olarak okumaz; proxy’yi koddaki ajanla (örneğin undici paketinin ProxyAgent’ı) verin.

Birçok komut satırı aracı aynı adları okur, ancak büyük/küçük harf kuralları araçtan araca değişir; emin olmak için iki biçimi de tanımlayın. Parolada @, : ya da / varsa URL içinde yüzde kodlaması kullanın (@ → %40).

04cURL

cURL ile kısa başvuru

Bir proxy’yi uygulamanıza bağlamadan önce tek satırla sınayın. Komutlar bash ve zsh’te olduğu gibi çalışır; Windows PowerShell’de curl.exe yazın, cmd.exe’de tek tırnak yerine çift tırnak kullanın.

proxy-kontrol.sh
# 1) HTTP proxy, kimlik bilgisi ayrı parametreyle (parolada @ veya : varsa en güvenli yol)
curl -x http://PROXY_ADRESI:PORT -U 'KULLANICI:PAROLA' 'https://api.ipify.org?format=json'

# 2) Aynı istek, kimlik bilgisi proxy adresinin içinde
curl -x 'http://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 3) SOCKS5, alan adı proxy tarafında çözülür (socks5h)
curl -x 'socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 4) SOCKS5, alan adı yerelde çözülür (socks5)
curl -x 'socks5://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 5) Ayrıntılı çıktı: CONNECT, 407 ve TLS adımlarını satır satır görün
curl -v -x 'http://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 6) Zaman sınırları: bağlantı için 10 sn, tüm istek için 30 sn
curl --connect-timeout 10 --max-time 30 -x 'http://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 7) Yalnızca durum kodu ve toplam süre
curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' -x 'http://KULLANICI:PAROLA@PROXY_ADRESI:PORT' 'https://api.ipify.org?format=json'

# 8) Ortam değişkeniyle: bu kabukta çalışan sonraki komutlar proxy kullanır
export https_proxy='http://KULLANICI:PAROLA@PROXY_ADRESI:PORT'
curl 'https://api.ipify.org?format=json'

# 9) Ortamda proxy tanımlıyken tek bir isteği proxy’siz gönderin
curl --noproxy '*' 'https://api.ipify.org?format=json'

05Doğrulama ve hata ayıklama

Hata iletileri ne söyler?

En sık görülen durumlar ve her birinde ilk bakılacak yer. Bağlantıyı tarayıcıdan sınamak için araçlar en altta.

  1. 407

    Proxy Authentication Required

    Proxy kimlik bilgisini kabul etmedi. Kullanıcı adı ve parolayı yeniden kopyalayın; parolada @, : veya / varsa yüzde kodlaması kullanın ya da curl’de -U ile ayrı verin. IP yetkilendirmesiyle çalışan paketlerde bağlandığınız IP’nin tanımlı olduğundan emin olun.

  2. ECONNREFUSED

    Connection refused

    Adres ya da port yanlış veya o portta dinleyen bir hizmet yok. PROXY_ADRESI ve PORT değerlerini siparişinizle karşılaştırın; portun dışarıdan açık olup olmadığını Port Kontrol aracıyla görün.

  3. ETIMEDOUT

    Zaman aşımı

    Bağlantı kurulamıyor ya da yanıt gelmiyor. Her istemciye açık bir süre verin (curl’de --connect-timeout 10, Python’da timeout=(10, 30)). Kurumsal ağ veya yerel güvenlik duvarı giden bağlantıyı engelliyor olabilir; sorun tek bir hedefte oluyorsa proxy’yi değil hedefi sınayın.

  4. ŞEMA

    Protokol ile şema uyuşmuyor

    HTTP olarak teslim edilen bir porta socks5:// ile bağlanmak (ya da tersi) el sıkışma aşamasında hata verir. Şemayı paketinizin protokolüne göre seçin: HTTP için http://, SOCKS5 için socks5h:// veya socks5://.

  5. DNS

    DNS sızıntısı: socks5 ve socks5h

    socks5:// ile birçok istemci hedef adını kendi çözümleyicinizde çözer; DNS sorgusu proxy’den değil sizin ağınızdan çıkar. socks5h:// adı proxy’ye bırakır (Python requests’te de aynı yazım). HTTP proxy’de CONNECT kullanıldığında ad zaten proxy tarafında çözülür.

  6. TLS

    Sertifika hataları

    CONNECT tünelinde sertifikayı hedef sunucu sunar; SSL certificate problem gibi bir hata çoğunlukla hedef adından ya da yerel sertifika deposundan kaynaklanır. Doğrulamayı -k veya verify=False ile kapatmayın.

  7. IP

    Çıkış IP’sini doğrulayın

    İstek proxy’den çıktıysa api.ipify.org sizin değil proxy’nin çıkış adresini döndürür. Kendi adresinizi IP Sorgulama ile görün; listeleri topluca Proxy Kontrol, SOCKS5 el sıkışmasını SOCKS5 Kontrol ile sınayın.

06Sık sorulanlar

Geliştiricilerin sık sorduğu sorular

Hayır. Resmi SDK, kütüphane veya programlama API’si yoktur. Proxy’ler standart HTTP ve SOCKS5 protokolleriyle çalışır; bu sayfadaki örnekler her dilin standart kütüphanesini ya da o dilde yaygın, açık kaynak bir istemciyi kullanır.

Sonraki adım

Protokolü seçtiniz; şimdi doğru ürünü bulun.