I have two computers computer 1
and computer 2
on the same network. I’m trying to make computer 1
act as a proxy server so when I send a request from computer 2
using its ip address as a proxy, the request will pass through computer 1
.
After trying multiple approaches, this is my code on the client side:
import requests
# Proxy server settings
PROXY_HOST = '192.168.1.112'
PROXY_PORT = 8888
url = 'https://www.google.com'
proxies = {
'http': f'http://{PROXY_HOST}:{PROXY_PORT}',
'https': f'http://{PROXY_HOST}:{PROXY_PORT}'
}
try:
response = requests.get(url, proxies=proxies)
print("Response from server:")
print(response.content.decode('utf-8'))
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
And this is the code on my server side (computer 1
):
import socket
import threading
import ssl
LOCAL_HOST = '0.0.0.0'
PROXY_PORT = 8888
def handle_client(client_socket):
request = client_socket.recv(4096)
print(f"Received request from client: {request}")
first_line = request.split(b'n')[0]
method = first_line.split()[0]
if method == b'CONNECT':
handle_https(client_socket, request)
else:
handle_http(client_socket, request)
def handle_https(client_socket, request):
# Extract the host and port from the CONNECT request
first_line = request.split(b'n')[0]
host, port = first_line.split()[1].split(b':')
port = int(port)
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((host.decode('utf-8'), port))
client_socket.send(b'HTTP/1.1 200 OKnn')
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
client_ssl = context.wrap_socket(client_socket, server_side=True)
remote_ssl = context.wrap_socket(remote_socket, server_hostname=host.decode('utf-8'))
forward_data(client_ssl, remote_ssl)
def handle_http(client_socket, request):
remote_host = 'www.example.com'
remote_port = 80
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((remote_host, remote_port))
remote_socket.send(request)
remote_response = remote_socket.recv(4096)
print(f"Received response from remote server: {remote_response}")
client_socket.send(remote_response)
remote_socket.close()
client_socket.close()
def forward_data(sock1, sock2):
sockets = [sock1, sock2]
while True:
for sock in sockets.copy():
try:
data = sock.recv(4096)
if data:
other_sock = sock2 if sock == sock1 else sock1
other_sock.sendall(data)
else:
sock.close()
sockets.remove(sock)
except Exception as e:
print(f"Error: {e}")
sock.close()
sockets.remove(sock)
def start_proxy_server():
proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxy_socket.bind((LOCAL_HOST, PROXY_PORT))
proxy_socket.listen(5)
print(f"Proxy server listening on port {PROXY_PORT}...")
while True:
client_socket, addr = proxy_socket.accept()
print(f"Accepted connection from {addr[0]}:{addr[1]}")
# Handle client request in a separate thread
client_handler = threading.Thread(target=handle_client, args=(client_socket,))
client_handler.start()
if __name__ == '__main__':
start_proxy_server()
If I send an http request that works well, but when sending an https request I’m getting this error on the server side during the handshake proccess:
ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1000)
I tried to add this to my code but it didn’t help:
cipher = 'DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256'
context.set_ciphers(cipher)