Skip to main content
Gainsight Inc.

Enable PX Tracking with Proxy Server

This article explains how to enable PX tracking via a Secure Socket Layer (SSL) Proxy.

Overview

Gainsight PX tracks usage data from your application and presents it in various Analytics reports. You can use this data to get insights about how your customers are using your product. 

You can also enable tracking of your data without allowing your APIs to reach the PX server. You can instead use an intermediate Proxy server to enable tracking of your data by PX. Gainsight PX supports two modes of SSL proxy; SSL Termination Proxy and Tunnel Mode proxy. This article explains how to implement both of these SSL proxy modes.

Traffic Proxy and SSL Termination

In the SSL Termination mode, an intermediate SSL Termination proxy is used. This proxy decrypts your encrypted requests and sends the same to the PX app. PX then responds in HTTP format to the proxy. The Proxy encrypts PX responses and sends them back to you. 

Gainsight PX recommends using this mode of connection as it significantly reduces network hops and latency.

To implement this mode, you must complete the following tasks:

  1. Create and provide a single-domain SSL certificate to PX: You must create a domain and provide the SSL certificate of this domain along with the private and public keys to PX. This domain can be used to send requests and receive responses from PX.

  2. Create Canonical Name (CNAME) Record in your DNS: Once you create a domain and share its certificate details with PX, you must create a CNAME record for this domain in your Domain Name Systems (DNS) server. The source for this record must be your single domain (created in step a) and the destination must be esp-proxy.aptrinsic.com. 

  3. Modify PX tag code: You must modify the PX tracking code installed in your application. This modification ensures that your single domain is now included in the tracking code. The details of the code are as follows:

 

Update the PX tag with two overrides:

Default URL Proxy domain example PX Proxy endpoint Description
esp.aptrinsic.com px-esp.yourdomain.com esp-proxy.aptrinsic.com Tracking traffic endpoint
web-sdk.aptrinsic.com px-sdk.yourdomain.com web-sdk.aptrinsic.com

CDN resource for:

  • Web-SDK hostname

  • Styling

  • Knowledge center resources.

Override parameters:

  • espProxyDomain
  • contentProxyDomain
<script type="text/javascript">
  (function(n,t,a,e,co){var i="aptrinsic";n[i]=n[i]||function()
  {
      (n[i].q=n[i].q||[]).push(arguments)},n[i].p=e;n[i].c=co;
    var r=t.createElement("script");r.async=!0,r.src=a+"?a="+e;
    var c=t.getElementsByTagName("script")[0];c.parentNode.insertBefore(r,c)
  })
  (window,document,"https://px-sdk.yourdomain.com/api/aptrinsic.js","AP-ZZZZZZZZ-2",
  {"espProxyDomain":"https://px-esp.yourdomain.com", "contentProxyDomain":"https://px-sdk.yourdomain.com"});
</script>

In the above code, navigate to the penultimate line and replace AP-ZZZZZZZZ-2 with your PX product key and px-sdk.yourdomain.com with the URL of the single-domain, created in Step a.

Tunneling

This section describes the tunneling mode of SSL connection supported by Gainsight PX. Gainsight PX recommends using this mode only if you are using strict firewall rules. In this mode, a secure tunnel is created between your application and PX. 

The following code uses a local NGINX server to establish a tunnel for the tracking server:

# merged nginx.conf default.conf
user  nginx;
# https://github.com/denji/nginx-tuning
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
  worker_connections  1024;
  use epoll;
  multi_accept on;
}


http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for" "$request_body"';

  # docker logs have symlink to stdout
  # https://stackoverflow.com/questions/22541333/have-nginx-access-log-and-error-log-log-to-stdout-and-stderr-of-master-process
  access_log  off;

  sendfile        on;
  #tcp_nopush     on;

  # https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340
  keepalive_timeout  650;
  keepalive_requests 10000;

  #gzip  on;

  #include /etc/nginx/conf.d/*.conf;

  # start default.conf

  upstream backend {
    server esp.aptrinsic.com:443;
  }

  server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;


    server_tokens off;


    server_name _;


    location / {
      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_pass https://backend;
    }
  }
}

Content Proxy Tunnel settings

# merged nginx.conf default.conf
user  nginx;
# https://github.com/denji/nginx-tuning
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
  worker_connections  1024;
  use epoll;
  multi_accept on;
}


http

{
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for" "$request_body"';

  # docker logs have symlink to stdout
  # https://stackoverflow.com/questions/22541333/have-nginx-access-log-and-error-log-log-to-stdout-and-stderr-of-master-process
  access_log  off;

  sendfile        on;
  #tcp_nopush     on;

  # https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340
  keepalive_timeout  650;
  keepalive_requests 10000;

  #gzip  on;

  #include /etc/nginx/conf.d/*.conf;

  # start default.conf

  upstream backend {
    server web-sdk.aptrinsic.com:443;
  }

  server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;


    server_tokens off;


    server_name _;


    location / {
      proxy_set_header        Host "web-sdk.aptrinsic.com";
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_pass https://backend;
    }
  }
  • Was this article helpful?