Configuring IG For HTTPS (Client-Side)

When IG sends requests over HTTP to a proxied application, or requests services from a third-party application, IG is acting as a client of the application, and the application is acting as a server. IG is client-side.

When IG sends requests securely over HTTPS, IG must be able to trust the server. By default, IG uses the Java environment truststore to trust server certificates. The Java environment truststore includes public key signing certificates from many well-known Certificate Authorities (CAs).

When servers present certificates signed by trusted CAs, then IG can send requests over HTTPS to those servers, without any configuration to set up the HTTPS client connection. When server certificates are self-signed or signed by a CA whose certificate is not automatically trusted, the following objects can be required to configure the connection:

  • KeyStore, to hold the server certificates or the CA's signing certificate. See "KeyStore".

  • SecretsTrustManager, to let IG handle the certificates in the KeyStore when deciding whether to trust a server certificate. See "SecretsTrustManager".

  • (Optional) KeyManager, to let IG present its certificate from the keystore when the server must authenticate IG as client. See "KeyManager".

  • ClientHandler and ReverseProxyHandler reference to ClientTlsOptions, for connecting to TLS-protected endpoints. See "ClientTlsOptions".

The following procedure describes how to set up IG for HTTPS (client-side), when server certificates are self-signed or signed by untrusted CAs.

Set Up IG for HTTPS (Client-Side) for Untrusted Servers
  1. Locate or set up the following directories:

    • Directory containing the sample application .jar: sampleapp_install_dir

    • Directory to store the sample application certificate and IG keystore: /path/to/secrets

  2. Extract the public certificate from the sample application:

    $ cd /path/to/secrets
    $ jar --verbose --extract \
    --file $sampleapp_install_dir/IG-sample-application-7.0.2.jar tls/sampleapp-cert.pem
    
    inflated: tls/sampleapp-cert.pem

    The file /path/to/secrets/tls/sampleapp-cert.pem is created.

  3. From the same directory, import the certificate into the IG keystore, and answer yes to trust the certificate:

    $ keytool -importcert \
    -alias ig-sampleapp \
    -file tls/sampleapp-cert.pem \
    -keystore reverseproxy-truststore.p12 \
    -storetype pkcs12 \
    -storepass password
    
    ...
    Trust this certificate? [no]:yes
    Certificate was added to keystore  

    Note

    Because KeyStore converts all characters in its key aliases to lower case, use only lowercase in alias definitions of a KeyStore.

  4. List the keys in the IG keystore to make sure that a key with the alias ig-sampleapp is present:

    $ keytool -list \
    -v \
    -keystore /path/to/secrets/reverseproxy-truststore.p12 \
    -storetype pkcs12 \
    -storepass password
    
    Keystore type: PKCS12
    Keystore provider: SUN
    Your keystore contains 1 entry
    Alias name: ig-sampleapp
    ...
  5. In the terminal where you run IG, create an environment variable for the value of the keystore password:

    $ export KEYSTORE_SECRET_ID='cGFzc3dvcmQ='

    The password is retrieved by the SystemAndEnvSecretStore, and must be base64-encoded.

  6. Add the following route to IG, to serve .css and other static resources for the sample application:

    $HOME/.openig/config/routes/static-resources.json
    %appdata%\OpenIG\config\routes\static-resources.json
    {
      "name" : "sampleapp_resources",
      "baseURI" : "http://app.example.com:8081",
      "condition": "${matches(request.uri.path,'^/css')}",
      "handler": "ReverseProxyHandler"
    }
  7. Add the following route to IG:

    $HOME/.openig/config/routes/client-side-https.json
    %appdata%\OpenIG\config\routes\client-side-https.json
    {
      "name": "client-side-https",
      "condition": "${matches(request.uri.path, '/home/client-side-https')}",
      "baseURI": "https://app.example.com:8444",
      "heap": [
        {
          "name": "Base64EncodedSecretStore-1",
          "type": "Base64EncodedSecretStore",
          "config": {
            "secrets": {
              "keystore.secret.id": "cGFzc3dvcmQ="
            }
          }
        },
        {
          "name": "KeyStoreSecretStore-1",
          "type": "KeyStoreSecretStore",
          "config": {
            "file": "/path/to/secrets/reverseproxy-truststore.p12",
            "storeType": "PKCS12",
            "storePassword": "keystore.secret.id",
            "secretsProvider": "Base64EncodedSecretStore-1",
            "mappings": [
              {
                "secretId": "trust.manager.secret.id",
                "aliases": [ "ig-sampleapp" ]
              }
            ]
          }
        },
        {
          "name": "SecretsTrustManager-1",
          "type": "SecretsTrustManager",
          "config": {
            "verificationSecretId": "trust.manager.secret.id",
            "secretsProvider":"KeyStoreSecretStore-1"
          }
        },
        {
          "name": "ReverseProxyHandler-1",
          "type": "ReverseProxyHandler",
          "config": {
            "tls": {
              "type": "ClientTlsOptions",
              "config": {
                "trustManager": "SecretsTrustManager-1"
              }
            },
            "hostnameVerifier": "ALLOW_ALL"
          },
          "capture": "all"
        }
      ],
      "handler": "ReverseProxyHandler-1"
    }
    

    Notice the following features of the route:

    • The route matches requests to /home/client-side-https.

    • The baseURI changes the request URI to point to the HTTPS port for the sample application.

    • The Base64EncodedSecretStore provides the KeyStore password.

    • The SecretsTrustManager uses a KeyStoreSecretStore to manage the trust material.

    • The KeyStoreSecretStore points to the sample application certificate. The password to access the KeyStore is provided by the SystemAndEnvSecretStore.

    • The ReverseProxyHandler uses the SecretsTrustManager for the connection to TLS-protected endpoints. All hostnames are allowed.

  8. Test the setup:

    1. Start the sample application

      $ java -jar $sampleapp_install_dir/IG-sample-application-7.0.2.jar
    2. Go to http://openig.example.com:8080/home/client-side-https.

      The request is proxied transparently to the sample application, on the TLS port 8444. Check the route log for GET https://app.example.com:8444/home/client-side-https.

Read a different version of :