这里的代理服务器,是指二级代理服务器。
比如:A可以访问B,B可以访问C,A不能直接访问C。这时,如果在B开一个二级代理,就可实现A访问C。现有的工具有CCProxy。原文为python2
这里就是使用Python简单的实现一个二级代理。
import os
import logging
import socket
import select
import sys
logsDir = "logs"
if not os.path.isdir(logsDir):
os.mkdir(logsDir)
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a,%d %b %Y %H:%M:%S ',
filename='logs/logs.log',
filemode='a')
to_addr=('136.158.20.3',3389)#目标主机,就是上面的C机
maxConnections = 32
class Proxy:
def __init__(self,addr):
self.proxy = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.proxy.bind(addr)
self.proxy.listen(maxConnections)
self.inputs = {self.proxy:None}
self.route = {}
def serve_forever(self):
logging.info('proxy listen....')
while 1:
readable,_,_=select.select(list(self.inputs.keys()),[],[])
for self.sock in readable:
if self.sock == self.proxy:
self.on_join()
else:
try:
data = self.sock.recv(8192)
except Exception as e:
logging.error(str(e))
self.on_quit()
continue
if not data:
self.on_quit()
else:
try:
self.route[self.sock].send(data)
except Exception as e:
logging.error(str(e))
self.on_quit()
continue
def on_join(self):
client,addr = self.proxy.accept()
logging.info("proxy client "+str(addr)+' connect')
forward = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
forward.connect(to_addr)
except Exception as e:
logging.error(str(e))
client.close()
return
self.inputs[client] = None
self.inputs[forward] = None
self.route[client] = forward
self.route[forward] = client
def on_quit(self):
ls = [self.sock]
if self.sock in self.route:
ls.append(self.route[self.sock])
for s in ls:
if s in self.inputs:
del self.inputs[s]
if s in self.route:
del self.route[s]
s.close()
if __name__ == "__main__":
try:
Proxy(('',8192)).serve_forever()
except KeyboardInterrupt as e:
logging.error("KeyboardInterrupt"+str(e))
# ————————————————
# 版权声明:本文为CSDN博主「xsjyahoo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# 原文链接:https://blog.csdn.net/xsjyahoo/article/details/51568712
实现二:
# coding:utf8
# 创建一个 TCP 代理
import sys
import socket
import threading
def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 服务器监听的 host和端口
server.bind((local_host, local_port))
except Exception as e:
print("[!!] Failed to listen on %s:%d" % (local_host, local_port))
print("[!!] Check for other listening sockets or correct permissions")
sys.exit(0)
print("[*] Listening on %s:%d" % (local_host, local_port))
#开始监听TCP传入连接
server.listen(5)
while True:
# 获取客户端请求过来的数据
client_socket, addr = server.accept()
# 打印出本地客户端连接的信息
print("[==>] Received incoming connection from %s:%d" % (addr[0], addr[1]))
# 开启一个线程 与 远程主机通信
proxy_thread = threading.Thread(target=proxy_handler, args=(client_socket, remote_host, remote_port, receive_first))
proxy_thread.start()
# 十六进制转储的函数
def hexdump(src, length=16):
result = []
digits = 4 if isinstance(src, bytes) else 2 #isinstance(src,unicode)
for i in range(0, len(src), length):
s = src[i:i+length]
hexa = b' ' . join(["%0*X" % (digits, ord(x)) for x in s])
text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
result.append(b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text))
print(b'\n'.join(result))
# 从远程服务器里面接受数据
def receive_from(connection):
print("receive_from function start ........... ")
buffer = ""
# 我们设置了两秒的超时, 这取决于目标的情况, 可能需要调整
connection.settimeout(2)
try:
# 持续从缓存中读取数据直到没有数据或者超时
while True:
data = connection.recv(4096)
print("receive_from data is %s " % data)
if not data:
print("receive_from data is break .......")
break
buffer += data
except Exception as e:
print(str(e))
#print(str(e))
print('error for receive_from')
return buffer
# 对目标是远程主机的请求进行修改
def request_handler(buffer):
#执行包修改
return buffer
# 对目标是本地主机的响应进行修改
def response_handler(buffer):
#执行包修改
return buffer
def proxy_handler(client_socket, remote_host, remote_port, receive_first):
# 连接远程主机
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("remote_socket start ...... %s %d" % (remote_host, remote_port))
remote_socket.connect((remote_host, remote_port))
# 如果必要从远程主机接收数据
if receive_first:
remote_buffer = receive_from(remote_socket)
hexdump(remote_buffer)
# 发送给我们的响应处理
remote_buffer = response_handler(remote_buffer)
# 如果我们有数据传递给本地客户端,发送它
if len(remote_buffer):
print("[<==] Sending %d bytes to localhost." % len(remote_buffer))
client_socket.send(remote_buffer)
# 现在我们从本地循环读取数据, 发送给远处主机和本地主机
while True:
# 从本地读取数据
local_buffer = receive_from(client_socket)
print("local_buffer is %s " % local_buffer)
if len(local_buffer):
print("[==>] Received %d bytes from localhost." % len(local_buffer))
hexdump(local_buffer)
# 这里可以改变我们请求的数据 过滤等功能
local_buffer = request_handler(local_buffer)
# 向远处主机发送数据
remote_socket.send(local_buffer)
print("[==>] Sent to remote.")
# 接收响应的数据
remote_buffer = receive_from(remote_socket)
if len(remote_buffer):
print("[<==] Received %d bytes from remote." % len(remote_buffer))
hexdump(remote_buffer)
# 发送到响应处理函数
remote_buffer = response_handler(remote_buffer)
# 将响应发送给本地socket
client_socket.send(remote_buffer)
# 如果两边都没有数据, 关闭连接
if not len(local_buffer) or not len(remote_buffer):
client_socket.close()
remote_socket.close()
print("[*] No more data. Closing connections.")
sys.exit(0)
break
def main():
if len(sys.argv[1:]) != 5:
print("Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]")
print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
# 设置本地监听参数
local_host = sys.argv[1]
local_port = int(sys.argv[2])
# 设置远程目标
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
# 告诉代理在发送给远程主机之前连接和接受数据
receive_first = sys.argv[5]
if "True" in receive_first:
receive_first = True
else:
receive_first = False
# 设置好我们的监听 socket
server_loop(local_host, local_port, remote_host, remote_port, receive_first)
main()