Python 简单的 HTTPS 转发器

Python simple HTTPS forwarder

下面是我用来重定向端口 8080 上的常规 HTTP 请求的简单脚本,它会立即根据源 IP 地址重定向(至少使它们成为)它们。

它有效(对于 HTTP),但是我希望对来自 443 端口的 HTTPS 请求具有相同的行为。假设如果不存在重定向,则传入此简单服务器的客户端将能够通过自签名证书与重定向到的目标握手。

import SimpleHTTPServer
import SocketServer

LISTEN_PORT = 8080
source = "127.0.0.1"
target = "http://target/"

class simpleHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_POST(self):
        clientAddressString = ''.join(str(self.clientAddress))

        if source in clientAddressString:
            # redirect incoming request
            self.send_response(301)
            new_path = '%s%s' % (target, self.path)
            self.send_header('Location', new_path)
            self.end_headers()

handler = SocketServer.TCPServer(("", LISTEN_PORT), simpleHandler)
handler.serve_forever()

我可以使用自签名证书并可以访问通常用于此连接的文件 "server.crt" 和 "server.key"(无需中间重定向 python 服务器)。我不确定当我像这样在两者之间放置重定向时会发生什么,尽管我认为它必须是 hand-shaking 链的一部分。

我怎样才能实现这种行为?

除了请求中的新目标和响应代码之外,还有什么我应该修改的吗headers?

我会将我的回答分为网络和 Python 部分。

Networking 端,您不能在 SSL 层重定向 - 因此您需要一个完整的 HTTPs 服务器,并在 SSL 握手完成后重定向 GET/POST 请求完全的。 HTTP 和 HTTPs 的响应代码和实际 do_POSTdo_GET 实现完全相同。

附带说明一下,您在重定向 POST 时没有遇到任何问题吗?当您在 POST 上执行 301 时,浏览器不会将 POST 数据重新发送到您的新目标,因此应用程序级别可能会出现问题。

Python 方面,您可以通过包装套接字将 HTTP 服务器扩展为 HTTPs 服务器:

import BaseHTTPServer, SimpleHTTPServer
import ssl

handler = BaseHTTPServer.HTTPServer(("", LISTEN_PORT), simpleHandler)
handler.socket = ssl.wrap_socket (handler.socket, certfile='path/to/combined/PKCS12/container', server_side=True)
handler.serve_forever()

希望对您有所帮助。