Datadog Gold Partner logo

Configuring mTLS for Apigee X Southbound Traffic Flow

Configuring-mTLS-for-Apigee-X-Southbound-Traffic-Flow_1

By Payal Jindal.Dec 28, 2022

Before diving into mTLS, let us first understand how one-way TLS works.

One-way TLS

Only the server’s identity is verified in one-way Transport Layer Security (TLS), as depicted in Fig. 1. First, the client initiates a session request to the server. Then, the server responds with its certificate, which the client verifies before beginning the transfer of data with the server. To authenticate the certificate, the client can either request verification from a Certificate Authority (CA) or validate the certificate against a certificate stored in its Truststore if the TLS server is using a self-signed certificate or one that is not signed by a trusted CA.

Configuring-mTLS-for-Apigee-X-Southbound-Traffic-Flow_1
Fig.1. One-way TLS handshake

In the above figure, the Keystore (on the server’s side) holds the TLS certificate and private key that are used to identify the entity during the TLS handshake process. The Truststore (on the client’s side), on the other hand, contains certificates that are used to verify the certificates received during TLS handshaking.

How does mTLS differ from TLS?

mTLS (mutual TLS) is a variant of the TLS (Transport Layer Security) protocol that provides enhanced security by requiring both the client and the server to present their own TLS certificates and keys during the TLS handshake process. In contrast, in one-way TLS, only the server is required to present its TLS certificate and key, leaving the client’s identity unverified.

In an mTLS handshake, the TLS server first presents its certificate containing the public key to the TLS client. The client then verifies the identity of the server by checking the certificate against a trusted list of certificates (such as those stored in a Truststore). Once the server’s identity is verified, the client presents its own certificate and public key to the server in order to get authenticated. If the server verifies the client’s identity, the data transfer can begin.

The diagram below shows the mTLS handshake process between the client and the server.

Article:Configuring mTLS for Apigee X Southbound Traffic Flow_2
Fig.2. Mutual TLS handshake

In order to use mTLS for mutual authentication, both the client and the server will need to maintain a Keystore containing their own TLS certificate and private key. Additionally, if the certificates used for authentication are self-signed, both the client and the server will need to have a Truststore containing a trusted list of certificates.

mTLS in Apigee X

In Apigee X, any request made to a backend system(through Apigee API Proxy) can be divided into two parts: the request from the user to the Apigee instance, and the request from the Apigee instance to the backend system. The diagram below shows this process:

Article:Configuring mTLS for Apigee X Southbound Traffic Flow_3
Fig.3. mTLS in Apigee X

In the context of Apigee X, the term “northbound” refers to traffic flow between the clients and the Apigee instances, while “southbound” refers to traffic flow between the Apigee instances and the proxy backends. mTLS can be enabled for both northbound and southbound traffic flows (this article only covers configuration for southbound mTLS only); mTLS configuration for northbound traffic currently requires one to set up a network bridge (like Envoy proxy) between the External Load Balancer and Apigee Runtime. mTLS enforced on the External Load Balancer [HTTP(s)] is under preview.

Enabling mTLS for southbound requests allows for secure communication between the Apigee instances and the proxy backends, ensuring that the identities of both parties are verified before data is transmitted.

This blog post will discuss how to configure mTLS for southbound requests in Apigee X.

Configuring Southbound mTLS

In Apigee, southbound mTLS can be used to secure requests between the runtime instance (acting as the TLS client) and the proxy target and backends (acting as the TLS server). Mutual TLS enables mutual authentication between the runtime instances and the backends, ensuring that only authorised parties can access the API.

Now, with the help of an example, we will demonstrate how to enable southbound mTLS in Apigee using an Nginx server as the proxy target. This reference demonstration shows the use of OpenSSL certificates. You can refer to this to read about how to generate OpenSSL certificates.

Apigee Proxy

Let’s see how to configure mTLS at the Apigee proxy level. To do this, we will need to make a change to the TargetEndpoint configuration by adding an SSLInfo block (sample configuration shown below) that includes information about the Keystore and Truststore to be used for the mutual TLS handshake.

<TargetEndpoint name="default">
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <Flows/>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <HTTPTargetConnection>
        <URL>https://nginx.example.com</URL>
        <SSLInfo>
            <Enabled>true</Enabled>
            <ClientAuthEnabled>true</ClientAuthEnabled>
            <KeyStore>ref://ks-apigee-gateway-ref</KeyStore>
            <KeyAlias>ks-apigee-gateway-alias</KeyAlias>
            <TrustStore>ref://ts-apigee-gateway-ref</TrustStore>
            <IgnoreValidationErrors>false</IgnoreValidationErrors>
        </SSLInfo>
    </HTTPTargetConnection>
</TargetEndpoint>

Let us take a look at the various tags in the <SSLInfo> block that needs to be added for configuring mTLS.

The <Enables> tag enables one-way TLS between the Apigee runtime instances and the target backends, while the <ClientAuthEnabled> tag enables two-way TLS. The <KeyStore> and <TrustStore> tags allow you to specify the Keystore and Truststore to be used for the mutual TLS handshake, either by providing the names of the Keystore and Truststore directly or by using references to them. A reference is a variable that contains the name of the Keystore or Truststore. The preferred way is to use references so that if someday your certificate expires in the Keystore, you will only need to change the reference to point to the new Keystore and no changes would be required in the proxy if you keep the new KeyAlias name same as the previous one. The <KeyAlias> tag specifies the name of the alias that was assigned to the certificate and private key when they were added to the Keystore. The <IgnoreValidationErrors> tag, if set to true, allows you to ignore TLS certificate errors.

To create Truststore and Keystore, you can use Apigee UI.

NOTE: In Apigee UI, you configure both the Keystore and Truststore under the Keystore section only. A Truststore is a Keystore that only contains a certificate or a certificate chain. Hence, whenever you upload a cert and key in the key store, it’ll be used as a Keystore and if you upload only a certificate, it can be used as a Truststore. Also, you don’t need to specify an alias for a Truststore, as it is not used to store a private key. Keep in mind that whenever you upload a certificate and key to the Keystore, you will need to specify an alias for it.

Proxy Backend

To enable mTLS for the backend service, an Nginx server that accepts all HTTP requests by default has been used. This server needs to be configured to listen on port 443 and to do this, a Keystore must be created. In addition, a Truststore is required to configure mTLS because this demonstration involves generating pem and key files using a self-signed certificate with OpenSSL. The following code snippet should be added to the Nginx server’s configuration file to enable mTLS.




server{
        listen 443 ssl;
        server_name nginx.payaljindal.com;
        ssl_certificate /etc/nginx/client-certis/nginx_server.pem;
        ssl_certificate_key /etc/nginx/client-certis/nginx_server.key;
        ssl_client_certificate /etc/nginx/client-certis/RootCA.pem;
        ssl_verify_client on;
}

In the provided code, the Keystore is made up of the ssl_certificate and ssl_certificate_key. The ssl_client_certificate contains the certificate that will be used to verify the certificate sent by the Apigee instance as a Truststore. Two-way TLS is enabled by setting ssl_verify_client to “on”.

NOTE: This configuration may vary if you’re using a different target backend, but the files/certificates that we are uploading will remain the same.

Testing

Now that we have completed the process of adding Truststore and Keystore configurations to the Apigee proxy and its backend, we can proceed to test the setup.

Further, we will need to send a certificate with all requests sent to the Nginx server on port 443. Let us try to hit the Nginx server on port 443 directly from the browser, it gives the response shown below-

Article:Configuring mTLS for Apigee X Southbound Traffic Flow_4
Fig.4. Hitting Nginx Server from the browser

The reason for the error is that the browser is not sending any certificate but the Nginx server is expecting one, as indicated by the error message “No required SSL certificate was sent”.

However, if the request is sent to the Nginx server from the Apigee proxy with the Nginx server as the target backend, it will work as intended because the Apigee proxy has been configured to send the necessary certificates as shown in the below picture.

Article:Configuring mTLS for Apigee X Southbound Traffic Flow_5
Fig.5. Hitting the Nginx server via Apigee proxy

Therefore, we can enable southbound mTLS at the Apigee proxy level. I hope this article was helpful to you!

Happy Learning!!


The original article published on Medium.

Related Posts