Skip to content

Latest commit

 

History

History
164 lines (134 loc) · 3.93 KB

File metadata and controls

164 lines (134 loc) · 3.93 KB

my-proxy

My Local proxy (socks5h) with realtime debugging and logs.

How to start

Start first proxy server after server started then you use what you want like curl, or wget or npm install or composer install.

php socks5h.php

Set Proxy

Set local proxy server

export ALL_PROXY="socks5h://127.0.0.1:10080"
export HTTP_PROXY="socks5h://127.0.0.1:10080"
export HTTPS_PROXY="socks5h://127.0.0.1:10080"

Source code:

<?php
/**
 * SOCKS5 proxy with request + traffic logging
 * Works with Composer, curl, browsers
 * PHP 8+
 */

set_time_limit(0);
error_reporting(E_ALL);

$LISTEN_ADDR = '127.0.0.1';
$LISTEN_PORT = 10080;
$LOG_FILE    = __DIR__ . '/logs/socks.log';

/* -------------------- LOGGER -------------------- */
function log_line(string $msg): void
{
    global $LOG_FILE;
    file_put_contents(
        $LOG_FILE,
        '[' . date('Y-m-d H:i:s') . '] ' . $msg . PHP_EOL,
        FILE_APPEND | LOCK_EX
    );
}

/* -------------------- SERVER -------------------- */
$server = stream_socket_server(
    "tcp://{$LISTEN_ADDR}:{$LISTEN_PORT}",
    $errno,
    $errstr
);

if (!$server) {
    die("Server error: $errstr\n");
}

echo "✅ SOCKS5 proxy listening on {$LISTEN_ADDR}:{$LISTEN_PORT}\n";
log_line("SERVER started on {$LISTEN_ADDR}:{$LISTEN_PORT}");

/* -------------------- MAIN LOOP -------------------- */
while ($client = stream_socket_accept($server)) {

    $peer = stream_socket_get_name($client, true);
    log_line("CLIENT connected from {$peer}");

    /* ---- 1) GREETING ---- */
    $greeting = fread($client, 262);
    if (!$greeting || ord($greeting[0]) !== 0x05) {
        log_line("ERROR invalid SOCKS version");
        fclose($client);
        continue;
    }

    // No authentication
    fwrite($client, "\x05\x00");

    /* ---- 2) REQUEST ---- */
    $request = fread($client, 262);
    if (!$request || ord($request[1]) !== 0x01) {
        log_line("ERROR unsupported command");
        fclose($client);
        continue;
    }

    $atype = ord($request[3]);
    $offset = 4;

    if ($atype === 0x01) {              // IPv4
        $addr = inet_ntop(substr($request, $offset, 4));
        $offset += 4;
    } elseif ($atype === 0x03) {         // DOMAIN
        $len  = ord($request[$offset]);
        $offset++;
        $addr = substr($request, $offset, $len);
        $offset += $len;
    } else {
        log_line("ERROR address type not supported");
        fclose($client);
        continue;
    }

    $port = unpack('n', substr($request, $offset, 2))[1];
    log_line("CONNECT {$addr}:{$port}");

    /* ---- 3) CONNECT TARGET ---- */
    $remote = @stream_socket_client(
        "tcp://{$addr}:{$port}",
        $e,
        $es,
        10
    );

    if (!$remote) {
        log_line("ERROR connect failed {$addr}:{$port}");
        fwrite($client, "\x05\x01\x00\x01\0\0\0\0\0\0");
        fclose($client);
        continue;
    }

    // Success reply
    fwrite($client, "\x05\x00\x00\x01\0\0\0\0\0\0");

    /* ---- 4) TUNNEL + LOGGING ---- */
    stream_set_blocking($client, false);
    stream_set_blocking($remote, false);

    $bytesUp = 0;
    $bytesDown = 0;
    $write=null;
    $ecept=null;
    $start = microtime(true);

    while (!feof($client) && !feof($remote)) {
        $read = [$client, $remote];
        if (stream_select($read, $write, $ecept, 1) === false) {
            break;
        }

        foreach ($read as $sock) {
            $data = fread($sock, 8192);
            if ($data === '' || $data === false) {
                continue;
            }

            if ($sock === $client) {
                $bytesUp += strlen($data);
                fwrite($remote, $data);
            } else {
                $bytesDown += strlen($data);
                fwrite($client, $data);
            }
        }
    }

    $duration = round(microtime(true) - $start, 3);
    log_line("DONE {$addr}:{$port}{$bytesUp}B ↓{$bytesDown}B {$duration}s");

    fclose($client);
    fclose($remote);
}