拦截并过滤对python中的HTTPS服务器的请求?

时间:2018-08-17 10:55:52

标签: python https server proxy

是否可以创建一个模块(像中间人一样)来过滤对本地服务器的请求?

我有一个HTTPS服务器和一些不应该到达服务器的请求规则(我想在另一个模块中实现)。我正在尝试做的是一个模块,客户端通过该模块与服务器通信,但在服务器端。这个想法是,模块应该仅拦截(在某个端口上)到达服务器的请求,并决定是否将请求转发到服务器,并且服务器应仅通过该模块接收请求。

是否可以在python中做类似的事情?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用扭曲的反向代理。在此处查看https反向代理示例:Python-Twisted: Reverse Proxy to HTTPS API: Could not connect

您应该将其更改为从443端口启动(使用ssl)并添加一些逻辑。例如:

class LocalResource(Resource):
    def render(self, request):
        return "Banned"


class HTTPSReverseProxyResource(proxy.ReverseProxyResource, object):
    def proxyClientFactoryClass(self, *args, **kwargs):
        """
        Make all connections using HTTPS.
        """
        return TLSMemoryBIOFactory(
            ssl.optionsForClientTLS(self.host.decode("ascii")), True,
            super(HTTPSReverseProxyResource, self)
            .proxyClientFactoryClass(*args, **kwargs))

    def getChild(self, path, request):
        if any([re.match(url, path) for url in banned_urls]):
            return LocalResource()
        else:
            child = super(HTTPSReverseProxyResource, self).getChild(path, request)
            return HTTPSReverseProxyResource(child.host, child.port, child.path,
                                             child.reactor)

要使用https(在443端口上启动代理),请尝试以下代码段(从https://github.com/fmoo/twisted-connect-proxy开始):

if __name__ == '__main__':
    import argparse
    ap = argparse.ArgumentParser()
    ap.add_argument('port', default=8080, nargs='?', type=int)
    ap.add_argument('--ssl-cert', type=str)
    ap.add_argument('--ssl-key', type=str)
    ns = ap.parse_args()

    if ns.ssl_cert:
        from twisted.internet import ssl
        with open(ns.ssl_cert, 'rb') as fp:
            ssl_cert = fp.read()
        if ns.ssl_key:
            from OpenSSL import crypto
            with open(ns.ssl_key, 'rb') as fp:
                ssl_key = fp.read()
            ftype = crypto.FILETYPE_PEM
            k = ssl.KeyPair.load(ssl_key, ftype)
            certificate = ssl.PrivateCertificate.load(ssl_cert, k, ftype)
        else:
            certificate = ssl.PrivateCertificate.loadPEM(ssl_cert)

        srv = HTTPSReverseProxyResource('your_main_server', 443 , '')
        reactor.listenSSL(ns.port, srv, certificate.options())
        reactor.run()