Set Up Authentication

Follow the steps in this guide to configure authentication for Instance Manager.


This documentation applies to NGINX Management Suite Instance Manager 2.0.0 and later.


Note:
NGINX Plus is provided and intended only to be used with Instance Manager as a frontend. You should not use NGINX Plus for other web applications or instances. Contact your sales team to purchase additional subscriptions for external uses and other systems.

Prerequisites

  1. Install NGINX Management Suite.
  2. Install NGINX or NGINX Plus.
  3. Start and Enable Instance Manager and NGINX Plus (or NGINX).

Authentication Options

The following table shows the authentication options for Instance Manager on NGINX Open Source and NGINX Plus.

Table: Authentication options

Security Method NGINX OSS NGINX Plus
Commercial Support Included Included
Denylisting IPs N/A Supported
Basic Authentication Included Included
JWT Authentication N/A Included
OpenID Connect/OAuth2 N/A Supported
Rate-Limiting Included Included
Role Based Access Control N/A Supported

Basic Authentication

Warning:
Basic authentication is not secure and should not be used for production environments. Use OpenID Connect (OIDC) or another secure authentication method for production.

Basic authentication is enabled by default. When installing NGINX Management Suite, a default username of admin is created with a randomly generated password that’s displayed in the installation output. You can change the default admin password by editing the /etc/nms/nginx/.htpasswd file, explained below.

Initially, the admin user is the only user with a role assigned. To give other users access to NGINX Management Suite, you need to add users and assign them roles.

Basic authentication uses a username and password that you can set locally in the /etc/nms/nginx/.htpasswd file.

To restrict user access with basic authentication, take the following steps:

  1. Add users using the NGINX Management Suite web interface. Note each user’s username for step 2.

  2. Add each user’s username and password to the /etc/nms/nginx/.htpasswd file on the NGINX Management Suite server. See Restricting Access with HTTP Basic Auth for instructions on working with a password file.

    If desired, you can use separate .htpasswd files in different locations or restrict by IP addresses. Refer to the guide Restricting Access with HTTP Basic Authentication for more information.


JWT Authentication

You can use JSON Web Token (JWT) Authentication with NGINX Plus and Instance Manager. You need to create the JWT or use an identity provider (idP) to generate the JWT. For more examples, refer to the NGINX documentation Setting up JWT Authentication.

Below is an example NGINX conf for using JWT.

/etc/nginx/conf.d/nginx-manager-jwt.conf

nginx-manager-jwt.conf

# nginx-manager-jwt.conf
# Proxy API with JWT to 127.0.0.1 on nginx-manager
# Include the nginx-manager-upstreams.conf for the proxy_pass to work
# Ensure you have permissions set in the directories
# More information is available <https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/>

map $jwt_claim_sub $jwt_status {
    "quotes" "revoked";
    "test"   "revoked";
    default  "";
}

limit_req_zone $jwt_claim_sub zone=10rps_per_client:1m rate=10r/s;

log_format jwt '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
               '$jwt_header_alg $jwt_claim_uid $jwt_claim_url' ;

# reverse proxy with JWT authentication
#
server {
    listen      443 http2 ssl;
    status_zone nginx-manager_oauth_https;
    server_name nginx-manager.example.com;

    # Optional log locations
    # error_log /var/log/nginx/nginx-manager-jwt-error.log debug; # Reduce severity level as required   

    # SSL certificates must be valid for the FQDN and placed in the correct directories
    ssl_certificate             /etc/nms/certs/manager-server.crt;
    ssl_certificate_key         /etc/nms/certs/manager-server.key;
    # ssl_client_certificate    /etc/ssl/nginx-manager/ca.pem;

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 24h;
    ssl_session_tickets off;

    ssl_protocols   TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers   off;
    
    # Could change to /api for multiple methods of auth
    location / {
        # JWT validation
        auth_jwt "JWT Test Realm" token=$arg_myjwt;    # Change to realm you use or "" for no realm
        auth_jwt_key_file /etc/nginx/api_secret.jwk;

        if ( $jwt_status = "revoked" ) {
            return 403;
        }

        limit_req zone=10rps_per_client;

        proxy_pass http://nginx-manager_servers;
        health_check uri=/swagger-ui/;

        # Successfully authenticated users are proxied to the backend,
        # with 'sub' claim passed as HTTP header
        proxy_set_header Nginx-Management-Suite-User $jwt_claim_sub;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        client_max_body_size 0;

        access_log /var/log/nginx/nginx-manager-jwt-access.log jwt;
    }

}

# vim: syntax=nginx

OpenID Connect

You can enable OpenID Connect (OIDC) for Instance Manager for production environments that require secure authentication.

Warning:
Before switching from Basic Auth to OIDC, make sure to add at least one admin user to your identity provider. A failure to do so may lock admin users out of Instance Manager when you enable OIDC. If that happens, you can revert to Basic Auth to restore access.
See Also:
Follow the steps in Configure OIDC with Azure Active Directory to secure Instance Manager with OpenID Connect (OIDC) using Azure Active Directory (AD) as the identity provider.

Prerequisites

To use OIDC with Instance Manager, you need to perform the following:

Enable OIDC

The OIDC configuration file (openid_configuration.conf) includes placeholder default values in map blocks that need to be updated for OIDC to work.

  1. Open the OIDC configuration file /etc/nms/nginx/oidc/openid_configuration.conf for editing and update the placeholder values with the information for your identity provider (See variable descriptions below). Save the changes.

  2. Open the NGINX Management Suite configuration file /etc/nginx/conf.d/nms-http.conf for editing and uncomment the OIDC settings beginning with #OIDC and comment out the settings for Basic Auth. Save the changes.

  3. If you are running additional modules, such as API Connectivity Manager, you will need to modify module-specific configuration files.

    • Open the API Connectivity Manager configuration file /etc/nms/nginx/locations/nms-acm.conf for editing, uncomment the OIDC settings beginning with #OIDC, and comment out the settings for Basic Auth. Save the changes.
  4. Run sudo nginx -t to verify the config has no errors.

  5. Run sudo nginx -s reload to reload and apply the config.

The following information is needed to configure the service:

Table: OIDC Metadata via Well-Known Endpoints

Variable Description
$oidc_authz_endpoint URL of the IdP’s OAuth 2.0 Authorization endpoint.
$oidc_jwt_keyfile URL of the IdP’s JSON Web Key Set document.
$oidc_logout_endpoint URL of the IdP’s end_session endpoint.
$oidc_token_endpoint URL of the IdP’s OAuth 2.0 Token endpoint.
$oidc_userinfo_endpoint URL of the IdP’s UserInfo endpoint.
$oidc_host URL of the IdP’s application. For example, https://{my-app}.okta.com
$oidc_scopes List of the OAuth 2.0 scope values that this server supports.
For example, openid+profile+email+offline_access

Table: OIDC Custom Configuration for Well-Known Endpoints

Variable Description
$oidc_authz_path_params_enable 1: Enable custom path params when {arbitrary param-name} is in the $oidc_authz_endpoint.
0: Disable it.
$oidc_authz_path_params Use for when $oidc_authz_path_params_enable is enabled.

Example:
map $host $oidc_authz_endpoint { 
default “https://{my-app}.okta.com/oauth2/{version}/authorize”;
}
map $host $oidc_authz_path_params {
default ‘{ “my-app”: “{my-app}”, “version”: “v1” }';
}
$oidc_authz_query_params_enable 1: Enable additional query params when the $oidc_authz_endpoint needs them.
0: Disable it.
$oidc_authz_query_params Use for when $oidc_authz_query_params_enable is enabled.

Example:
 map $host $oidc_authz_query_params { 
default ‘{
“response_type”: “code”,
“scope” : “$oidc_scopes”,
“client_id” : “$oidc_client”,
“redirect_uri” : “$redirect_base$redir_location”,
“nonce” : “$nonce_hash”,
“state” : 0
}';
$oidc_logout_path_params_enable 1: Enable custom path params when {arbitrary param-name} is in the $oidc_logout_endpoint.
0: Disable it.
$oidc_logout_path_params Use for when $oidc_logout_path_params_enable is enabled.

Example:
map $host $oidc_logout_endpoint { 
default “https://{my-app}.okta.com/oauth2/{version}/logout”;
}
map $host $oidc_authz_path_params {
default ‘{ “my-app”: “{my-app}”, “version”: “v1” }';
}
$oidc_logout_query_params_enable 1: Enable additional query params when the IdP doesn’t support OIDC RP-initiated logout.
0: OIDC RP-initiated logout.
$oidc_logout_query_params Use for when $oidc_logout_query_params_enable is enabled.

Example:
 map $host $oidc_logout_query_params {
# example 1. AWS Cognito Logout & prompt a user to sign in as another user.
default ‘{
“response_type”: “code”,
“client_id” : “$oidc_client”,
“redirect_uri” : “$redirect_base$redir_location”,
“state” : “STATE”,
“scope” : “$oidc_scopes”
}';

# example 2. AWS Cognito Logout & redirect back to client.
default ‘{
“client_id” : “$oidc_client”,
“logout_uri” : “$redirect_base/_logout”
}';

$oidc_token_path_params_enable 1: Enable custom path params when {arbitrary param-name} is in the $oidc_token_endpoint.
0: Disable it.
$oidc_token_path_params Use for when $oidc_token_path_params_enable is enabled.

Example:
map $host $oidc_token_endpoint { 
default “https://{my-app}.okta.com/oauth2/{version}/token”;
}
map $host $oidc_authz_path_params {
default ‘{ “my-app”: “{my-app}”, “version”: “v1” }';
}
$oidc_token_query_params_enable 1: Enable additional query params when the $oidc_token_endpoint needs them.
0: Disable it.
$oidc_token_query_params Use for when $oidc_token_query_params_enable is enabled.

Example:
map $host $oidc_token_query_params { 
default ‘{ “example”: “data” }';
}

Table: OIDC Advanced Configuration

Variable Description
$oidc_client IdP’s client ID which is a public identifier for the client that is required for all OAuth flows.
$oidc_client_secret IdP’s client secret which is used by the client to exchange an authorization code for a token.
It should be an empty value with "" when PKCE is enabled.
$oidc_hmac_key Hash-based Message Authentication Code (or HMAC) is a cryptographic technique that combines public keys, private keys, and a hash into a mix hackers can’t unpack.
It should be unique for every NGINX instance/cluster.
$oidc_logout_redirect URI to be redirected by the IdP after successful logout from the IdP.
This should be configured in your IdP.
$oidc_pkce_enable PKCE is an OAuth 2.0 security extension for public clients on mobile devices or single page apps intended to avoid a malicious programme creeping into the same computer from intercepting the authorization code.

1: Enable PKCE
0: Disable PKCE
$oidc_app_name IdP’s application name.

gRPC Metadata

You can use advanced NGINX Plus features such as JWT and gRPC by following the guides on the NGINX blog. Use the encryption guide for setting up gRPC on Instance Manager.


Rate-Limiting

Enabling rate-limiting can help mitigate and prevent DDoS attacks and should be enabled for the API and web interface listeners. Using a configuration file similar to the one below can be leveraged with other authentication and encryption methods.

/etc/nginx/conf.d/nginx-manager-jwt.conf

nginx-manager-jwt.conf

# nginx-manager-jwt.conf
# Proxy API with JWT to 127.0.0.1 on nginx-manager
# Include the nginx-manager-upstreams.conf for the proxy_pass to work
# Ensure you have permissions set in the directories
# More information is available <https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/>

map $jwt_claim_sub $jwt_status {
    "quotes" "revoked";
    "test"   "revoked";
    default  "";
}

limit_req_zone $jwt_claim_sub zone=10rps_per_client:1m rate=10r/s;

log_format jwt '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
               '$jwt_header_alg $jwt_claim_uid $jwt_claim_url' ;

# reverse proxy with jwt authentication
#
server {
    listen      443 http2 ssl;
    status_zone nginx-manager_oauth_https;
    server_name nginx-manager.example.com;

    # Optional log locations
    # error_log /var/log/nginx/nginx-manager-jwt-error.log debug; # Reduce severity level as required   

    # SSL certificates must be valid for the FQDN and placed in the correct directories
    ssl_certificate             /etc/nms/certs/manager-server.crt;
    ssl_certificate_key         /etc/nms/certs/manager-server.key;
    # ssl_client_certificate    /etc/ssl/nginx-manager/ca.pem;

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 24h;
    ssl_session_tickets off;

    ssl_protocols   TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers   off;
    
    # Could change to /api for multiple methods of auth
    location / {
        # JWT validation
        auth_jwt "JWT Test Realm" token=$arg_myjwt;    # Change to realm you use or "" for no realm
        auth_jwt_key_file /etc/nginx/api_secret.jwk;

        if ( $jwt_status = "revoked" ) {
            return 403;
        }

        limit_req zone=10rps_per_client;

        proxy_pass http://nginx-manager_servers;
        health_check uri=/swagger-ui/;

        # Successfully authenticated users are proxied to the backend,
        # with 'sub' claim passed as HTTP header
        proxy_set_header Nginx-Management-Suite-User $jwt_claim_sub;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        client_max_body_size 0;

        access_log /var/log/nginx/nginx-manager-jwt-access.log jwt;
    }

}

# vim: syntax=nginx

Role-Based Access Control

For instruction on how to limit access to features using role-based access control, see the Set Up RBAC tutorial.


What’s Next