3.2.7.1. Procedure – Configuring keybridging

Purpose: 

To configure keybridging in a proxy, complete the following steps.

Steps: 

  1. Create the required keys and CAs.

    1. Generate two local CA certificates. One of them will be used to sign bridging certificates for servers having trusted certificates, the other one for servers with untrusted or self-signed certificates. It is useful to reflect this difference somewhere in the CA's certificates, for example, in their common name (CA_for_Untrusted_certs; CA_for_Trusted_certs). These CA certificates can either be self-signed or signed by a local root CA. The certificate of the CA signing the trusted certificates should be imported to your clients to make the generated certificates 'trusted'. The other CA certificate should not be imported to the clients.

      Warning

      IMPORTANT: Do NOT set a password for these CAs, as they have to be accessible automatically by Zorp.

    2. Generate a new certificate. The private key of this keypair will be used in the on-the-fly generated certificates, the public part (DN and similar information) will not be used.

    3. Copy the generated certificate, the CA certificates, and the keys to the firewall, for example, into /etc/zorp/sslbridge/. This directory will be used in the ssl.client_ca_directory option.

      Note

      If you want to send the root CA of the CA certificates to the clients, also copy the root CA (and any intermediate CA certificates) to this directory.

    4. Create a cache directory to store the keybridged certificates generated by Zorp, for example, /var/lib/zorp/sslbridge/, and make it writable for the zorp user.

      Note

      Zorp automatically creates a file called serial.txt in the cache directory. If you delete the certificates from the cache, do NOT delete this file. If you accidentally delete it, recreate it, and make sure that it is writable for the zorp user.

  2. Set up a proxy class (for example, a class derived from the HttpProxy class) and set the following attributes with the following values:

    • Instruct Zorp to perform the handshake with the server first: self.ssl.handshake_seq=SSL_HSO_SERVER_CLIENT

      class KeybrideHttpsProxy(HttpProxy):
          def config(self):
              self.ssl.handshake_seq=SSL_HSO_SERVER_CLIENT
    • Enable keybridging. Depending on the direction the keybridging is performed, add the self.ssl.client_keypair_generate or the self.ssl.server_keypair_generate parameter, and set it to TRUE. When the generated certificates are shown to the clients, the self.ssl.client_keypair_generate parameter has to be used. (Actually, if a keypair_generate parameter is set, the proxy will request a keypair from the key_generator class. This class — discussed a bit later — returns either a newly generated keypair, or if its key_file parameter is set, a pregenerated keypair. In this example this latter option will be used.)

      class KeybrideHttpsProxy(HttpProxy):
          def config(self):
              self.ssl.handshake_seq=SSL_HSO_SERVER_CLIENT
              self.ssl.client_keypair_generate = TRUE
    • Configure the key_generator class. Note that the parameters of this class must be added to the proxy as a single line, for example:

      class KeybrideHttpsProxy(HttpProxy):
          def config(self):
              self.ssl.handshake_seq=SSL_HSO_SERVER_CLIENT
              self.ssl.client_keypair_generate = TRUE
              self.ssl.key_generator=X509KeyBridge( \
              key_file="/etc/key.d/Keybridging_cert/key.pem", \
              key_passphrase="", cache_directory="/var/lib/zorp/sslbridge",\
              trusted_ca_files=("/etc/ca.d/certs/0000000070.pem",\
                  "/etc/ca.d/keys/0000000070.pem"),\
              untrusted_ca_files=("/etc/ca.d/certs/0000000069.pem",\
                  "/etc/ca.d/keys/0000000069.pem"))
  3. Create a service and a rule using the modified proxy class. Use the previously defined proxy class in your Service definition, set up service and access control properties as usual.

  4. Restart Zorp.

    Expected result: 

    Every time the client connects to a previously unknown host, a new certificate will be generated, signed by one of the CAs specified above. This new certificate will be stored under /var/lib/zorp/sslbridge under a filename based on the original server certificate. It will also be shown to the client as the server certificate, and assuming the signer CA is trusted, the client (browser or other application) will not warn about untrusted certificates in any way. If the certificate is signed by the CA for untrusted certificates, the application will not recognize the issuer CA (since its certificate has not been imported to the client) and give a warning to the user. The user can then decide whether the certificate can be accepted or not.

    (Actually, two files are stored on the firewall for each certificate: the original certificate received from the server, and the generated certificate. When a client connects to the server, the certificate provided by the server is compared to the stored one: if the two does not match, a new certificate is generated. This happens for example if the server certificate has been expired and refreshed.)