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
Module | Documentation |
---|---|
ngx_http_core_module | https://nginx.org/en/docs/http/ngx_http_core_module.html |
ngx_http_proxy_module | https://nginx.org/en/docs/http/ngx_http_proxy_module.html |
ngx_http_ssl_module | https://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:
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:
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:
server {
...
location ^~ /data/ {
...
}
location ^~ /system/ {
...
}
location ^~ /res/ {
...
}
location ^~ /idp/ {
...
}
location ^~ /.well-known/ {
...
}
Example Configuration
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;
}
}