---
title: Configuring NGINX Plus for PingIntelligence
description: Configure nginx.conf to set up NGINX Plus and PingIntelligence sideband integration.
component: pingintelligence
version: 5.2
page_id: pingintelligence:pingintelligence_integrations:pingintelligence_configure_nginx_plus_ubuntu1604
canonical_url: https://docs.pingidentity.com/pingintelligence/5.2/pingintelligence_integrations/pingintelligence_configure_nginx_plus_ubuntu1604.html
revdate: June 7, 2024
section_ids:
  about-this-task: About this task
  steps: Steps
  example: Example:
  example-2: Example:
  example-3: Example:
  example-4: Example:
  example-5: Example:
  choose-from: Choose from:
  example-6: Example:
---

# Configuring NGINX Plus for PingIntelligence

Configure `nginx.conf` to set up NGINX Plus and PingIntelligence sideband integration.

## About this task

To configure NGINX Plus for PingIntelligence:

## Steps

1. Create a `modules` directory in NGINX Plus:

   ```
   # mkdir /etc/nginx/modules
   ```

2. Download the NGINX Plus - PingIntelligence policy modules from the [PingIntelligence Downloads site](https://www.pingidentity.com/en/resources/downloads/pingintelligence.html).

3. Untar the downloaded file:

   ```
   # tar -xvzf pi-api-nginx-plus-policy-4.3.tar.gz
   ```

4. Copy the three PingIntelligence modules files for Ubuntu to the `modules` directory of NGINX Plus and the `pi-pf.conf` file to `/usr/local/nginx/conf/` directory.

   The three PingIntelligence modules are:

   * `ngx_ase_integration_module.so`

   * `ngx_http_ase_integration_request_module.so`

   * `ngx_http_ase_integration_response_module.so`

     The `pi-pf.conf` file has the OAuth policy details.

     ```
     # cp ngx_ase_integration_module.so /etc/nginx/modules
     # cp ngx_http_ase_integration_request_module.so /etc/nginx/modules
     # cp ngx_http_ase_integration_response_module.so /etc/nginx/modules
     # cp pi-pf.conf /usr/local/nginx/conf/
     ```

5. Change to `root` user:

   ```
   # sudo su
   ```

6. Export client credentials as environment variables.

   ```
   # export PF_ID=<ID>
   # export PF_SECRET=<SECRET>
   ```

   Here `PF_ID` and `PF_SECRET` are PingFederate client ID and secret.

7. Edit the `nginx.conf` file to load the PingIntelligence modules.

   ### Example:

   The following is a snippet of the `nginx.conf` file showing the loaded PingIntelligence modules:

   ```
   worker_processes  4;

   error_log  /usr/local/nginx/logs/error.log debug;
   worker_rlimit_core  500M;
   working_directory  /usr/local/nginx;

   pid        /usr/local/nginx/pid/nginx.pid;
   env PF_ID;
   env PF_SECRET;

   load_module modules/ngx_ase_integration_module.so; load_module modules/ngx_http_ase_integration_request_module.so; load_module modules/ngx_http_ase_integration_response_module.so; load_module modules/ndk_http_module.so; load_module modules/ngx_http_lua_module.so;

   events {
       worker_connections  1024;
   }
    truncated nginx.conf file
   ```

8. Configure ASE primary and secondary node IP address by replacing `IP:PORT` in the `nginx.conf` file snippet shown below:

   ### Example:

   ```
   http {

       keepalive_timeout  65;
       upstream ase.pi {
          server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10;
          server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10 backup;
          keepalive 32;
          #keepalive_timeout 3600s; # NOT allowed < 1.15.3
      }

   truncated nginx.conf file
   ```

9. Configure introspect server IP address by replacing `IP:PORT` in the `nginx.conf` file snippet show below:

   ### Example:

   ```
   upstream introspect_server {
           server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10;
           server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10 backup;
           keepalive 32;
       }

   truncated nginx.conf file
   ```

10. Configure the username and client ID keys in `nginx.conf`.

    These are the keys for username and client ID that you have configured in PingFederate.

    ```
    set $oauth_username_key  Username;
    set $oauth_client_id_key  ClientID;

    truncated nginx.conf file
    ```

11. Configure the token parameter name after `$arg_` and in `ase/request`:

    ```
    # Set the token parameter name below after $arg_ and inside /ase/request.
        set $oauth_key_param $arg_access_token;
        set $oauth_token_param $arg_access_token;
    	#ASE Request Proxy Configuration
           location = /ase/request {
           internal;
           ase_integration https://test.ase.pi;
           ase_integration_method "POST";
           ase_integration_http_version 1.1;
           ase_integration_ase_token $ase_token;
           ase_integration_correlation_id $correlationid;
           ase_integration_host $ase_host;
           # set token key here.
           ase_integration_token_key  access_token;
           ase_integration_ssl_trusted_certificate $certificate;
           ase_integration_ssl_verify    off;
           ase_integration_ssl_verify_depth 1;
           ase_integration_ssl_server_name off;
           ase_integration_ssl_name $ase_ssl_host;
           ase_integration_next_upstream error timeout non_idempotent;
        }

    truncated nginx.conf file
    ```

12. Configure the URL of the introspection server:

    ```
    # Set introspection URL
        set $oauth_url https://introspect_server/as/introspect.oauth2;

    truncated nginx.conf file
    ```

13. Configure the ASE sideband token.

    The sideband authentication token was created in step 4 of [Preparing to deploy the PingIntelligence policy](pingintelligence_nginx_plus_prepare.html).

    ### Example:

    The following is a snippet the showing certificate location and sideband authentication token:

    ```
     #ASE Token for sideband authentication
        set $ase_token  <ASE_TOKEN>;
    ```

14. Configure the ASE request and response API endpoints in `nginx.conf`.

    ### Example:

    The following snippet of `nginx.conf` shows ASE request and response:

    ```
     #ASE Request Proxy Configuration
        location = /ase/request {
           internal;
           ase_integration https://test.ase.pi;
           ase_integration_method "POST";
           ase_integration_http_version 1.1;
           ase_integration_ase_token $ase_token;
           ase_integration_correlation_id $correlationid;
           ase_integration_host $ase_host;
           # set token key here.
           ase_integration_token_key access_token;
           ase_integration_ssl_trusted_certificate $certificate;
           ase_integration_ssl_verify    off;
           ase_integration_ssl_verify_depth 1;
           ase_integration_ssl_server_name off;
           ase_integration_ssl_name $ase_ssl_host;
           ase_integration_next_upstream error timeout non_idempotent;
        }
        #ASE Response Proxy Configuration
        location = /ase/response {
           internal;
           ase_integration https://test.ase.pi;
           ase_integration_method "POST";
           ase_integration_http_version 1.1;
           ase_integration_ase_token $ase_token;
           ase_integration_correlation_id $correlationid;
           ase_integration_host $ase_host;
           ase_integration_ssl_trusted_certificate $certificate;
           ase_integration_ssl_verify    off;
           ase_integration_ssl_verify_depth 1;
           ase_integration_ssl_server_name off;
           ase_integration_ssl_name $ase_ssl_host;
           ase_integration_next_upstream error timeout non_idempotent;
        }

    truncated nginx.conf file
    ```

15. Apply the PingIntelligence policy either at the global level for all the APIs in your environment or for an individual API.

    |   |                                                                                                                                                                       |
    | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    |   | If the authorization header in the request has multiple tokens, the PingIntelligence policy extracts only the first valid bearer token from the authorization header. |

    ### Choose from:

    * To apply the PingIntelligence policy globally, add `ase_integration_request` and `ase_integration_response` in the `server` section of `nginx.conf` as shown below:

      ```
      server {
          listen              4443 ssl bind;
          server_name         localhost;
          ssl_certificate     /usr/local/nginx/ssl/cert.pem;
          ssl_certificate_key /usr/local/nginx/ssl/key.pem;
          ssl_password_file   /usr/local/nginx/ssl/password_file;
          ssl_protocols       TLSv1.2;
          ssl_ciphers         HIGH:!aNULL:!MD5;
          resolver 8.8.8.8 ipv6=off;
           ase_integration_request; ase_integration_response;

          # Set OAuth Client details
       truncated nginx.conf file
      ```

    * To apply the PingIntelligence policy for a specific API, configure `location` in `nginx.conf`.

      `ase_integration_request` should be the first and a `ase_integration_response` should be the last.

      |   |                                                                                                                                             |
      | - | ------------------------------------------------------------------------------------------------------------------------------------------- |
      |   | Comment-out the `ase_integration_request` and `ase_integration_response` that was configured to apply the PingIntelligence policy globally. |

      ```
      location / {
             include /usr/local/nginx/conf/pi-pf.conf;
             ase_integration_request;
             proxy_pass http://localhost:8080/;
             ase_integration_response;
      }

      truncated nginx.conf file
      ```

16. To verify the syntactical correctness of `nginx.conf`, run the following command:

    ```
    # /usr/local/nginx/sbin/nginx -t
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
    ```

17. Configure the PingIntelligence policy for NGINX Plus:

    1. Restart NGINX by entering the following command:

       ```
       # /usr/local/nginx/sbin/nginx -s stop
       # /usr/local/nginx/sbin/nginx
       ```

    2. Run the following command to verify if `--with-compat` and `--with-http_ssl_module` is in the list of flags under configured arguments:

       ```
       # sudo /usr/local/nginx/sbin/nginx -V
       nginx version: nginx/1.15.2 (nginx-plus-r16)
       built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
       built with OpenSSL 1.0.2g  1 Mar 2016
       TLS SNI support enabled
       configure arguments: --with-compat --with-http_ssl_module
       ```

    3. Verify that NGINX has restarted by entering the following command:

       ```
       # netstat -tulpn | grep 4443
       ```

       ### Example:

       The following is a sample `nginx.conf` file. Make sure that the PingIntelligence module and other configurations are added at the correct place in `nginx.conf` as shown in the sample file.

       ```
       worker_processes  4;

       error_log  /usr/local/nginx/logs/error.log debug;
       worker_rlimit_core  500M;
       working_directory  /usr/local/nginx;

       pid        /usr/local/nginx/pid/nginx.pid;
       env PF_ID;
       env PF_SECRET;

       load_module modules/ngx_ase_integration_module.so;
       load_module modules/ngx_http_ase_integration_request_module.so;
       load_module modules/ngx_http_ase_integration_response_module.so;
       load_module modules/ndk_http_module.so;
       load_module modules/ngx_http_lua_module.so;

       events {
           worker_connections  1024;
       }

       http {

           keepalive_timeout  65;
           upstream test.ase.pi {
              server IP:PORT max_fails=1 max_conns=100 fail_timeout=10;
              server IP:PORT max_fails=1 max_conns=100 fail_timeout=10 backup;
              keepalive 32;
       #      keepalive_timeout 3600s; # NOT allowed < 1.15.3
          }

           upstream introspect_server {
               server IP:PORT max_fails=1 max_conns=100 fail_timeout=10;
               server IP:PORT max_fails=1 max_conns=100 fail_timeout=10 backup;
               keepalive 32;
           }

           lua_shared_dict cache_dict 128m;

       server {
           listen              4443 ssl bind;
           server_name         localhost;
           ssl_certificate     /usr/local/nginx/ssl/cert.pem;
           ssl_certificate_key /usr/local/nginx/ssl/key.pem;
           ssl_password_file   /usr/local/nginx/ssl/password_file;
           ssl_protocols       TLSv1.2;
           ssl_ciphers         HIGH:!aNULL:!MD5;
           resolver 8.8.8.8 ipv6=off;
           ase_integration_request;
           ase_integration_response;

           # Set OAuth Client details

           # Set env variable PF_ID &PF_SECRET
           set_by_lua $client_id 'return os.getenv("PF_ID")';
           set_by_lua $client_secret 'return os.getenv("PF_SECRET")';

           # Uncomment next 2 lines to set client credentials here.
           # set $client_id nginx_client;
           # set $client_secret nginx_secret;

           set $oauth_username_key Username;
           set $oauth_client_id_key ClientID;

           # Set the token parameter name below after $arg_ and inside /ase/request.
           set $oauth_key_param $arg_access_token;
           set $oauth_token_param $arg_access_token;

           # Set cache lifetime, default is 120s.
           set $oauth_cache_timeout 120;

           # Set introspection URL
           set $oauth_url https://introspect_server/as/introspect.oauth2;

           location /introspect {
               internal;
               proxy_method    POST;
               if ($arg_auth_token) {
                   set $auth_token $arg_auth_token;
               }
                if ($http_authorization ~* .*?(bearer)(\s+)([-a-zA-Z0-9._~+/]+)(,|\s|$)) {
                   set $auth_token $3;
               }
               proxy_set_header  Content-Type "application/x-www-form-urlencoded";
               proxy_set_body  "client_id=${client_id}&client_secret=${client_secret}&token=${auth_token}";
               proxy_pass_request_body off;
               proxy_http_version 1.1;
               proxy_set_header Connection "";
               proxy_pass      $oauth_url;
           }

           location /shop {
              include /usr/local/nginx/conf/pi-pf.conf;
              proxy_pass http://18.209.173.37:4100/shop;

           }
           #DO NOT EDIT BELOW VARIABLE
           set $correlationid $pid-$request_id-$server_addr-$remote_addr-$remote_port-$request_length-$connection;
           #Certificate location of ASE
           set $certificate /usr/local/nginx/ssl/test.ase.pi;
           #ASE Token for sideband authentication
           set $ase_token <ASE_TOKEN>;
           #Host header which should be send to ASE
           set $ase_host test.ase.pi;
           #SNI value to use for ASE
           set $ase_ssl_host test.ase.pi;
           #ASE Request Proxy Configuration
           location = /ase/request {
              internal;
              ase_integration https://test.ase.pi;
              ase_integration_method "POST";
              ase_integration_http_version 1.1;
              ase_integration_ase_token $ase_token;
              ase_integration_correlation_id $correlationid;
              ase_integration_host $ase_host;
              # set token key here.
              ase_integration_token_key access_token;
              ase_integration_ssl_trusted_certificate $certificate;
              ase_integration_ssl_verify    off;
              ase_integration_ssl_verify_depth 1;
              ase_integration_ssl_server_name off;
              ase_integration_ssl_name $ase_ssl_host;
              ase_integration_next_upstream error timeout non_idempotent;
           }
           #ASE Response Proxy Configuration
           location = /ase/response {
              internal;
              ase_integration https://test.ase.pi;
              ase_integration_method "POST";
              ase_integration_http_version 1.1;
              ase_integration_ase_token $ase_token;
              ase_integration_correlation_id $correlationid;
              ase_integration_host $ase_host;
              ase_integration_ssl_trusted_certificate $certificate;
              ase_integration_ssl_verify    off;
              ase_integration_ssl_verify_depth 1;
              ase_integration_ssl_server_name off;
              ase_integration_ssl_name $ase_ssl_host;
              ase_integration_next_upstream error timeout non_idempotent;
           }
       }

       }
       ```
