missing constants and methods in pssl.py
Now trying to create an https proxy for Outlook Web Access with Zorp GPL 3.1.12. 1. It looks like some of the constants are named differently than the Zorp GPL tutorial at http://www.balabit.hu/network-security/zorp-gateway/gpl/tutorial/, for example it mentions PSSL_VERIFY_NONE and PSSL_VERIFY_REQUIRED_TRUSTED in the example in section 5.6, but the code for the included Pssl.py v. 1.28 says SSL_VERIFY_NONE = 0 SSL_VERIFY_OPTIONAL = 1 SSL_VERIFY_REQUIRED_UNTRUSTED = 2 SSL_VERIFY_REQUIRED_TRUSTED = 3 (without the "P") 2. Looks like some methods and constants mentioned in the Zorp Gateway v3.1 SSL tutorial PDF aren't there, for example Methods: server_ssl_method server_disable_proto server_ssl_cipher Constants: PSSL_METHOD_SSLV23 Permit the use of SSLv2 and v3. PSSL_METHOD_SSLV2 Permit the use of SSLv2 exclusively. PSSL_METHOD_SSLV3 Permit the use of SSLv3 exclusively. PSSL_METHOD_TLSV1 Permit the use of TLSv1 exclusively. PSSL_METHOD_ALL Permit the use of all the supported (SSLv2, SSLv3, and TLSv1) protocols. Is this because these are only defined in the Pssl module for Zorp Pro? 3. Using a policy.py containing from Zorp.Core import * from Zorp.Http import * from Zorp.Plug import * from Zorp.Pssl import * def Zhttps(): Service("INhttps", INhttps, router=DirectedRouter(SockAddrInet("10.0.0.9", 80))) Listener(SockAddrInet("aaa.bbb.ccc.ddd", 50443), "INhttps") class StrongPsslProxy(PsslProxy): def config(self): PsslProxy.config(self) #docs say PSSL_VERIFY_NONE self.client_verify_type = SSL_VERIFY_NONE self.server_ca_directory = "/etc/ssl/certs/" #PDF docs want more here - #self.server_ssl_method = PSSL_METHOD_TLSV1 #self.server_disable_proto = TRUE #self.server_ssl_cipher = PSSL_CIPHERS_HIGH class INhttps(StrongPsslProxy): def config(self): StrongPsslProxy.config(self) self.server_need_ssl=FALSE self.server_keypair_files = ("/etc/ssl/certs/owa.crt", "/etc/ssl/private/owa.key") self.stack_proxy=(Z_STACK_PROXY, OWAHttpProxy) #wild guess on my part, maybe this will help self.client_need_ssl=TRUE class OWAHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request_header["Front-End-Https"]=(HTTP_HDR_INSERT, "on") I'm seeing in my logs stuff like Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0): Starting proxy instance; client_fd='15', client_address='AF_INET(aaa.bbb.ccc.def:3139)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(aaa.bbb.ccc.ddd:443)', client_protocol='TCP' Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0/pssl): Server connection established; server_fd='18', server_address='AF_INET(10.0.0.9:80)', server_zone='Zone(intra, 10.0.0.0/24)', server_local='AF_INET(10.0.0.69:55718)', server_protocol='TCP' Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0/pssl): SSL handshake failed on the client side; error='error:1408A0C1:SSL routines:lib(20):SSL3_GET_CLIENT_HELLO:func(138):no shared cipher:reason(193)' Where 10.0.0.0 is the local network, aaa.bbb.ccc.ddd is my public IP, and aaa.bbb.ccc.def is the gateway address of my Snapgear (which my internal test client demaquerades as.) Looks like the protocol is defaulting to TCP instead of something sane like TLSV1, but I can't set it anywhere I can see. Is this disabled on purpose or is there something I can do to fix it? Thanks in advance! David Yerger
On Sun, 2008-02-17 at 16:38 -0500, David Yerger wrote:
Now trying to create an https proxy for Outlook Web Access with Zorp GPL 3.1.12.
1. It looks like some of the constants are named differently than the Zorp GPL tutorial at http://www.balabit.hu/network-security/zorp-gateway/gpl/tutorial/, for example it mentions PSSL_VERIFY_NONE and PSSL_VERIFY_REQUIRED_TRUSTED in the example in section 5.6, but the code for the included Pssl.py v. 1.28 says
SSL_VERIFY_NONE = 0 SSL_VERIFY_OPTIONAL = 1 SSL_VERIFY_REQUIRED_UNTRUSTED = 2 SSL_VERIFY_REQUIRED_TRUSTED = 3
(without the "P")
The Professional and GPLd version of the proxy are totally different beasts and although they have some things in common, they are maintained differently. The "official" names of the above constants are prefixed with a P, but this change was not commited to the GPLd version. I've committed a fix for this. I'm also Ccing the documentation team to clarify that the Pssl documentation in our refguide applies to the professional version, and how that differs from the GPLd one. The documentation of the GPLd version is in the Pssl.py source file as text comments. However the GPLd version should be enough for the stuff you want to implement.
2. Looks like some methods and constants mentioned in the Zorp Gateway v3.1 SSL tutorial PDF aren't there, for example
Methods: server_ssl_method server_disable_proto server_ssl_cipher
Constants:
PSSL_METHOD_SSLV23 Permit the use of SSLv2 and v3. PSSL_METHOD_SSLV2 Permit the use of SSLv2 exclusively. PSSL_METHOD_SSLV3 Permit the use of SSLv3 exclusively. PSSL_METHOD_TLSV1 Permit the use of TLSv1 exclusively. PSSL_METHOD_ALL Permit the use of all the supported (SSLv2, SSLv3, and TLSv1) protocols.
This is not supported by the GPLd version, it basically always uses "SSLv23", which is described by SSL_CTX_new(3) manual page as: SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void) A TLS/SSL connection established with these methods will understand the SSLv2, SSLv3, and TLSv1 protocol. A client will send out SSLv2 client hello messages and will indicate that it also understands SSLv3 and TLSv1. A server will understand SSLv2, SSLv3, and TLSv1 client hello messages. This is the best choice when compatibility is a concern.
Is this because these are only defined in the Pssl module for Zorp Pro?
Yes, just as I described above, the Pssl proxy in pro is not the same as the Pssl in the GPLd version. I might try to convince our management to release the Pro version into the GPLd branch if there's interest though.
3. Using a policy.py containing
from Zorp.Core import * from Zorp.Http import * from Zorp.Plug import * from Zorp.Pssl import *
def Zhttps(): Service("INhttps", INhttps, router=DirectedRouter(SockAddrInet("10.0.0.9", 80))) Listener(SockAddrInet("aaa.bbb.ccc.ddd", 50443), "INhttps")
class StrongPsslProxy(PsslProxy): def config(self): PsslProxy.config(self) #docs say PSSL_VERIFY_NONE self.client_verify_type = SSL_VERIFY_NONE self.server_ca_directory = "/etc/ssl/certs/" #PDF docs want more here - #self.server_ssl_method = PSSL_METHOD_TLSV1
As I said, the GPLd proxy will use SSLv2, v3 and TLSv1
#self.server_disable_proto = TRUE
The proper name for this attribute is self.server_disable_proto_sslv2 = TRUE e.g. you need a protocol suffix, but again this is not in the GPLd version.
#self.server_ssl_cipher = PSSL_CIPHERS_HIGH
class INhttps(StrongPsslProxy): def config(self): StrongPsslProxy.config(self) self.server_need_ssl=FALSE
This means that you don't want ssl encryption on the server side
self.server_keypair_files = ("/etc/ssl/certs/owa.crt", "/etc/ssl/private/owa.key")
You probably don't need server side keys as you disabled encryption. You want the same on the client side, e.g. you'd need client_keypair_files, however the 'keypair' attributes were only added because of the GUI of the professional version, you need these: client_key_file -- [STRING:"":RW:R] Client side authentication private key corresponding to 'client_cert_file'. client_cert_file -- [STRING:"":RW:R] Filename of the client side authentication certificate in PEM format. This must be a server certificate, since for clients the proxy behaves as it were an SSL server.
self.stack_proxy=(Z_STACK_PROXY, OWAHttpProxy) #wild guess on my part, maybe this will help self.client_need_ssl=TRUE
This is on by default.
class OWAHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request_header["Front-End-Https"]=(HTTP_HDR_INSERT, "on")
I'm seeing in my logs stuff like
Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0): Starting proxy instance; client_fd='15', client_address='AF_INET(aaa.bbb.ccc.def:3139)', client_zone='Zone(inter, 0.0.0.0/0)', client_local='AF_INET(aaa.bbb.ccc.ddd:443)', client_protocol='TCP' Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0/pssl): Server connection established; server_fd='18', server_address='AF_INET(10.0.0.9:80)', server_zone='Zone(intra, 10.0.0.0/24)', server_local='AF_INET(10.0.0.69:55718)', server_protocol='TCP' Feb 17 16:09:49 localhost zorp/Zhttps[5552]: (svc/INhttps:0/pssl): SSL handshake failed on the client side; error='error:1408A0C1:SSL routines:lib(20):SSL3_GET_CLIENT_HELLO:func(138):no shared cipher:reason(193)'
The reason is that you did not specify the keys for the proxy (in fact you did, but for the wrong side, see above)
Where 10.0.0.0 is the local network, aaa.bbb.ccc.ddd is my public IP, and aaa.bbb.ccc.def is the gateway address of my Snapgear (which my internal test client demaquerades as.)
Feel free to ask more, if you need help. -- Bazsi
Thanks for your help, I think we are getting there! Choking on proxy stacking though, see below: Bazsi wrote:
You probably don't need server side keys as you disabled encryption. You want the same on the client side, e.g. you'd need
client_keypair_files,
however the 'keypair' attributes were only added because of the GUI of the professional version, you need these:
client_key_file -- [STRING:"":RW:R] Client side authentication private key corresponding to 'client_cert_file'. client_cert_file -- [STRING:"":RW:R] Filename of the client side authentication certificate in PEM format. This must be a server certificate, since for clients the proxy behaves as it were an SSL server.
OK, did that, also stripped the PEM passphrase from my private key so Zorp could read it-- Then was seeing Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (svc/INhttps:0/pssl): Client side SSL handshake successful; Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (svc/INhttps:0/pssl): Stacking subproxy; client='19:20', server='21:22' Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): Traceback (most recent call last): Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): File "/usr/share/zorp/pylib/Zorp/Proxy.py", line 425, in stackProxy Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): proxyLog(self, CORE_DEBUG, 7, "Stacking child proxy; client_fd='%d', server_fd='%d', class='%s'", (client_stream.fd, server_stream.fd, proxy_class.__name__)) Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): AttributeError: 'tuple' object has no attribute '__name__' Looked again at the example in http://www.balabit.com/network-security/zorp-gateway/gpl/tutorial/, looks like for Zorp GPL the correct form is self.stack_proxy= OWAHttpProxy instead of self.stack_proxy=(Z_STACK_PROXY, OWAHttpProxy) I now have in my policy.py: def Zhttps(): Service("INhttps", INhttps, router=DirectedRouter(SockAddrInet("10.0.0.9", 80))) Listener(SockAddrInet("aaa.bbb.ccc.ddd", 50443), "INhttps") class StrongPsslProxy(PsslProxy): def config(self): PsslProxy.config(self) #docs say PSSL_VERIFY_NONE #this will change but for now agree with present code self.client_verify_type = SSL_VERIFY_NONE #self.server_ca_directory = "/etc/ssl/certs/" class OWAHttpProxy(HttpProxy): def config(self): HttpProxy.config(self) self.request_header["Front-End-Https"]=(HTTP_HDR_INSERT, "on") class INhttps(StrongPsslProxy): def config(self): StrongPsslProxy.config(self) self.server_need_ssl=FALSE self.client_key_file = "/etc/ssl/private/owa.key" self.client_cert_file = "/etc/ssl/certs/owa.crt" self.stack_proxy=OWAHttpProxy which seems to work. Thanks again David Yerger
On Tue, 2008-02-19 at 18:56 -0500, David Yerger wrote:
Thanks for your help, I think we are getting there! Choking on proxy stacking though, see below:
Bazsi wrote:
You probably don't need server side keys as you disabled encryption. You want the same on the client side, e.g. you'd need
client_keypair_files,
however the 'keypair' attributes were only added because of the GUI of the professional version, you need these:
client_key_file -- [STRING:"":RW:R] Client side authentication private key corresponding to 'client_cert_file'. client_cert_file -- [STRING:"":RW:R] Filename of the client side authentication certificate in PEM format. This must be a server certificate, since for clients the proxy behaves as it were an SSL server.
OK, did that, also stripped the PEM passphrase from my private key so Zorp could read it--
Then was seeing
Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (svc/INhttps:0/pssl): Client side SSL handshake successful; Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (svc/INhttps:0/pssl): Stacking subproxy; client='19:20', server='21:22' Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): Traceback (most recent call last): Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): File "/usr/share/zorp/pylib/Zorp/Proxy.py", line 425, in stackProxy Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): proxyLog(self, CORE_DEBUG, 7, "Stacking child proxy; client_fd='%d', server_fd='%d', class='%s'", (client_stream.fd, server_stream.fd, proxy_class.__name__)) Feb 19 18:01:00 localhost zorp/Zhttps[6286]: (stderr): AttributeError: 'tuple' object has no attribute '__name__'
Looked again at the example in http://www.balabit.com/network-security/zorp-gateway/gpl/tutorial/, looks like for Zorp GPL the correct form is
self.stack_proxy= OWAHttpProxy
instead of
self.stack_proxy=(Z_STACK_PROXY, OWAHttpProxy)
Hm... this should also work for the GPLd version, let me check... You are right, it indeed does not work, as the stacking generalization that was done in the Pro version was not released as part of the GPLd version. I'm checking in a patch that will allow the use of the same format (e.g. the tuple based format), while retaining the program & remote stacking features. Thanks for noticing and reporting this. -- Bazsi
One more thing: looks like the OWA with IE7 as the client, as well as Windows Mobile Direct Push use more request methods than HttpProxy allows by default, so adding what they want I now have class OWAHttpProxy(HttpWebdavProxy): def config(self): #IE7 uses PROPFIND, might as well use the WebDAV proxy HttpWebdavProxy.config(self) #Direct Push wants this self.request["OPTIONS"] = (HTTP_REQ_ACCEPT,) #IE7 OWA wants these self.request["SUBSCRIBE"] = (HTTP_REQ_ACCEPT,) self.request["SEARCH"] = (HTTP_REQ_ACCEPT,) self.request["POLL"] = (HTTP_REQ_ACCEPT,) self.request["BPROPPATCH"] = (HTTP_REQ_ACCEPT,) self.request_header["Front-End-Https"]=(HTTP_HDR_INSERT, "on") Works great! Thanks again for your help David Yerger
participants (2)
-
Balazs Scheidler
-
David Yerger