Skip to main content
Version: 8.1

Defining SSL on a Perspective Reverse Proxy

Reverse Proxy Use Cases

While a forward proxy proxies on behalf of clients (or requesting hosts), a reverse proxy proxies on behalf of servers. There are many possible use cases for placing Perspective behind a reverse proxy:

  • Control what resources the user is able to access
  • Direct traffic to a portion of the web server
  • Limit which projects are accessible to users via subdomains
  • Define an SSL certificate on the reverse proxy

For this example, we will use NGINX to define an SSL certificate and key on a reverse proxy. NGINX is a popular choice for reverse proxies, though other open source servers such as Varnish, Apache, and Traefik provide similar functionality.

Installation

Install NGINX or NGINX Plus following the relevant installation instructions. Obtain a Signed Security Certificate (SSL) Place the SSL certificate and key in the directory where you installed NGINX under etc/nginx/ssl/

Configuring NGINX

In this example, we will create an nginx.conf file that specifies the configuration of our server. This section details the modules and properties that are required to configure Perspective behind a reverse proxy; for a more general overview of a proxy server configuration, see the NGINX Admin Guide.

Required NGINX Modules

ModuleDocumentation
ngx_http_core_modulehttps://nginx.org/en/docs/http/ngx_http_core_module.html
ngx_http_proxy_modulehttps://nginx.org/en/docs/http/ngx_http_proxy_module.html
ngx_http_ssl_modulehttps://nginx.org/en/docs/http/ngx_http_ssl_module.html

Websocket Proxying

For compatibility with Perspective's Websocket connections, we change the HTTP version to 1.1. In order to pass hop-by-hop headers from the client to the proxied server, the "Upgrade" and "Connection" headers must be passed explicitly in the configuration file:

Example
proxy_http_version 1.1;                    
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Custom Headers

In cases where a reverse proxy or other middleware is located between the Gateway and a running Perspective session, the proxy server will need to whitelist custom headers. Doing so ensures that the proxy allows requests from the session to pass through to the Gateway. To allow requests with custom headers, you will need to enable proxy_pass_request_headers in your configuration file:

Example
location / {
proxy_pass https://localhost:8043/data/perspective/client/demo/;
proxy_http_version 1.1;
...
proxy_pass_request_headers on;
...

Additional Location Contexts

Perspective sessions require resources within several folders that must be defined as additional location contexts within the configuration file. The following additional locations are required to enable the Perspective session to run the reverse proxy:

Example
server { 
...
location ^~ /data/ {
...
}
location ^~ /system/ {
...
}
location ^~ /res/ {
...
}
location ^~ /idp/ {
...
}
location ^~ /.well-known/ {
...
}

Example Configuration

nginx.conf
server {                            
listen 443 ssl;
listen [::]:443 ssl;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
server_name demo.xxx.com;

underscores_in_headers on;

# Specify the paths to your SSL certificate and key:
ssl_certificate /etc/nginx/ssl/reverse_proxy.crt;
ssl_certificate_key /etc/nginx/ssl/reverse_proxy.key;


# The next few location contexts define how to process resources required by the Perspective session.
# If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.
location ^~ /data/ {
proxy_pass https://localhost:8043/data/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}

location ^~ /system/ {
proxy_pass https://localhost:8043/system/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}

location ^~ /res/ {
proxy_pass https://localhost:8043/res/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}

location ^~ /idp/ {
proxy_pass https://localhost:8043/idp/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}

location ^~ /.well-known/ {
proxy_pass https://localhost:8043/.well-known/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}

# Here we are setting the protocol type, address, port, and uri (optional)
# that will be the destination of our proxied server:
location / {
proxy_pass https://localhost:8043/data/perspective/client/demo/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
}
}