【发布时间】:2018-08-17 10:55:51
【问题描述】:
是否可以创建一个模块(类似中间人)来过滤对本地服务器的请求?
我有一个 HTTPS 服务器和一些不应该到达服务器的请求规则(我想在不同的模块中实现)。我想要做的是一个模块,客户端通过它与服务器通信,但在服务器端。这个想法是模块应该只拦截到达服务器的请求(在某个端口上),它决定是否将请求转发到服务器,服务器应该只通过该模块接收请求。
在python中可以做这样的事情吗?
【问题讨论】:
是否可以创建一个模块(类似中间人)来过滤对本地服务器的请求?
我有一个 HTTPS 服务器和一些不应该到达服务器的请求规则(我想在不同的模块中实现)。我想要做的是一个模块,客户端通过它与服务器通信,但在服务器端。这个想法是模块应该只拦截到达服务器的请求(在某个端口上),它决定是否将请求转发到服务器,服务器应该只通过该模块接收请求。
在python中可以做这样的事情吗?
【问题讨论】:
您可以尝试使用扭曲的反向代理。在此处查找 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 端口上启动代理),试试这个 sn-p(从这里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()
【讨论】: