Configure the
nginx.conf
to setup NGINX Plus and PingIntelligence
sideband integration. Following is a summary of steps to configure NGINX Plus for
PingIntelligence:- Create
modules
directory inside NGINX working directory - Download PingIntelligence modules
- Copy PingIntelligence modules in the
modules
directory - Edit
nginx.conf
for PingIntelligence
Create modules
directory and download PingIntelligence
modules
- Create a
modules
directory in NGINX Plus:# mkdir /etc/nginx/modules
- Download the NGINX Plus - PingIntelligence modules from the download site
- Untar the downloaded file.
The three PingIntelligence modules are:# tar -xvzf pi-api-nginx-plus-policy-4.3.tar.gz
ngx_ase_integration_module.so
ngx_http_ase_integration_request_module.so
ngx_http_ase_integration_response_module.so
pi-pf.conf
file has the OAuth policy details. - Copy the three PingIntelligence modules files for Ubuntu to the
modules
directory of NGINX Plus and pi-pf.conf file to /usr/local/nginx/conf/ directory.# 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/
- Change to
root
user:# sudo su
- Export client credentials as environment variables:
Here# export PF_ID=<ID> # export PF_SECRET=<SECRET>
PF_ID
andPF_SECRET
are PingFederate client ID and secret.
Configure nginx.conf file
Complete the following steps to configure nginx.conf
for
PingIntelligence. Make sure that the PingIntelligence module and other
configurations are added at the correct place in nginx.conf
as
shown in the sample file at the end of the section.
- Load PingIntelligence modules: Edit the
nginx.conf
file to load the PingIntelligence modules. Following is a snippet ofnginx.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
- Configure ASE primary and secondary node: Configure ASE primary and
secondary node IP address by replacing IP:PORT in the
nginx.conf file
snippet show below: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
- Configure introspect server IP address: Configure introspect server
IP address by replacing IP:PORT in the
nginx.conf file
snippet show below: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
- Configure username and client ID key: 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
- Configure token parameter name: Configure the token parameter name after
$arg_
and inase/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
- Configure introspection URL: Configure the URL of the introspection
server:
# Set introspection URL set $oauth_url https://introspect_server/as/introspect.oauth2; truncated nginx.conf file
- Configure ASE Sideband token: The sideband authentication token was created as part of thePrerequisites in the PingIntelligence section. Following is a snippet the showing certificate location and sideband authentication token:
- Configure ASE request and response: Configure ASE request and
response API endpoints in
nginx.conf
. Following snippet ofnginx.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
- Apply PingIntelligence policy: You can apply PingIntelligence policy at the global
level, that is, for all the APIs in your environment or for an individual
API. Note: If the authorization header in the request has multiple tokens, the PingIntelligence policy extracts only the first valid bearer token from the authorization header.
- Apply PingIntelligence policy globally: To apply
PingIntelligence policy globally, add
ase_integration_request
andase_integration_response
in theserver
section ofnginx.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
- Apply PingIntelligence policy for a specific API: Apply
PingIntelligence modules for APIs by configuring
location
innginx.conf
.ase_integration_request
should be the first and aase_integration_response
should be the last.Note: Comment-out thease_integration_request
andase_integration_response
that was configured to apply 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
- Apply PingIntelligence policy globally: To apply
PingIntelligence policy globally, add
- Verify syntactical correctness of nginx.conf: 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
Final configuration steps: Complete the following steps to configure
PingIntelligence policy for NGINX Plus:
- Restart NGINX by entering the following
command:
# /usr/local/nginx/sbin/nginx -s stop # /usr/local/nginx/sbin/nginx
- 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
- Verify that NGINX has restarted by entering the following
command:
# netstat -tulpn | grep 4443
Following is a sample
nginx.conf
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;
}
}
}