I have the following problem:
I want to start a proxy on a server that client PCs can access. Currently, the ps1 script starts an HTTP proxy and also runs an HTTP-to-HTTPS script that redirects all HTTP requests to HTTPS. The HTTP proxy is tunneled through serveo.net, which provides a public URL.
When I enter this URL as a proxy in Firefox as an HTTP proxy (you need to omit https:// and the / at the end) and set the HTTP proxy to port 80, the client can continue browsing the Internet. However, it does not use the IP and geolocation of the proxy server.
And that is exactly the point I want to achieve:
To start a proxy on a server that clients can use and to be able to browse the web with the IP and geolocation of the proxy server in their own browser.
Here is the code:
# Temporäres Verzeichnis für die Portable Python-Installation und Arbeitsdateien
$TempDir = "$env:TEMPPortablePython"
# Sicherstellen, dass das Verzeichnis existiert
if (-Not (Test-Path $TempDir)) {
New-Item -ItemType Directory -Path $TempDir
}
# Portable Python herunterladen und installieren
$PythonZip = "$TempDirpython-3.9.5-embed-amd64.zip"
Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.9.5/python-3.9.5-embed-amd64.zip" -OutFile $PythonZip
Expand-Archive -Path $PythonZip -DestinationPath $TempDir
Remove-Item -Path $PythonZip
# Python-Skripte für Proxy und Tunnel erstellen
$ScriptPath = "$PSScriptRoot"
$HTTPSProxyScript = @"
from http.server import BaseHTTPRequestHandler, HTTPServer
import ssl
class HTTPSProxy(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b'Hello, this is a simple HTTPS proxy.')
def do_CONNECT(self):
self.send_response(200, 'Connection Established')
self.end_headers()
conn = ssl.wrap_socket(self.connection, server_side=False, keyfile='./key.pem', certfile='./cert.pem', ssl_version=ssl.PROTOCOL_TLS)
while True:
data = conn.recv(1024)
if not data:
break
conn.send(data)
def run(server_class=HTTPServer, handler_class=HTTPSProxy, port=8443):
server_address = ('127.0.0.1', port)
httpd = server_class(server_address, handler_class)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='./cert.pem', keyfile='./key.pem', server_side=True)
print(f'Starting HTTPS proxy on 127.0.0.1:{port}...')
httpd.serve_forever()
if __name__ == "__main__":
run()
"@
$HTTPToHTTPSProxyScript = @"
from http.server import BaseHTTPRequestHandler, HTTPServer
import http.client
import urllib.parse
import ssl
class HTTPToHTTPSProxy(BaseHTTPRequestHandler):
def do_GET(self):
parsed_url = urllib.parse.urlparse(self.path)
try:
conn = http.client.HTTPSConnection('127.0.0.1', 8443, context=ssl._create_unverified_context())
conn.request('GET', parsed_url.path)
response = conn.getresponse()
self.send_response(response.status)
self.send_header('Content-type', response.getheader('Content-Type'))
self.end_headers()
self.wfile.write(response.read())
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(b'Error occurred during the request.')
def do_CONNECT(self):
parsed_url = urllib.parse.urlparse(self.path)
try:
self.send_response(200, 'Connection Established')
self.end_headers()
conn = http.client.HTTPSConnection(parsed_url.hostname, parsed_url.port or 443, context=ssl._create_unverified_context())
self.connection.settimeout(10)
conn.set_tunnel(parsed_url.hostname, parsed_url.port or 443)
conn.request('CONNECT', parsed_url.path)
response = conn.getresponse()
self.wfile.write(response.read())
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(b'Error occurred during the CONNECT request.')
def run(server_class=HTTPServer, handler_class=HTTPToHTTPSProxy, port=8080):
server_address = ('127.0.0.1', port)
httpd = server_class(server_address, handler_class)
print(f'Starting HTTP-to-HTTPS proxy on 127.0.0.1:{port}...')
httpd.serve_forever()
if __name__ == "__main__":
run()
"@
$HTTPSProxyScriptPath = "$ScriptPathhttps_proxy.py"
$HTTPToHTTPSProxyScriptPath = "$ScriptPathhttp_to_https_proxy.py"
# Skripte erstellen
$HTTPSProxyScript | Out-File -FilePath $HTTPSProxyScriptPath -Encoding UTF8
$HTTPToHTTPSProxyScript | Out-File -FilePath $HTTPToHTTPSProxyScriptPath -Encoding UTF8
# Starten der Python-Skripte
Start-Process -FilePath "$TempDirpython.exe" -ArgumentList $HTTPSProxyScriptPath -NoNewWindow -PassThru
Start-Process -FilePath "$TempDirpython.exe" -ArgumentList $HTTPToHTTPSProxyScriptPath -NoNewWindow -PassThru
# Warten, bis die Python-Skripte gestartet sind
Start-Sleep -Seconds 5
# Tunnel über Serveo.net erstellen
$tunnel = Start-Process -FilePath "ssh" -ArgumentList "-R 80:127.0.0.1:8080 serveo.net" -NoNewWindow -PassThru
# Informiere den Benutzer über den Status
Write-Host "Proxy server and tunnel setup complete. Use the Serveo URL as your proxy server in Firefox."
As described above, the clients should simply use the IP and geolocation of the proxy server through the proxy URL.