3.2.4.1. Procedure – Enabling SSL-encryption in the connection

Purpose: 

To proxy HTTPS connections, configure an Encryption Policy to handle SSL/TLS connections, and use this Encryption Policy in your Service. The policy will be configured to:

  • Require the client and the server to use strong encryption algorithms, the use of weak algorithms will not be permitted.

  • Enable connections only to servers with certificates signed by CAs that are in the trusted CAs list of the Zorp firewall node. (For details on managing trusted CA groups, see Section 11.3.7.3, Managing trusted groups in Zorp Professional 7 Administrator Guide.)

  • The clients will only see the certificate of Zorp. To allow the clients to access the certificate information of the server, see Procedure 2.2, Configuring keybridging in How to configure SSL proxying in Zorp 7.

Steps: 

  1. Generate a certificate for your firewall. The Zorp component requires its own certificate and keypair to perform SSL/TLS proxying.

    ZMCCreate a certificate, set the firewall as the owner host of the certificate, then distribute it to the firewall host. For details, see Chapter 11, Key and certificate management in Zorp in Zorp Professional 7 Administrator Guide.

    Python: In configurations managed manually from python, create an X.509 certificate (with its related keypair) using a suitable software (for example, OpenSSL) and deploy it to the Zorp firewall host (for example, copy it to the /etc/key.d/mycert folder).

  2. Create and configure an Encryption Policy. Complete the following steps.

    1. Navigate to the Zorp ZMC component of the firewall host.

    2. Select Policies > New.

    3. Enter a name into the Policy name field, for example, MyTLSEncryption.

      Creating a new Encryption policy

      Figure 3.1. Creating a new Encryption policy

    4. Select Policy type > Encryption Policy, then click OK.

    5. Select Class > TwoSidedEncryption.

      Python:

      EncryptionPolicy(
          name="MyTLSEncryption",
          encryption=TwoSidedEncryption()
          )
    6. Double-click client_certificate_generator, then select Class > StaticCertificate.

      Selecting Encryption policy class

      Figure 3.2. Selecting Encryption policy class

    7. Double-click the certificates and click New to add a certificate entry to a list of certificates.

      Creating a new certificate entry

      Figure 3.3. Creating a new certificate entry

    8. Double-click the certificate_file_path. A window displaying the certificates owned by the host will open up. The lower section of the window shows the information contained in the certificate. Select the list of certificates Zorp is required to show to the clients (for example, the certificate created in Step 1), then click Select.

      Creating a new Encryption policy

      Figure 3.4. Creating a new Encryption policy

      Python:

          encryption=TwoSidedEncryption(
              client_certificate_generator=StaticCertificate(
                  certificates=(
                      Certificate.fromFile(
                          certificate_file_path="/etc/key.d/ZMS_Engine/cert.pem",
                          private_key=PrivateKey.fromFile(
                              "/etc/key.d/ZMS_Engine/key.pem")
                      ),
                  )
              )
          )
    9. If the private key of the certificate is password-protected, double-click private_key_password, type the password, then click OK. Otherwise, click OK.

    10. Disable mutual authentication. That way, Zorp will not request a certificate from the clients.

      Double-click client_verify, select Class > ClientNoneVerifier, then click OK.

      Disabling mutual authentication

      Figure 3.5. Disabling mutual authentication

      Python:

          encryption=TwoSidedEncryption(
              client_verify=None
          )
    11. Specify the directory containing the certificates of the trusted CAs. These settings determine which servers can the clients access: the clients will be able to connect only those servers via SSL/TLS which have certificate signed by one of these CAs (or a lower level CA in the CA chain).

      Double-click server_verify, double-click ca_directory, then type the path and name to the directory that stores the trusted CA certificates, for example, /etc/ca.d/certs/. Click OK.

      Specifying trusted CAs

      Figure 3.6. Specifying trusted CAs

      Python:

          encryption=TwoSidedEncryption(
              server_verify=ServerCertificateVerifier(
                  ca_directory="/etc/ca.d/certs/"
              )
          )
      Note

      CAs cannot be referenced directly, only the trusted group containing them. For details on managing trusted groups, see Section 11.3.7.3, Managing trusted groups in Zorp Professional 7 Administrator Guide.

    12. Specify the directory containing the CRLs of the trusted CAs.

      Double-click crl_directory, then type the path and name to the directory that stores the CRLs of the trusted CA certificates, for example, /etc/ca.d/crls/. Click OK.

      Specifying CRLs

      Figure 3.7. Specifying CRLs

      Python:

          encryption=TwoSidedEncryption(
              server_verify=ServerCertificateVerifier(
                  ca_directory="/etc/ca.d/certs/",
                  crl_directory="/etc/ca.d/crls/"
              )
          )
    13. Optional Step: The Common Name in the certificate of a server or webpage is usually its domain name or URL. By default, Zorp compares this Common Name to the actual domain name it receives from the server, and rejects the connection if they do not match. That way it is possible to detect several types of false certificates and prevent a number of phishing attacks. If this mode of operation interferes with your environment, and you cannot use certificates that have proper Common Names, disable this option.

      Double-click server_verify > check_subject, select FALSE, then click OK.

      Python:

          encryption=TwoSidedEncryption(
              server_verify=ServerCertificateVerifier(
                  ca_directory="/etc/ca.d/certs/",
                  crl_directory="/etc/ca.d/crls/",
                  check_subject=FALSE
              )
          )
    14. Optional Step: Forbid the use of weak encryption algorithms to increase security. The related parameters can be set separately for the client and the server-side of Zorp, using the client_ssl_options and server_ssl_options parameters of the Encryption Policy. Disabling weak algorithms also eliminates the risk of downgrade attacks, where the attacker modifies the SSL session-initiation messages to force using weak encryption that can be easily decrypted by a third party.

      Note

      Certain outdated operating systems, or old browser applications do not properly support strong encryption algorithms. If your clients use such systems or applications, it might be required to permit weak encryption algorithms.

      1. SSL methods may occasionally fall back to older (thus weaker) protocol versions if one of the peers does not support the newer version. To avoid this situation, explicitly disable undesired protocol versions (SSLv2 and SSLv3 are disabled by default).

        For example, to disable TLSv1, double-click client_ssl_options > disable_tlsv1, click TRUE, then click OK. Repeat this step for the server_ssl_options parameter.

      Python:

          encryption=TwoSidedEncryption(
              server_ssl_options=ServerSSLOptions(
                  disable_tlsv1=TRUE)
              client_ssl_options=ClientSSLOptions(
                  disable_tlsv1=TRUE)
              )
    15. Optional Step: Enable untrusted certificates. Since a significant number of servers use self-signed certificates (with unverifiable trustworthiness), in certain situations it might be needed to permit access to servers that have untrusted certificates.

      Note

      When an untrusted certificate is accepted, the generated certificates will be signed with the untrusted CA during keybridge scenarios. For details on configuring keybridging, see Procedure 2.2, Configuring keybridging in How to configure SSL proxying in Zorp 7

      Double-click server_verifier > trust_level, click the drop-down menu and select UNTRUSTED, then click OK.

      Note

      When the trust_level value is NONE, even the invalid certificates are accepted and at the client side there is no client certificate request sent to the client.

      Python:

          encryption=TwoSidedEncryption(
              server_verify=ServerCertificateVerifier(
                  trust_level=TLS_TRUST_LEVEL_UNTRUSTED
              )
          )

    Python:

    The Encryption Policy configured in the previous steps is summarized in the following code snippet.

    EncryptionPolicy(
        name="MyTLSEncryption",
        encryption=TwoSidedEncryption(
            client_verify=ClientNoneVerifier(),
            client_ssl_options=ClientSSLOptions(),
            server_verify=ServerCertificateVerifier(
                trust_level=TLS_TRUST_LEVEL_FULL,
                intermediate_revocation_check_type =
                    TLS_INTERMEDIATE_REVOCATION_SOFT_FAIL,
                leaf_revocation_check_type =
                    TLS_LEAF_REVOCATION_SOFT_FAIL,
                trusted_certs_directory="",
                verify_depth=4,
                verify_ca_directory="/etc/ca.d/certs/",
                verify_crl_directory="/etc/ca.d/crls/",
                check_subject=TRUE
                ),
            server_ssl_options=ServerSSLOptions(),
            client_certificate_generator=StaticCertificate(
                certificates=(
                    Certificate.fromFile(
                        certificate_file_path=
                            "/etc/key.d/ZMS_Engine/cert.chain.pem",
                        private_key=PrivateKey.fromFile(
                            "/etc/key.d/ZMS_Engine/key.pem")),
                ))
        ))
  3. Select PKI > Distribute Certificates.

    Note when managing Zorp without ZMC, copy the certificates and CRLs to their respective directories. They are not updated automatically as in configurations managed by ZMC.

    By performing the above steps, the proxy has been configured to use the specified certificate and its private key, and also the directory has been set that will store the certificates of the trusted CAs and their CRLs. Client authentication has also been disabled.

  4. Create a service that clients can use to access the Internet in a secure channel. This service will use the MyTLSEncryption Encryption Policy.

    1. Select Services > New, enter a name for the service (for example, intra_HTTPS_inter), then click OK.

    2. Select Proxy class > Http > HttpProxy.

    3. Select Encryption > MyTLSEncryption.

    4. Configure the other parameters of the service as neecessary for the environment, then click OK.

    5. Select Firewall Rules > New > Service, and select the service created in the previous step. For more details on creating firewall rules, see Section 6.5, Configuring firewall rules in Zorp Professional 7 Administrator Guide.

    6. Configure the other parameters of the rule as necessary for the environment, then click OK.

    Creating a Service

    Figure 3.8. Creating a Service

    Python:

    def demo() :
        Service(
            name='demo/intra_HTTPS_inter',
            router=TransparentRouter(),
            chainer=ConnectChainer(),
            proxy_class=HttpProxy,
            max_instances=0,
            max_sessions=0,
            keepalive=Z_KEEPALIVE_NONE,
            encryption_policy="MyTLSEncryption"
        )
    
        Rule(
            rule_id=300,
            src_subnet=('192.168.1.1/32', ),
            dst_zone=('internet', ),
            proto=6,
            service='demo/intra_HTTPS_inter'
        )
  5. Commit and upload the changes, then restart Zorp.

    Expected result: 

    Every time a client connects to a server, Zorp checks the certificate of the server. If the signer CA is trusted, Zorp shows a trusted certificate to the client (browser or other application). If the certificate of the server is untrusted, Zorp shows an untrusted certificate to the client, giving a warning to the user. The user can then decide whether the certificate can be accepted or not.