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