Reverse proxy + side stacking broken (config?) for large pages?
Using Zorp GPL 3.3, have a reverse proxy for OWA, I added def Zcommunicator(): Service("INcommunicator", INcommunicator, chainer=SideStackChainer(CommunicatorHttpProxy), router=DirectedRouter(SockAddrInet("<LAN IP>", 80))) Listener(SockAddrInet("<public ip>", 55000), "INcommunicator") class CommunicatorHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.filterURL) self.request["POST"] = (HTTP_REQ_POLICY, self.filterURL) def filterURL(self, method, url, version): if ("http://<public DNS>:5500/cas" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5447)) elif ("http://<public DNS>:5500/director2" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5449)) elif ("http://<public DNS>:5500/techops" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) elif ("http://<public DNS>:5500/fubar" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) else: self.session.setServer(SockAddrInet("10.0.7.2", 80)) return HTTP_REQ_ACCEPT class INcommunicator(PsslProxy): def config(self): PsslProxy.config(self) self.client_verify_type = SSL_VERIFY_NONE self.client_ca_directory = "/etc/ssl/certs" self.server_need_ssl=FALSE self.client_key_file = "/etc/ssl/private/xxx.key" self.client_cert_file = "/etc/ssl/certs/xxx.crt" #self.stack_proxy = CommunicatorHttpProxy the "fubar" URL doesn't point to a real location--and I get the 500 error page back from the web server. But when I try a (larger) real page, I'm seeing Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9): Starting proxy instance; client_fd='15', client_address='AF_INET(<public ip>:2220)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(<public ip>:5500)', client_protocol='TCP' Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9/pssl): SSL handshake failed on the client side; error='error:1407609C:SSL routines:lib(20):SSL23_GET_CLIENT_HELLO:func(118):http request:reason(156)' Ideas? Should I just reinstall 3.9.2 and copy my config files over? (no apt-get dist-upgrade option I see) Thanks in advance
Hi David, On Tue, 2011-11-29 at 08:49 -0500, David Yerger wrote:
def Zcommunicator(): Service("INcommunicator", INcommunicator, chainer=SideStackChainer(CommunicatorHttpProxy), router=DirectedRouter(SockAddrInet("<LAN IP>", 80))) Listener(SockAddrInet("<public ip>", 55000), "INcommunicator")
class CommunicatorHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.filterURL) self.request["POST"] = (HTTP_REQ_POLICY, self.filterURL)
def filterURL(self, method, url, version): if ("http://<public DNS>:5500/cas" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5447)) elif ("http://<public DNS>:5500/director2" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5449)) elif ("http://<public DNS>:5500/techops" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) elif ("http://<public DNS>:5500/fubar" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) else: self.session.setServer(SockAddrInet("10.0.7.2", 80)) return HTTP_REQ_ACCEPT
class INcommunicator(PsslProxy): def config(self): PsslProxy.config(self) self.client_verify_type = SSL_VERIFY_NONE self.client_ca_directory = "/etc/ssl/certs" self.server_need_ssl=FALSE self.client_key_file = "/etc/ssl/private/xxx.key" self.client_cert_file = "/etc/ssl/certs/xxx.crt" #self.stack_proxy = CommunicatorHttpProxy
the "fubar" URL doesn't point to a real location--and I get the 500 error page back from the web server.
But when I try a (larger) real page, I'm seeing
Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9): Starting proxy instance; client_fd='15', client_address='AF_INET(<public ip>:2220)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(<public ip>:5500)', client_protocol='TCP' Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9/pssl): SSL handshake failed on the client side; error='error:1407609C:SSL routines:lib(20):SSL23_GET_CLIENT_HELLO:func(118):http request:reason(156)'
Based on the OpenSSL error message you're getting I think the client did speak plain HTTP and not HTTPS. You could use tcpdump/wireshark to confirm this.
Ideas? Should I just reinstall 3.9.2 and copy my config files over? (no apt-get dist-upgrade option I see)
I don't think that would solve this problem. -- KOVACS Krisztian
Hi David, The problem seems to be that you receive plain HTTP traffic on your HTTPS port (55000) instead of an SSL handshake. The openssl under Zorp recognizes this common error, and instead of returning a handshake error it adds the http request. The cause of this can be: - your client enters http://IP_ADDRESS:55000 into the browser instead of https://IP_ADDRESS:55000, or - the address in the browser is OK, but the website redirects it from https to http, though this should be visible in the URL bar of the client browser - a packet filter messes up the ports (in your config you have both 55000 and 5500, but I guess that's not the entire config) As for upgrading to 3.9.2, unfortunately there is no automated method, just reinstall, copy the config files, and tweak them until they work (the changes between 3.3 and 3.9.2 may or may not affect your current config file). HTH Regards, Robert Fekete On 11/29/2011 02:49 PM, David Yerger wrote:
Using Zorp GPL 3.3, have a reverse proxy for OWA, I added
def Zcommunicator(): Service("INcommunicator", INcommunicator, chainer=SideStackChainer(CommunicatorHttpProxy), router=DirectedRouter(SockAddrInet("<LAN IP>", 80))) Listener(SockAddrInet("<public ip>", 55000), "INcommunicator")
class CommunicatorHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.filterURL) self.request["POST"] = (HTTP_REQ_POLICY, self.filterURL)
def filterURL(self, method, url, version): if ("http://<public DNS>:5500/cas" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5447)) elif ("http://<public DNS>:5500/director2" in url): self.session.setServer(SockAddrInet("10.0.7.2", 5449)) elif ("http://<public DNS>:5500/techops" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) elif ("http://<public DNS>:5500/fubar" in url): self.session.setServer(SockAddrInet("10.0.0.6", 80)) else: self.session.setServer(SockAddrInet("10.0.7.2", 80)) return HTTP_REQ_ACCEPT
class INcommunicator(PsslProxy): def config(self): PsslProxy.config(self) self.client_verify_type = SSL_VERIFY_NONE self.client_ca_directory = "/etc/ssl/certs" self.server_need_ssl=FALSE self.client_key_file = "/etc/ssl/private/xxx.key" self.client_cert_file = "/etc/ssl/certs/xxx.crt" #self.stack_proxy = CommunicatorHttpProxy
the "fubar" URL doesn't point to a real location--and I get the 500 error page back from the web server.
But when I try a (larger) real page, I'm seeing
Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9): Starting proxy instance; client_fd='15', client_address='AF_INET(<public ip>:2220)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(<public ip>:5500)', client_protocol='TCP' Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9/pssl): SSL handshake failed on the client side; error='error:1407609C:SSL routines:lib(20):SSL23_GET_CLIENT_HELLO:func(118):http request:reason(156)'
Ideas? Should I just reinstall 3.9.2 and copy my config files over? (no apt-get dist-upgrade option I see)
Thanks in advance _______________________________________________ zorp mailing list zorp@lists.balabit.hu https://lists.balabit.hu/mailman/listinfo/zorp
On sze, 2011-11-30 at 14:00 +0100, Fekete Robert wrote:
Hi David,
The problem seems to be that you receive plain HTTP traffic on your HTTPS port (55000) instead of an SSL handshake. The openssl under Zorp recognizes this common error, and instead of returning a handshake error it adds the http request.
The cause of this can be: - your client enters http://IP_ADDRESS:55000 into the browser instead of https://IP_ADDRESS:55000, or - the address in the browser is OK, but the website redirects it from https to http, though this should be visible in the URL bar of the client browser - a packet filter messes up the ports (in your config you have both 55000 and 5500, but I guess that's not the entire config)
As for upgrading to 3.9.2, unfortunately there is no automated method, just reinstall, copy the config files, and tweak them until they work (the changes between 3.3 and 3.9.2 may or may not affect your current config file).
FYI: You can find configuration examples on GitHub for 3.9.x (note that these examples work only with KZorp) https://github.com/balabit/zorp-examples or you can download virtual machines with the version 3.9.2 of Zorp for testing http://people.balabit.hu/szilard/zorp-gpl/virtual-machines/ -- Szilárd Pfeiffer <szilard.pfeiffer@balabit.com>
in your config you have both 55000 and 5500, but I guess that's not the entire config
Correct, I have a TPROXY from 5500 to 55000 in iptables.conf.in: -A PRinter -p tcp --dport 5500 -j TPROXY --on-port 55000 I thought something like that was needed to work. Seems to be working now, the only difference that I see, is that I have both of my HTTPS and HTTP services listed in my inbound_services and outbound_services. Maybe python indentation bit me? Another question: is it possible to rewrite a URL like Def filterURL(self, method, url, version): If ("http://foo.bar.com:5500/fubar" in url): self.request_url = "http://<inside address>/bugzilla" self.session.setServer(SockAddrInet("<inside address>", 80)) for my reverse proxy? I am now getting an error Firefox can't establish a connection to the server at <inside address>:5500. So I probably want somewhere else in the object hierarchy (self.session.owner.proxy.request_url doesn't work either...) Thanks everyone! -----Original Message----- From: zorp-bounces@lists.balabit.hu [mailto:zorp-bounces@lists.balabit.hu] On Behalf Of Fekete Robert Sent: Wednesday, November 30, 2011 8:00 AM To: Zorp users mailing list Subject: Re: [zorp] Reverse proxy + side stacking broken (config?) for large pages? Hi David, The problem seems to be that you receive plain HTTP traffic on your HTTPS port (55000) instead of an SSL handshake. The openssl under Zorp recognizes this common error, and instead of returning a handshake error it adds the http request. The cause of this can be: - your client enters http://IP_ADDRESS:55000 into the browser instead of https://IP_ADDRESS:55000, or - the address in the browser is OK, but the website redirects it from https to http, though this should be visible in the URL bar of the client browser - a packet filter messes up the ports (in your config you have both 55000 and 5500, but I guess that's not the entire config) As for upgrading to 3.9.2, unfortunately there is no automated method, just reinstall, copy the config files, and tweak them until they work (the changes between 3.3 and 3.9.2 may or may not affect your current config file). HTH Regards, Robert Fekete On 11/29/2011 02:49 PM, David Yerger wrote:
Using Zorp GPL 3.3, have a reverse proxy for OWA, I added
def Zcommunicator(): Service("INcommunicator", INcommunicator, chainer=SideStackChainer(CommunicatorHttpProxy), router=DirectedRouter(SockAddrInet("<LAN IP>", 80))) Listener(SockAddrInet("<public ip>", 55000), "INcommunicator")
class CommunicatorHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.filterURL) self.request["POST"] = (HTTP_REQ_POLICY, self.filterURL)
def filterURL(self, method, url, version): if ("http://<public DNS>:5500/cas" in url):
self.session.setServer(SockAddrInet("10.0.7.2", 5447))
elif ("http://<public DNS>:5500/director2" in url):
self.session.setServer(SockAddrInet("10.0.7.2", 5449))
elif ("http://<public DNS>:5500/techops" in url):
self.session.setServer(SockAddrInet("10.0.0.6", 80))
elif ("http://<public DNS>:5500/fubar" in url):
self.session.setServer(SockAddrInet("10.0.0.6", 80))
else: self.session.setServer(SockAddrInet("10.0.7.2",
80))
return HTTP_REQ_ACCEPT
class INcommunicator(PsslProxy): def config(self): PsslProxy.config(self) self.client_verify_type = SSL_VERIFY_NONE self.client_ca_directory = "/etc/ssl/certs" self.server_need_ssl=FALSE self.client_key_file = "/etc/ssl/private/xxx.key" self.client_cert_file = "/etc/ssl/certs/xxx.crt" #self.stack_proxy = CommunicatorHttpProxy
the "fubar" URL doesn't point to a real location--and I get the 500
error page back from the web server.
But when I try a (larger) real page, I'm seeing
Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]:
(svc/INcommunicator:9): Starting proxy instance; client_fd='15', client_address='AF_INET(<public ip>:2220)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(<public ip>:5500)', client_protocol='TCP'
Nov 28 15:42:39 localhost zorp/Zcommunicator[4334]: (svc/INcommunicator:9/pssl): SSL handshake failed on the client side; error='error:1407609C:SSL routines:lib(20):SSL23_GET_CLIENT_HELLO:func(118):http request:reason(156)'
Ideas? Should I just reinstall 3.9.2 and copy my config files over? (no apt-get dist-upgrade option I see)
Thanks in advance _______________________________________________ zorp mailing list zorp@lists.balabit.hu https://lists.balabit.hu/mailman/listinfo/zorp
_______________________________________________ zorp mailing list zorp@lists.balabit.hu https://lists.balabit.hu/mailman/listinfo/zorp
Hi David, On 12/12/2011 10:27 PM, David Yerger wrote:
Another question: is it possible to rewrite a URL like
Def filterURL(self, method, url, version): If ("http://foo.bar.com:5500/fubar" in url): self.request_url = "http://<inside address>/bugzilla" self.session.setServer(SockAddrInet("<inside address>", 80))
for my reverse proxy? I am now getting an error
Firefox can't establish a connection to the server at <inside address>:5500.
So I probably want somewhere else in the object hierarchy (self.session.owner.proxy.request_url doesn't work either...)
Maybe you're missing the return HTTP_REQ_ACCEPT from the end of your filterURL() method? I've just checked it and setting self.request_url seems to be working just fine for me, - 8< - MatcherPolicy(name="DNS", matcher=DNSMatcher(hosts=("google.com"))) class TestHttpProxy(HttpProxyNonTransparent): def config(self): HttpProxyNonTransparent.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.checkurl) self.request_header["Host"] = (HTTP_HDR_POLICY, self.checkhosthdr) def __post_config__(self): # check client IP address with DNSMatcher matcher = getMatcher("DNS") if matcher.checkMatch(self.session.client_address.ip_s): proxyLog(self, HTTP_DEBUG, 3, "Matcher matched") def checkurl(self, method, url, version): proxyLog(self, HTTP_DEBUG, 5, "Checking URL; url='%s'", (url,)) self.request_url = "http://google.com/" return HTTP_REQ_ACCEPT def checkhosthdr(self, name, value): if name == "Host": proxyLog(self, HTTP_DEBUG, 5, "Processing header; name='%s', value='%s'", (name, value)) return HTTP_HDR_ACCEPT def connectServer(self): # check server IP address with DNSMatcher stream = HttpProxyNonTransparent.connectServer(self) matcher = getMatcher("DNS") if matcher.checkMatch(self.session.server_address.ip_s): proxyLog(self, HTTP_DEBUG, 3, "Server matched") return stream def http_test(): Service("http1", TestHttpProxy, router=InbandRouter()) Dispatcher(transparent=FALSE, bindto=DBSockAddr(SockAddrInet("127.0.0.1", 8765), protocol=ZD_PROTO_TCP), service="http1") - 8< - -- KOVACS Krisztian
Almost there, my only problem now is that once I set the destination port with setServer, I can't subsequently change to a different destination port once the session starts, which my application needs unfortunately because it expects the reverse proxy to be able to demultiplex the destination ports based on the URL. Any way to get around this? Some way to force creation of a new session? I have now in policy.py: from Zorp.Core import * from Zorp.Http import * from Zorp.Plug import * from Zorp.Pssl import * import re InetZone("intra", "10.0.0.0/16", outbound_services=[], inbound_services=["INhttp", "INhttps", "INcommunicator", "CommunicatorHttpProxy"]) InetZone("local", "127.0.0.0/8", inbound_services=["*"], outbound_services=[]) InetZone("inter", "0.0.0.0/0", inbound_services=[], outbound_services=["INhttp", "INhttps", "INcommunicator", "CommunicatorHttpProxy"]) InetZone(name="hq", addr=["10.0.7.90/32", ], inbound_services=["*"], outbound_services=["*"], admin_parent="intra" ) def Zcommunicator(): #we are going to override the router port Service("INcommunicator", INcommunicator, chainer=SideStackChainer(CommunicatorHttpProxy), router=DirectedRouter(SockAddrInet("10.0.7.90", 80))) Listener(SockAddrInet("<outside IP>", 5500), "INcommunicator") class CommunicatorHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request["GET"] = (HTTP_REQ_POLICY, self.filterURL) self.request["POST"] = (HTTP_REQ_POLICY, self.filterURL) def filterURL(self, method, url, version): if re.search('/theme/', url): url2= re.sub('(?P<auth>https?://.*)/theme/', '\g<auth>/director2/theme/', url) elif re.search('/yui_2.7.0/', url): url2= re.sub('(?P<auth>https?://.*)/yui_2.7.0/', '\g<auth>/director2/yui_2.7.0/', url) elif re.search('/js/', url): url2= re.sub('(?P<auth>https?://.*)/js/', '\g<auth>/director2/js/', url) elif re.search('/authenticate/', url): url2= re.sub('(?P<auth>https?://.*)/authenticate/', '\g<auth>/', url) elif re.search('/cas/', url): url2= re.sub('(?P<auth>https?://.*)/cas/', '\g<auth>/', url) log("communicator_http.info", 3, "%s: Access to cas: %s" % (self.session.session_id, url)) elif re.search('/fubar/', url): url2= re.sub('(?P<auth>https?://.*)/fubar/', '\g<auth>/cgi-bin/', url) else: url2= url self.request_url= url2 if ("director2" in url2): self.session.setServer(SockAddrInet("10.0.7.90", 5449)) elif ("/cas/" in url): self.session.setServer(SockAddrInet("10.0.7.90", 5447)) log("communicator_http.info", 3, "%s: redirecting to port 5447: %s" % (self.session.session_id, url)) elif ("cgi-bin" in url2): self.session.setServer(SockAddrInet("10.0.0.60", 8000)) else: self.session.setServer(SockAddrInet("10.0.7.90", 80)) log("communicator_http.info", 3, "%s: GET or POST: %s" % (self.session.session_id, url2)) return HTTP_REQ_ACCEPT class INcommunicator(PsslProxy): def config(self): PsslProxy.config(self) self.client_verify_type = SSL_VERIFY_NONE self.client_ca_directory = "/etc/zorp/certs" self.server_need_ssl=FALSE self.client_key_file = "/etc/zorp/certs/private/foo.key" self.client_cert_file = "/etc/zorp/certs/foo.crt" #self.stack_proxy = CommunicatorHttpProxy Thanks in advance Dave
participants (4)
-
David Yerger
-
Fekete Robert
-
KOVACS Krisztian
-
Szilárd Pfeiffer