Python版:
# -*- coding:utf-8 -*-
import os
import random
import socket
import threading
import select
import time
import psutil
class NetInfo(object):
@staticmethod
def get_port():
"""
Gets the free port in the specified range
:return: Available ports
"""
net_cmd = "netstat -ntl |grep -v Active| grep -v Proto|awk '{print $4}'|awk -F: '{print $NF}'"
port_list = os.popen(net_cmd).read().split("\n")
port = random.randint(1024, 65535)
if port not in port_list:
return port
else:
NetInfo.get_port()
@staticmethod
def get_net_card():
"""Get the network card Ming and IP
"""
card_list = []
for card, values in psutil.net_if_addrs().items():
if card == "lo":
continue
address = ""
for key in values:
if key.family == 2:
address = key.address
if address == "":
continue
card_list.append(card + "-" + address)
return card_list
@staticmethod
def get_local_ips():
"""Get all IP of the machine, not including 127.0.0.1"""
res = [
item[1]
for k, v in psutil.net_if_addrs().items()
for item in v
if item[0] == 2
]
if "127.0.0.1" in res:
res.remove("127.0.0.1")
return res[0]
def prxoy(sock, address):
cs = sock
DspPort = 0
DspAddr = ''
try:
recv = cs.recv(512)
VER = recv[0:1]
# MethodNum=ord(recv[1:2])
# Methods=[]
# for i in range(0,MethodNum):
# Methods.append(ord(recv[2+i:3+i]))
if (IsNeedAuth): # Need AUTHENICATION
cs.send(b'\x05\x02') # Reply
recv = cs.recv(1024)
Ver = recv[0:1]
UserLen = ord(recv[1:2])
User = recv[2:2 + UserLen]
PassLen = ord(recv[2 + UserLen:3 + UserLen])
Pass = recv[3 + UserLen:3 + UserLen + PassLen]
if (User == Username and Pass == Password):
cs.send(Ver + '\x00')
else:
cs.send(Ver + '\xff')
cs.close()
return
else:
cs.send(VER + '\x00') # NO AUTHENICATION REQUEST
try:
recv = cs.recv(1024)
except Exception, ex:
print 'Client is Closed'
return
print("recv = {}".format(recv))
CMD = ord(recv[1:2])
ATYP = ord(recv[3:4])
print("CMD = {}, ATYP = {}".format(CMD, ATYP))
if (CMD == 0x01): # CONNECT CMD
if (ATYP == 03): # DOMAINNAME
AddrLen = ord(recv[4:5])
DspPort = 256 * ord(recv[5 + AddrLen:5 + AddrLen + 1]) + ord(recv[1 + 5 + AddrLen:5 + AddrLen + 2])
DspAddr = socket.gethostbyname(recv[5:5 + AddrLen])
elif (ATYP == 01): # IPV4
if (recv.count('.') == 4): # Asiic format split by '.'
AddrLen = ord(recv[4:5])
DspAddr = recv[5:5 + AddrLen]
DspPort = 256 * ord(recv[5 + AddrLen:5 + AddrLen + 1]) + ord(recv[5 + AddrLen + 1:5 + AddrLen + 2])
else: # four hex number format
DspAddr = recv[4:8]
DspAddrr = ''
for i in DspAddr:
DspAddrr += str(ord(i)) + '.'
DspAddr = DspAddrr[:-1]
DspPort = 256 * ord(recv[4 + 4:4 + 4 + 1]) + ord(recv[4 + 4 + 1:4 + 4 + 2])
else:
print "IPV6 is not support"
return
cs.send(VER + '\x00\x00\x01\x00\x00\x00\x00\x00\x00') # REPLY
forward(cs, DspAddr, DspPort)
else:
print "Don't suport this Cmd", CMD
except Exception, e:
print e
def forward(cs, DspAddr, DspPort):
try:
# print DspAddr +'\n'
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect((DspAddr, DspPort))
except Exception, e:
print "Connect to ", DspAddr, "Fail"
return
socks = []
socks.append(cs)
socks.append(ss)
while (True):
try:
r, w, e = select.select(socks, [], [])
for s in r:
if s is cs:
recv = cs.recv(2048)
caddr, cport = cs.getpeername()
if (len(recv) > 0):
saddr, sport = ss.getpeername()
print caddr, ':', cport, '<', len(recv), '>', saddr, ':', sport
ss.send(recv)
else:
for sock in socks:
sock.close()
return
elif s is ss:
recv = ss.recv(2048)
saddr, sport = ss.getpeername()
if (len(recv) > 0):
caddr, cport = cs.getpeername()
print saddr, ':', sport, '<', len(recv), '>', caddr, ':', cport
cs.send(recv)
else:
for sock in socks:
sock.close()
return
except Exception, e:
print "Translate data error"
break
if __name__ == "__main__":
IsNeedAuth = True
Username = 'admin'
Password = '123456'
host, port = NetInfo.get_local_ips(), NetInfo.get_port()
print("host = {}, port = {}, username = {}, password = {}".format(host, port, Username, Password))
ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ls.bind((host, port))
ls.listen(500)
while (True):
clientSock, address = ls.accept()
thread = threading.Thread(target=prxoy, args=(clientSock, address))
thread.start()
C#版:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Collections;
namespace ProxyTest
{
class Program
{
static string Username = "test";
static string Password = "test";
static public bool IsRun = false;
static bool IsNeedAuth = false;
static Socket ProxySocket;
static int ListenPort = 1080;
static ArrayList ClientSocks = new ArrayList();
static int SockNum = 0;
static object obj = new object();
static void BeginProxy()
{
IsRun = true;
IPAddress ip = IPAddress.Parse("0.0.0.0");
ProxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ProxySocket.Bind(new IPEndPoint(ip, ListenPort));
ProxySocket.Listen(100);
Console.WriteLine("Bind On 0.0.0.0:" + ListenPort.ToString());
while (IsRun)
{
try
{
Socket clientSocket = ProxySocket.Accept();
Console.WriteLine(" 接受了来自 " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString() +":" +((IPEndPoint)clientSocket.RemoteEndPoint).Port.ToString() + "的连接");
ClientSocks.Add(clientSocket);
Thread T = new Thread(ProcessClient);
T.Start(clientSocket);
}
catch
{
break;
}
}
}
static void StartTransData(Socket clisock, Socket sersock)
{
int SocketNum;
byte[] RecvBuf = new byte[1024*4];
lock (obj)
{
SocketNum = ++SockNum;
}
int Len;
String DstHost = ((IPEndPoint)sersock.RemoteEndPoint).Address.ToString() + ":";
DstHost += ((IPEndPoint)sersock.RemoteEndPoint).Port.ToString();
String SrcHost = ((IPEndPoint)sersock.LocalEndPoint).Address.ToString() + ":";
SrcHost += ((IPEndPoint)sersock.LocalEndPoint).Port.ToString();
while (IsRun)
{
try
{
if (clisock.Poll(1000, SelectMode.SelectRead))
{
Len = clisock.Receive(RecvBuf);
if (Len == 0)
{
clisock.Shutdown(SocketShutdown.Both);
clisock.Close();
sersock.Shutdown(SocketShutdown.Both);
sersock.Close();
break;
}
else
{
Len = sersock.Send(RecvBuf, 0, Len, 0);
Console.WriteLine("【" + SockNum.ToString() + "】" + SrcHost + "==>" + DstHost + "[发送" + Len.ToString() + "字节]");
}
}
if (sersock.Poll(1000, SelectMode.SelectRead))
{
Len = sersock.Receive(RecvBuf);
if (Len == 0)
{
sersock.Shutdown(SocketShutdown.Both);
sersock.Close();
clisock.Shutdown(SocketShutdown.Both);
clisock.Close();
break;
}
else
{
Len = clisock.Send(RecvBuf, 0, Len, 0);
Console.WriteLine("【" + SockNum.ToString() + "】" + DstHost + " ==> " + SrcHost + " [接收" + Len.ToString() + "字节]");
}
}
}
catch
{
break;
}
}
}
static void ProcessClient(object sock)
{
byte[] RecvBuf = new byte[1024];
Socket CliSock = (Socket)sock;
Socket ServerSock;
IPAddress ip = null;
int Port = 0;
byte[] buf = new byte[1024];
int Len = 0;
try
{
Len = CliSock.Receive(buf);
byte SockVer = buf[0];
if (IsNeedAuth)
{
CliSock.Send(new byte[] { 0x05, 0x02 }); //需要验证
Len = CliSock.Receive(buf);
byte UserLen = buf[1];
byte[] User = new byte[UserLen];
Buffer.BlockCopy(buf, 2, User, 0, UserLen);
byte PassLen = buf[2 + UserLen];
byte[] Pass = new byte[PassLen];
Buffer.BlockCopy(buf, 3 + PassLen, Pass, 0, PassLen);
if (Encoding.ASCII.GetString(User) == Username && Encoding.ASCII.GetString(Pass) == Password)
{
CliSock.Send(new byte[] { 0x05, 0x00 });
}
else
{
CliSock.Send(new byte[] { 0x05, 0xff });
CliSock.Close();
}
}
else
{
CliSock.Send(new byte[] { 0x05, 0x00 });
}
}
catch
{
}
try
{
Len = CliSock.Receive(RecvBuf);
byte CMD = RecvBuf[1];
byte ATYP = RecvBuf[3];
if (CMD == 0x01)
{
if (ATYP == 0x01)
{
if (RecvBuf.ToString().Split('.').Length == 5)
{
byte AddrLen = RecvBuf[4];
byte[] Addr = new byte[AddrLen];
Buffer.BlockCopy(RecvBuf, 5, Addr, 0, AddrLen);
IPAddress[] ips = Dns.GetHostAddresses(Addr.ToString());
ip = ips[0];
Port = 256 * RecvBuf[AddrLen + 5] + RecvBuf[AddrLen + 6];
}
else
{
byte[] Addr = new byte[4];
Buffer.BlockCopy(RecvBuf, 4, Addr, 0, 4);
String sip = "";
foreach (byte b in Addr)
{
sip += b.ToString() + ".";
}
IPAddress[] ips = Dns.GetHostAddresses(sip.Remove(sip.Length - 1));
ip = ips[0];
Port = 256 * RecvBuf[9] + RecvBuf[10];
}
}
else if (ATYP == 0x03)
{
byte AddrLen = RecvBuf[4];
byte[] Addr = new byte[AddrLen];
Buffer.BlockCopy(RecvBuf, 5, Addr, 0, AddrLen);
String HostName = System.Text.Encoding.Default.GetString(Addr);
IPAddress[] ips = Dns.GetHostAddresses(HostName);
ip = ips[0];
Port = 256 * RecvBuf[AddrLen + 5] + RecvBuf[AddrLen + 6];
}
else
{
return;
}
CliSock.Send(new byte[] { 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
}
}
catch
{
return;
}
try
{
ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerSock.Connect(ip, Port);
StartTransData(CliSock, ServerSock);
}
catch
{
CliSock.Shutdown(SocketShutdown.Both);
CliSock.Close();
return;
}
}
static void Main(string[] args)
{
BeginProxy();
}
}
}