Running with a Proxy
Overview
Posit Workbench runs a fully managed Nginx HTTP server that can be customized for SSL, security and more. It is configured from settings in rserver.conf (e.g. ssl-enabled, www-address) and can be customized with additional Nginx directives. See Customizing default proxy for more info on customizing the built-in proxy server.
Even with a built-in Nginx server, it’s common for customers to also use an external proxy server that runs in front of Workbench for security, to bridge firewalls, or to leverage an existing IT proxy server. This section describes how to configure an external proxy server to proxy traffic to and from Workbench.
If you are installing a new Apache or Nginx proxy server, see the complete examples for Nginx Configuration and Apache Configuration for a quicker start. These step-by-step instructions allow you to customize those examples or update an existing proxy server’s configuration.
Add a proxy pass directive
The proxy pass directive controls which URLs are forwarded to Workbench. If the proxy server is shared with other applications, choose a path prefix that identifies Workbench requests, e.g., /rstudio
. Otherwise, for a dedicated proxy server, send all requests to Workbench by specifying a location of /
. The proxy pass directive requires the host name or ip address of Workbench. In the examples below, replace localhost with Workbench’s host name or ip address when the proxy server is not local. The proxy pass directive also requires a protocol in the target URL. Use https when Workbench itself has SSL enabled (with the setting ssl-enabled=1 in rserver.conf), otherwise use http.
Here’s the proxy_pass directive for Nginx with the /rstudio prefix and ssl-enabled=0:
{
location /rstudio # Removes /rstudio from the URL
$1 break;
rewrite ^/rstudio(.*)$ /8787;
proxy_pass http://localhost:# other directives go here
}
or for Nginx with no prefix:
{
location / 8787;
proxy_pass http://localhost:# other directives go here
}
For Apache with the /rstudio prefix:
8787/$1 [P,L]
RewriteRule /rstudio/(.*) http://localhost:8787/ ProxyPass /rstudio/ http://localhost:
or for Apache with no prefix:
8787/ ProxyPass / http://localhost:
Set HTTP headers
To properly generate externally resolvable redirect URLs and cookie domain paths, Workbench needs the external proxy server’s host name, port, protocol and optional path prefix. These should be similar to those used in a location redirect for HTTP.
Hostname and port
By default, Workbench obtains the hostname and port from the standard HTTP Host header. This value is set by the browser and forwarded to Workbench but it’s important to set it in the proxy configuration as well. Those headers are optional in HTTP and resetting them prevents tampering from the browser, and prevents the proxy server from rewriting the Host header to the internal hostname. It’s usually possible to add a Set-Header
directive to the proxy server configuration that sets Host to the correct external hostname. Add the :serverport
suffix if you are not using default ports for http
/https
.
Server protocol
If the proxy server is configured for SSL and Workbench is not the X-Forwarded-Proto
header should be set to https
.
This will prevent Workbench from changing the protocol of generated URLs from https
to http
when it performs a redirect. For example, if the header is not set the login page will redirect back to http://servername
instead of https://servername
.
Path prefix
If you configured the ProxyPass directive with a path prefix, configure the www-root-path
attribute in /etc/rstudio/rserver.conf
so that Workbench knows to add this path prefix to any external URLs it generates.
/etc/rstudio/rserver.conf
www-root-path=/rstudio
Alternatively, to configure the path-prefix entirely in the proxy server’s configuration, add a proxy set header directive to set the HTTP header X-RStudio-Root-Path
with the value of your path prefix - e.g. /rstudio
.
The header X-RStudio-Root-Path
and the configuration option www-root-path
serve the same purpose. If either is set Workbench will always return cookies and redirects for the correct path, without requiring rewrite assistance from the proxy. The header value has precedence over the configuration value.
Alternate headers
Workbench supports other HTTP headers as alternative ways to inform it of the hostname, server port, protocol, and path prefix:
To set all of the values with one header, use:
-RStudio-Request protocol://server-name:server-port/path-prefix X
For example:
-RStudio-Request https://www.example.com:8787/rstudio X
Just as with X-Forwarded-Proto
, if your proxy server already sets the headers X-Forwarded-Host
and X-Forwarded-Port
they can be used to ensure Workbench redirects to the correct hostname and port, respectively.
Similarly Workbench supports the standard Forwarded
header for retrieving the host= and proto= fields.
When not using a custom path prefix, the hostname used by Workbench will always come from the Host header, not from X-Forwarded-Host, X-RStudio-Request, or Forwarded.
Forwarding websockets
Beyond the normal reverse proxy configuration you’d apply for any HTTP server application, you also need to ensure that websockets are forwarded correctly between the proxy server and Workbench to ensure that all Workbench functions work correctly. In particular, they’re needed for Shiny applications and VS Code sessions.
The configuration to forward websockets varies for each proxy server. There are examples for enabling websockets in Nginx Configuration and Apache Configuration.
Check the connection timeout
It’s also important to ensure that your reverse proxy allows long-standing connections or uses a relatively lenient connection timeout; we recommend at least 60 seconds. Several components of Workbench use HTTP Long Polling to push information to the browser; a connection timeout of under 50 seconds will result in HTTP 504 (gateway timeout) errors from the reverse proxy.
Shiny applications will close abruptly if the websocket is timed out by a proxy server.
Starting a VS Code session will show a blank page if the websocket connection is not fowarded.
Nginx configuration
On Debian or Ubuntu a version of Nginx that supports reverse-proxying can be installed using the following command:
sudo apt-get install nginx
On CentOS or Red Hat you can install Nginx using the following command:
sudo yum install nginx
To enable an instance of Nginx running on the same server to act as a front-end proxy to Workbench you would add commands like the following to your nginx.conf
file. These examples represent the customizable chunks but you should insert each chunk under http, server, and location to modify your nginx.conf file as necessary. Note that you must add the configuration below to proxy websockets in order to correctly display Shiny apps and R Markdown Shiny documents in Workbench. Also note that if you are proxying to a server on a different machine you need to replace references to localhost
with the correct address of the server where you are hosting Workbench.
http {
# Support proxying of web-socket connections
$http_upgrade $connection_upgrade {
map
default upgrade;'' close;
}
server {80;
listen
/ {
location ://localhost:8787;
proxy_pass http1.1;
proxy_http_version $http_upgrade;
proxy_set_header Upgrade $connection_upgrade;
proxy_set_header Connection
# Set the Host header to match how users access your site. Omit :server_port if using the default 80/443
# so that this value will match the Origin: header for CORS (cross origin security validation)
$host:$server_port;
proxy_set_header Host
proxy_read_timeout 20d;
}
} }
If you want to serve Workbench from a custom path (e.g. /rstudio) update your nginx.conf
file with the directives shown below. Replace all occurrences of /rstudio with your chosen custom path prefix.
http {
# Support proxying of web-socket connections
$http_upgrade $connection_upgrade {
map
default upgrade;'' close;
}
server {80;
listen
/rstudio/ {
location # Needed only for a custom path prefix of /rstudio
^/rstudio(.*)$ /$1 break;
rewrite
# Use http here when ssl-enabled=0 is set in rserver.conf
://localhost:8787;
proxy_pass http
1.1;
proxy_http_version $http_upgrade;
proxy_set_header Upgrade $connection_upgrade;
proxy_set_header Connection
proxy_read_timeout 20d;
# Not needed if www-root-path is set in rserver.conf
-RStudio-Root-Path /rstudio;
proxy_set_header X
# Set the Host header to match how users access your site. Omit :server_port if using the default 80/443
# so that this value will match the Origin: header for CORS (cross origin security validation)
$host:$server_port;
proxy_set_header Host
}
} }
If the Nginx proxy is using SSL and Workbench has ssl-enabled=0, use the directives from this example:
http {# Support proxying of web-socket connections
$http_upgrade $connection_upgrade {
map
default upgrade;'' close;
}
server {443 ssl http2;
listen ::]:443 ssl http2;
listen [
server_name localhost;
# Change to point to your certs
/etc/ssl/certs/localhost.crt;
ssl_certificate /etc/ssl/private/localhost.key;
ssl_certificate_key
.2 TLSv1.1 TLSv1;
ssl_protocols TLSv1
/rstudio {
location # Needed only for prefix of /rstudio
^/rstudio(.*)$ /$1 break;
rewrite
# Use http here when ssl-enabled=0 is set in rserver.conf
://localhost:8787;
proxy_pass http1.1;
proxy_http_version
$http_upgrade;
proxy_set_header Upgrade $connection_upgrade;
proxy_set_header Connection
# Set the Host header to match how users access your site. Omit :server_port if using the default 80/443
# so that this value will match the Origin: header for CORS (cross origin security validation)
$host:$server_port;
proxy_set_header Host
# Not needed if there's no prefix or www-root-path is set in rserver.conf
-RStudio-Root-Path /rstudio;
proxy_set_header X
# Tells Workbench to send redirect URLs back to https
-Forwarded-Proto https;
proxy_set_header X
proxy_read_timeout 20d;
}
} }
After adding these entries you’ll then need to restart Nginx so that the proxy settings take effect:
sudo /etc/init.d/nginx restart
or
sudo systemctl restart nginx
In some cases, such as when streaming job statuses from the launcher, the default response buffering in nginx can be too slow for delivering real-time updates, especially when configured to use SSL. If job output streams are not working properly from the home page, we recommend disabling response buffering by adding the following line under the server
directive:
server {# ... follows previous configuration
proxy_buffering off; }
Apache configuration
To enable an instance of Apache running on the same server to act as a front-end proxy to Workbench you need to use the mod_proxy
and mod_proxy_wstunnel
modules. The steps for enabling this module vary across operating systems so you should consult your distribution’s Apache documentation for details. Apache as reverse proxy already includes X-Forwarded-Host
(with port) and X-Forwarded-Proto
by default.
On Debian and Ubuntu systems Apache can be installed with mod_proxy
using the following commands:
sudo apt-get install apache2
sudo apt-get install libapache2-mod-proxy-html
sudo apt-get install libxml2-dev
Then, to update the Apache configuration files to activate mod_proxy
you execute the following commands:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
On CentOS and RedHat systems Apache can be installed with mod_proxy
and mod_proxy_wstunnel
by following the instructions here:
http://httpd.apache.org/docs/2.4/platform/rpm.html
By default with Apache 2.4, mod_proxy
and mod_proxy_wstunnel
should be enabled. You can check this by opening the file /etc/httpd/conf.modules.d/00-proxy.conf
and making sure the following lines are included and not commented out:
proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so LoadModule
Once you have enabled mod_proxy
and mod_proxy_wstunnel
in your Apache installation you need to add the required proxy commands to your VirtualHost
definition. Note that you will also need to include code to correctly proxy websockets in order to correctly proxy Shiny apps and R Markdown documents within Workbench. Also note that if you are proxying to a server on a different machine you need to replace references to localhost
with the correct address of the server where you are hosting Workbench.
For Apache, if you are setting the Host header, you must enable the option:
ProxyPreserveHost On
Workbench relies on the Host header matching what the browser sees. If ProxyPreserveHost is Off, the server and port are changed in the Host header and URLs will point to the wrong server and port.
In the examples below, change example.com:80
to the hostname:port
users will use to access your site and change localhost:8787
to the hostname:port
of your RSW server.
Here’s an example where the proxy server is not configured with SSL or a path prefix, and where SSL is also not enabled (i.e. ssl-enabled=0
in rserver.conf
) for RSW.
ProxyPreserveHost On
<VirtualHost *:80>
<Proxy *>
from localhost
Allow</Proxy>
/ http://localhost:8787/
ProxyPass / http://localhost:8787/
ProxyPassReverse set Host example.com:80
RequestHeaderProxyRequests Off
</VirtualHost>
If you want to serve Workbench from a custom path (e.g. /rstudio) use this example. Replace all occurrences of /rstudio with your chosen custom path prefix.
ProxyPreserveHost On
<VirtualHost *:80>
<Proxy *>
from localhost
Allow</Proxy>
/rstudio/ http://localhost:8787/
ProxyPass set Host "example.com:80"
RequestHeader set X-RStudio-Root-Path "/rstudio"
RequestHeaderProxyRequests Off
</VirtualHost>
Use this example for a proxy server that supports SSL, also using a custom path prefix. For this example, you need to install the mod_ssl module for Apache.
ProxyPreserveHost On
<Proxy *>
from localhost
Allow</Proxy>
/rstudio/ http://localhost:8787/
ProxyPass set Host "example.com:443"
RequestHeader set X-RStudio-Root-Path "/rstudio"
RequestHeader set X-Forwarded-Proto https
RequestHeaderProxyRequests Off
/etc/rstudio/rserver.conf
www-root-path=/rstudio
Finally, after you’ve completed all of the above steps you’ll then need to restart Apache so that the proxy settings take effect:
sudo /etc/init.d/apache2 restart
or
sudo systemctl restart httpd
Workbench configuration
If your Workbench and proxy server are running on the same machine you can also change the port Workbench listens on from 0.0.0.0 (all remote clients) to 127.0.0.1 (only the localhost). This ensures that the only way to connect to Workbench is through the proxy server. You can do this by adding the www-address
entry to the /etc/rstudio/rserver.conf
file as follows:
www-address=127.0.0.1
Note that you may need to create this config file if it doesn’t already exist.
Customizing default proxy
Workbench exposes itself over TCP by means of an nginx proxy instance that runs as the rserver-http
process on the local machine. In some cases, this proxy instance may need to be customized.
In order to customize it, you can create any of the following three files. Each file modifies the nginx configuration at /var/lib/rstudio-server/conf/rserver-http.conf
in the following way:
/etc/rstudio/nginx.http.conf
- allows you to add additional nginx directives under the roothttp
node, and should be used for altering basic HTTP settings/etc/rstudio/nginx.server.conf
- allows you to add additional nginx directives under theserver
node, and should be used for altering basic server settings/etc/rstudio/nginx.site.conf
- allows you to add additional nginx directives under thelocation /
node, and should be used for altering responses sent from Workbench
Simply add the desired nginx configuration in the files above to modify the desired section - the contents of each file is copied into the rserver-http.conf
template verbatim. Then, restart rstudio-server
for the changes to take effect.
In most cases, you should not need to create these files and modify the nginx template that is provided.