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.
-
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
-
-
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. -
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. -
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 ...
-
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.
-
Add the following route to serve static resources, such as .css, 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": "${find(request.uri.path,'^/css')}", "handler": "ReverseProxyHandler" }
-
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": "${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.
-
-
Test the setup:
-
Start the sample application
$ java -jar sampleapp_install_dir/IG-sample-application-2023.4.0-SNAPSHOT.jar
-
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
. -
Check the route log for a line like this:
GET https://app.example.com:8444/home/client-side-https
-