Home What Is a Proxy Server? How to Build a Simple Socks5 Proxy with NodeJS

How to Build a Simple Socks5 Proxy with NodeJS

user profile
Pandada Article published on 2023-10-19
Review
5.00
0

Setting Up a Simple Socks5 Proxy Server with Node.js

This code is a simple implementation of a SOCKS5 Proxy Server using Node.js's net module. A SOCKS5 Proxy Server forwards client network requests to target servers. It supports various address types, including IPv4, IPv6, and domain names. In this implementation, the supported operation is CONNECT, which establishes a TCP connection.

Code Functionality Explained

  • Import Modules:
    const net = require('net');
    Import the Node.js net module to create TCP servers and clients.
  • Create Server:
    let server = net.createServer(function (socket) {
    // Server logic
    });
    Use the net.createServer method to create a TCP server. Whenever a new client connects, the callback function is executed, where the socket object represents the connection with the client.
  • Handle Client Data:
    socket.once('data', function (data) {
            // Handle data sent by the client
    });
    Use socket.once to listen for the first chunk of data sent by the client, which is usually the SOCKS5 handshake request.
  • Validate SOCKS5 Protocol:
    if (!data || data[0] !== 0x05) return socket.destroy();
    Validate that the data sent by the client conforms to the SOCKS5 protocol. If not, destroy the connection.
  • Send Response:
    socket.write(Buffer.from([5, 0]), function (err) {
            // Logic after sending response
    });
    Send a response to the client indicating that no authentication is needed.
  • Handle Connection Request:
    socket.once('data', (data) => {
            // Parse target address and port, and establish connection
    });
    Listen again for data from the client, which this time is the connection request. Parse the target address and port, then attempt to connect to the target server.
  • Establish Connection to Target Server:
    let remote = net.connect(remotePort, remoteAddr, function () {
             // Logic after successful connection
    });
    Use the net.connect method to try connecting to the target server. On success, execute the callback function.
  • Data Forwarding:
    remote.pipe(socket);
    socket.pipe(remote);
    Use the pipe method to achieve bidirectional data forwarding between the client and the target server.
  • Error Handling:
    remote.on('error', function (err) {
            // Handle errors connecting to the target server
    });
    socket.on('error', function (err) {
    // Handle client connection errors
    });
    Listen for error events and destroy the corresponding connection when an error occurs.
  • Start Server:
    server.listen(11100);
    The server listens on port 11100, waiting for client connections.
  • Complete Code

    const net = require('net');
    const net = require('net');
    let server = net.createServer(function (socket) {
        socket.once('data', function (data) {
            if (!data || data[0] !== 0x05) return socket.destroy();
            let addrLen = 0, remoteAddr = null, remotePort = null;
            socket.write(Buffer.from([5, 0]), function (err) {
                if (err) socket.destroy();
                socket.once('data', (data) => {
                    if (data.length < 7 || data[1] !== 0x01) return socket.destroy();  // Only supports CONNECT 
                    try {
                        addrtype = data[3]; // ADDRESS_TYPE target server address type
                        if (addrtype === 3) {  // 0x03 domain address
                            addrLen = data[4];  // The first byte of the domain address is the length, the remaining bytes are the domain name byte array
                        } else if (addrtype !== 1 && addrtype !== 4) {
                            return socket.destroy();
                        }
                        remotePort = data.readUInt16BE(data.length - 2); // The last two bytes are the port value
                        if (addrtype === 1) {  // 0x01 IP V4 address
                            remoteAddr = data.slice(3, 7).join('.');
                        } else if (addrtype === 4) {  // 0x04 IP V6 address
                            // remoteAddr = data.slice(3, 19);// IP V6 length is 16
                            return socket.write(Buffer.from([0x05, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));  // Do not support IP V6
                        } else {  // 0x03 domain address, the first byte is the length, the remaining bytes are the domain name byte array
                            remoteAddr = data.slice(5, 5 + addrLen).toString("binary");
                        }
                        let remote = net.connect(remotePort, remoteAddr, function () {
                            console.log(`connecting : ${remoteAddr}:${remotePort}`);
                            socket.write(Buffer.from([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), function (err) {
                                if (err) {
                                    console.error(`error:${err.message}`);
                                    return socket.destroy();
                                }
                                remote.pipe(socket);
                                socket.pipe(remote);
                            });
                        });
                        remote.on('error', function (err) {
                            console.error(`Failed to connect to remote server ${remoteAddr}:${remotePort}, error: ${err.message}`);
                            remote.destroy();
                            socket.destroy();
                        });
                    } catch (e) {
                        console.error(e);
                    }
                });
            });
        });
        socket.on('error', function (err) { console.error(`error:${err.message}`); });
    });
    server.listen(11100);
    
    

    Usage

  • Save the above code as socks5.js.
  • Run node socks5.js in the command line to start the SOCKS5 Proxy Server.
  • Configure your client to use the SOCKS5 proxy, setting the proxy address to the server's IP and port 11100.
  • Notes

    • This code is a simple implementation and does not include advanced features like authentication.
    • Consider security and performance optimizations when using in a production environment.
    • If you need to support more SOCKS5 protocol features, further code extensions are required.

    How to Build a Simple Socks5 Proxy with NodeJS Review FAQ

    SOCKS5 (Socket Secure 5) is a network protocol used for proxy services. It allows users to route their network connections through a proxy server to bypass geographic restrictions or enhance privacy. Like Shadowsocks and other proxy tools, SOCKS5 proxies can be used to protect user privacy and access restricted websites.

    You can configure proxy server information in your browser settings. In the configuration, you need to specify the IP address and port number of the SOCKS5 proxy server. Once configured, all network requests from the browser will be routed through the specified proxy server.
    Previous 24 Anti-fingerprint browsers (Summary) Browser fingerprinting technol...
    Next Detailed Explanation of Proxy Server Types and Uses Proxy Server are crucial tools...
    blog
    20 Popular SOCKS5 Pr...

    Proxy connection tools are pow...

    blog
    How to Use a SOCKS5 ...

    Using the v2rayNG app to set u...

    blog
    15+ Cheap and Reliab...

    Discover the best Socks5 Proxi...

    blog
    What is a SOCKS5 Pro...

    In today's interconnected glob...

    Please contact us directly via email [email protected]

    Curated Vendors