🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
70 lines
1.8 KiB
JavaScript
Executable File
70 lines
1.8 KiB
JavaScript
Executable File
const net = require('net');
|
|
|
|
const PORT = 1080;
|
|
const HOST = '0.0.0.0';
|
|
|
|
const server = net.createServer((client) => {
|
|
client.once('data', (data) => {
|
|
// SOCKS5 handshake
|
|
if (data[0] !== 0x05) {
|
|
client.end();
|
|
return;
|
|
}
|
|
|
|
// No auth required
|
|
client.write(Buffer.from([0x05, 0x00]));
|
|
|
|
client.once('data', (data) => {
|
|
if (data[0] !== 0x05 || data[1] !== 0x01) {
|
|
client.write(Buffer.from([0x05, 0x07, 0x00, 0x01, 0, 0, 0, 0, 0, 0]));
|
|
client.end();
|
|
return;
|
|
}
|
|
|
|
let host, port;
|
|
const atyp = data[3];
|
|
|
|
if (atyp === 0x01) {
|
|
// IPv4
|
|
host = `${data[4]}.${data[5]}.${data[6]}.${data[7]}`;
|
|
port = data.readUInt16BE(8);
|
|
} else if (atyp === 0x03) {
|
|
// Domain
|
|
const len = data[4];
|
|
host = data.slice(5, 5 + len).toString();
|
|
port = data.readUInt16BE(5 + len);
|
|
} else if (atyp === 0x04) {
|
|
// IPv6
|
|
host = '';
|
|
for (let i = 0; i < 16; i += 2) {
|
|
host += data.slice(4 + i, 6 + i).toString('hex');
|
|
if (i < 14) host += ':';
|
|
}
|
|
port = data.readUInt16BE(20);
|
|
} else {
|
|
client.write(Buffer.from([0x05, 0x08, 0x00, 0x01, 0, 0, 0, 0, 0, 0]));
|
|
client.end();
|
|
return;
|
|
}
|
|
|
|
const remote = net.createConnection(port, host, () => {
|
|
const response = Buffer.from([0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0]);
|
|
client.write(response);
|
|
client.pipe(remote);
|
|
remote.pipe(client);
|
|
});
|
|
|
|
remote.on('error', () => {
|
|
client.write(Buffer.from([0x05, 0x05, 0x00, 0x01, 0, 0, 0, 0, 0, 0]));
|
|
client.end();
|
|
});
|
|
});
|
|
});
|
|
|
|
client.on('error', () => {});
|
|
});
|
|
|
|
server.listen(PORT, HOST, () => {
|
|
console.log(`SOCKS5 proxy running on ${HOST}:${PORT}`);
|
|
});
|