IG 2023.4

Configure 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:

  • KeyStoreSecretStore, to manage a secret store for cryptographic keys and certificates, based on a standard Java keystore.

  • SecretsTrustManager, to manage trust material that verifies the credentials presented by a peer.

  • (Optional) SecretsKeyManager, to manage keys that authenticate a TLS connection to a peer.

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

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-2023.4.0-SNAPSHOT.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
    Because keytool converts all characters in its key aliases to lowercase, 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 serve static resources, such as .css, for the sample application:

    • Linux

    • Windows

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

    • Linux

    • Windows

    $HOME/.openig/config/routes/client-side-https.json
    appdata\OpenIG\config\routes\client-side-https.json
    {
      "name": "client-side-https",
      "condition": "${find(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",
            "storePasswordSecretId": "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-2023.4.0-SNAPSHOT.jar
    2. Go to http://ig.example.com:8080/home/client-side-https.

      The request is proxied transparently to the sample application, on the TLS port 8444.

    3. Check the route log for a line like this:

      GET https://app.example.com:8444/home/client-side-https
Copyright © 2010-2023 ForgeRock, all rights reserved.