Configuring TLS access to an API for the Private Cloud

A virtual host on Edge defines the domains and ports on which an API proxy is exposed, and, by extension, the URL that apps use to access an API proxy.

A virtual host also defines whether the API proxy is accessed by using the HTTP protocol, or by the encrypted HTTPS protocol that uses TLS. When configuring a virtual host to use HTTPS and TLS, you create a virtual host on Edge and configure the virtual host to use a keystore and truststore.

Learn more:

What you need to create a virtual host

Before you create a virtual host, you should have the following information:

  • The publicly facing domain name of the virtual host. For example, you should know if the publicly facing name is api.myCompany.com, myapi.myCompany.com, etc. That information is used when you create the virtual host and also when you create the DNS record for the virtual host.
  • For one-way TLS, you need to create a keystore where the keystore contains the following:
    • TLS certificate - either a certificate signed by a certificate authority (CA), or a chain of certificates where the last certificate is signed by a CA.
    • Private key - Edge supports key sizes up to 2048 bits. A passphrase is optional.
  • For two-way TLS, you need a keystore and you need a truststore to hold the client's certificate and, optionally, certificate's CA chain. You need the truststore even if the cert is signed by a CA.

See Keystores and Truststores for more information on creating keystores and truststores.

Virtual host configuration for TLS

To create a virtual host, create an XML object that defines the virtual host. The following XML object uses the <SSLInfo> element to define a virtual host for a one-way TLS configuration over HTTPS:

<VirtualHost name="myTLSVHost">
    <HostAliases> 
        <HostAlias>apiTLS.myCompany.com</HostAlias> 
    </HostAliases> 
    <Interfaces/> 
    <Port>9006</Port> 
    <OCSPStapling>off</OCSPStapling>     
    <SSLInfo> 
        <Enabled>true</Enabled> 
        <ClientAuthEnabled>false</ClientAuthEnabled> 
        <KeyStore>ref://myTestKeystoreRef</KeyStore> 
        <KeyAlias>myKeyAlias</KeyAlias> 
    </SSLInfo>
</VirtualHost>

In this example, the <Enabled> element is set to true to enable one-way TLS, and the <KeyStore> and <KeyAlias> elements specify the keystore and key used by the TLS connection.

To enable two-way TLS, set the <ClientAuthEnabled> element to true, and specify a truststore using the <TrustStore> element. The truststore holds the client's certificate and, optionally, certificate's CA chain.

Deciding how to specify the keystore and truststore name in the virtual host

In the virtual host example above, you specified the keystore by using a reference. A reference is a variable that contains the name of the keystore, rather than specifying the keystore name directly.

The advantage to using a reference is that you can change the value of the reference to change the keystore used by the virtual host, usually because the cert in the current keystore is expiring in the near future. Changing the value of the reference does not require you to restart the Edge Router.

Alternatively, you can use a literal keystore name in the virtual host. However, if you ever modify the virtual host to change the keystore name, you have to restart the Edge Routers.

Restrictions in using references to keystores and truststore

You must take into account the following restriction when using references to keystores and truststores:

  • You can only use keystore and truststore references in virtual hosts if you support SNI and you terminate SSL on the Apigee Routers.
  • If you have a load balancer in front of the Apigee Routers, and you terminate TLS on the load balancer, then you cannot use keystore and truststore references in virtual hosts.

Modifying an existing virtual host to use references to the keystore and truststore

Apigee strongly recommends that virtual hosts use reference to keystores and truststores. References let you change the keystore and truststore used by the virtual host without having to restart the Edge Routers.

If your virtual hosts are currently configured to use the literal name of the keystore or truststore, you can convert them to use references. To do so, update the virtual host to use references, and then restart the Edge Routers.

Setting the TLS ciphers and protocols for Edge 4.15.07 and earlier

If you are using Edge version 4.15.07 and earlier, then you set the TLS protocol and ciphers used by the virtual host by using the <Ciphers> and <Protocols> child tags of the <SSLInfo> tag. These tags are described in the table below.

For example:

    <SSLInfo> 
        <Enabled>true</Enabled> 
        <ClientAuthEnabled>false</ClientAuthEnabled> 
        <KeyStore>myTestKeystore</KeyStore> 
        <KeyAlias>myKeyAlias</KeyAlias> 
        <SSLInfo>
            <Enabled>true</Enabled>
            <ClientAuthEnabled>false</ClientAuthEnabled>
            <KeyStore>myTestKeystore</KeyStore>
            <KeyAlias>myKeyAlias</KeyAlias>
            <Ciphers>
                <Cipher>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</Cipher>    
                <Cipher>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</Cipher>
            </Ciphers>
            <Protocols>
                <Protocol>TLSv1.2</Protocol>
            </Protocols>
        </SSLInfo>
   </SSLInfo>

The <Cipher> tag uses the Java and JSSE name of the cipher. For example, for Java 8 see http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites.

Specifying the TLS ciphers and protocols for Edge 4.16.01 to 4.16.09

In Edge 4.16.01 through 4.16.09, you set the default ciphers and protocols for virtual hosts globally on the Router. These defaults then apply to all virtual hosts.

Use tokens to specify the default protocols and ciphers:

  • To specify the default protocols, use the token conf_load_balancing_load.balancing.driver.server.ssl.protocols
  • To specify the default ciphers for the Router, use the token conf_load_balancing_load.balancing.driver.server.ssl.ciphers

The default value of the conf_load_balancing_load.balancing.driver.server.ssl.protocols token is:

conf_load_balancing_load.balancing.driver.server.ssl.protocols=TLSv1 TLSv1.1 TLSv1.2

This setting specifies that the Router supports TLS versions 1.0, 1.1, and 1.2. Specify a space delimited list of values to the token.

The default value of the conf_load_balancing_load.balancing.driver.server.ssl.ciphers token is:

conf_load_balancing_load.balancing.driver.server.ssl.ciphers=HIGH:!aNULL:!MD5:!DH+3DES:!RSA+3DES

This setting specifies:

  • Key length of 128 bits or more required (HIGH).
  • Exclude ciphers with no authentication (!aNULL)
  • Exclude cipher suites using MD5 (!MD5)
  • Exclude cipher suites using DH (including anonymous DH, ephemeral DH and fixed DH) AND triple DES (!DH+3DES)
  • Exclude cipher suites using RSA key exchange AND triple DES (!RSA+3DES)

For information on the syntax and values allowed by this token, see https://www.openssl.org/docs/man1.0.2/apps/ciphers.html. Note that this token uses the OpenSSL cipher names, such as AES128-SHA256, and not the Java/JSSE cipher names, such as TLS_RSA_WITH_AES_128_CBC_SHA256.

To set the token for the Router:

  1. Edit the /opt/apigee/customer/application/router.properties file. If that file does not exist, create it.
  2. Set the conf_load_balancing_load.balancing.driver.server.ssl.ciphers token. For example, to specify TLSv1.2 only and exclude cipher suites using pre-shared keys, add!PSK:
    conf_load_balancing_load.balancing.driver.server.ssl.protocols=TLSv1.2
    conf_load_balancing_load.balancing.driver.server.ssl.ciphers=HIGH:!aNULL:!MD5:!DH+3DES:!RSA+3DES:!PSK
  3. Ensure that the router.properties file is owned by apigee:
    chown apigee:apigee /opt/apigee/customer/application/router.properties
  4. Restart the Edge Router:
    /opt/apigee/apigee-service/bin/apigee-service edge-router restart
  5. Check the value of the token:
    /opt/apigee/apigee-service/bin/apigee-service edge-router configure -search conf_load_balancing_load.balancing.driver.server.ssl.ciphers

Setting TLS virtual host parameters for Edge version 4.17.01 and later

If you are using Edge version 4.17.01 and later, then you can set some TLS properties for an individual virtual host, such as TLS protocol and cipher, by using the <Properties> child tag of the <VirtualHost> tag. These tags are described at Virtual host property reference.

For example:

<VirtualHost name="myTLSVHost">
    <HostAliases>
        <HostAlias>apiTLS.myCompany.com</HostAlias>
    </HostAliases>
    <Interfaces/>
    <Port>9006</Port>
    <OCSPStapling>off</OCSPStapling>     
    <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>false</ClientAuthEnabled>
        <KeyStore>ref://myTestKeystoreRef</KeyStore>
        <KeyAlias>myKeyAlias</KeyAlias>
    </SSLInfo>
    <Properties>
        <Property name="proxy_read_timeout">50</Property>
        <Property name="keepalive_timeout">300</Property>
        <Property name="proxy_request_buffering">off</Property>
        <Property name="proxy_buffering">off</Property>
        <Property name="ssl_protocols">TLSv1.2 TLSv1.1</Property>
        <Property name="ssl_ciphers">HIGH:!aNULL:!MD5:!DH+3DES:!kEDH</Property>
    </Properties>
</VirtualHost>

For information on the syntax and values allowed by the ssl_ciphers token, see https://www.openssl.org/docs/man1.0.2/apps/ciphers.html. Note that this token uses the OpenSSL cipher names, such as AES128-SHA256, and not the Java/JSSE cipher names, such as TLS_RSA_WITH_AES_128_CBC_SHA256.

Creating a virtual host that uses HTTPS

This example specifies the keystore to the virtual host by using a reference. Using a reference allows you to change the keystore without having to restart Routers.

Use the following procedure to create the virtual host:

  1. Create and configure a keystore named myTestKeystore by using the procedure described here: Keystores and Truststores. Ensure that the keystore uses an alias name of myKeyAlias for the cert and private key.
  2. Use the following POST API call to create the reference named keystoreref to the keystore you created above:

    curl -X POST  -H "Content-Type:application/xml" https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/references \
      -d '<ResourceReference name="keystoreref">
        <Refers>myTestKeystore</Refers>
        <ResourceType>KeyStore</ResourceType>
      </ResourceReference>'
      -u email:password
    

    The reference specifies the name of the keystore and the reference type as KeyStore.

    Use the following GET API call to view the reference:

    curl -X GET https://api.enterprise.apigee.com/v1/o/[org_name}/e/{env_name}/references/keystoreref -u uname:password
    
  3. Create the virtual host by using the Create a Virtual Host API, where <ms-IP> is the IP address or domain name of the Management Server node.

    Make sure to specify the correct keystore reference and key alias:

    curl -X POST -H "Content-Type:application/xml" \
      http://<ms-IP>:8080/v1/o/{org_name}/environments/{env_name}/virtualhosts \
      -d '<VirtualHost  name="newTLSTrustStore2">
        <HostAliases>
          <HostAlias>apiTLS.myCompany.com</HostAlias>
        </HostAliases>
        <Interfaces/>
        <Port>9005</Port>
        <OCSPStapling>off</OCSPStapling>
        <SSLInfo>
          <Enabled>true</Enabled>
          <ClientAuthEnabled>false</ClientAuthEnabled>
          <KeyStore>ref://keystoreref</KeyStore>
          <KeyAlias>myKeyAlias</KeyAlias>
        </SSLInfo>
      </VirtualHost>' \
      -u email:password
  4. Create a DNS record for the virtual host that matches the host alias.
  5. If you have any existing API proxies, add the virtual host to the <HTTPConnection> element in the ProxyEndpoint. The virtual host is added automatically to all new API proxies.

    See Updating an API proxy after creating a virtual host in About virtual hosts.

After updating an API proxy to use the virtual host, and creating the DNS record for the host alias, you can access the API proxy as shown below:

https://apiTLS.myCompany.com/v1/{project-base-path}/{resource-path}

For example:

https://apiTLS.myCompany.com/v1/weather/forecastrss?w=12797282

Creating and modifying references to a keystore or truststore

You can optionally configure the virtual host to use a reference to the keystore or truststore instead. The advantage to using a reference is that you can update the reference to point to a different keystore or truststore to update the TLS cert without having to restart a Router.

For example, shown below is a virtual host that uses a reference to the keystore:

<VirtualHost name="myTLSVHost"> 
    <HostAliases> 
        <HostAlias>apiTLS.myCompany.com</HostAlias> 
    </HostAliases> 
    <Interfaces/> 
    <Port>9006</Port> 
    <SSLInfo> 
        <Enabled>true</Enabled> 
        <ClientAuthEnabled>false</ClientAuthEnabled> 
        <KeyStore>ref://keystoreref</KeyStore> 
        <KeyAlias>myKeyAlias</KeyAlias> 
    </SSLInfo>
</VirtualHost>

Use the following POST API call to create the reference named keystoreref:

curl -X POST  -H "Content-Type:application/xml" https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/references \
  -d '<ResourceReference name="keystoreref">
    <Refers>myTestKeystore</Refers>
    <ResourceType>KeyStore</ResourceType>
  </ResourceReference>'
  -u email:password

The reference specifies the name of the keystore and its type.

Use the following GET API call to view the reference:

curl -X GET https://api.enterprise.apigee.com/v1/o/[org_name}/e/{env_name}/references/keystoreref -u uname:password

To later change the reference to point to a different keystore, ensuring that the alias has the same name, use the following PUT call:

curl -X PUT -H "Content-Type:application/xml" https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/references/keystoreref \
  -d '<ResourceReference name="keystoreref">
    <Refers>myNewKeystore</Refers>
    <ResourceType>KeyStore</ResourceType>
  </ResourceReference>'
  -u email:password