1

Is it possible to create a module(man-in-the-middle like) that filter request to a local server?

I have a HTTPS server and some rules for requests that shouldn't reach the server(which i will like to implement in a different module). What i am trying to do, is a module through which the client communicates with the server, but on the server side. The idea is that the module should intercept only the requests that are coming to the server(on a certain port) and it decides if the requests will be forwarded to the server and the server should receive request only through that module.

Is it possible to do something like this in python?

Alexvdan
  • 141
  • 2
  • 10

1 Answers1

1

You can try to use twisted reverse proxy. Look here for https reverse proxy example: Python-Twisted: Reverse Proxy to HTTPS API: Could not connect

You should change it to start on 443 port (use ssl) and add some logic. For example:

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)

To use https (start proxy on 443 port), try this snippet (from here 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()
ndpu
  • 22,225
  • 6
  • 54
  • 69