When hardening your Posit servers, there are a number of options available:
Posit Workbench: https://docs.posit.co/ide/server-pro/access_and_security/access_and_security.html
Posit Connect: https://docs.posit.co/connect/admin/security/#strong-https
Posit Package Manager: https://docs.posit.co/rspm/admin/security
To this end, our most common support request is for stronger HTTPS protocols. Each product has an allowance for broad-stroke TLS version configuration:
In Workbench:
# /etc/rstudio/rserver.conf
ssl-protocols=TLSv1.2 TLSv1.3
https://docs.posit.co/ide/server-pro/access_and_security/secure_sockets.html#ssl-protocols
In Connect:
# /etc/rstudio/rstudio-connect.gcfg
[HTTPS] Listen = 443 MinimumTLS = 1.2
https://docs.posit.co/connect/admin/security/#strong-https
In Package Manager:
# /etc/rstudio-pm/rstudio-pm.gcfg [HTTPS] Listen = 443 MinimumTLS = 1.2
https://docs.posit.co/rspm/admin/security/#strong-https
With Connect and Package Manager, we are often asked for fine-grained, per-cipher, exclusion options - here is what this type of request might look like:
"We need to disable TLSv1.1 and we need to disable DES, 3DES, IDEA, and RC2 ciphers, on our HTTPS/SSL enabled RStudio Package Manager instance."
Unfortunately, due to decisions outside of our control(1) we no longer offer the HTTPS.ExcludedCiphers
configuration option, and our advice is putting the server behind a reverse proxy and utilising that proxy's cipher suite modules.
This document will go through the setting up of both nginx
and apache2
proxies, and how to then configure each of Connect and Package Manager accordingly.
Using nginx as a reverse proxy
Connect
Using what we know from the simple Connect and proxy set up, we will add the necessary lines to the appropriate nginx
configuration file.
First, set up the nginx
configuration per the appropriate documentation:
https://docs.posit.co/connect/admin/proxy/#simple-configuration
Then, using the ssl_ciphers
syntax
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
and using the openssl
library's format described here:
https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
For the above request "we need to disable DES, 3DES, IDEA, and RC2 ciphers", this is what we want to see:
http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; client_max_body_size 0; # Disables checking of client request body size ssl_prefer_server_ciphers on; ssl_ciphers -DES:-3DES:-IDEA:-RC2; location / { proxy_set_header X-RSC-Request $scheme://$http_host$request_uri; proxy_pass http://localhost:3939; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_http_version 1.1; proxy_buffering off; # Required for XHR-streaming } } }
Note that we have added the directive ssl_prefer_server_ciphers
as well - this is because a server will naturally default to the client's cipher choice.
Package Manager
For Package Manager, it will be the same two lines, added to the appropriate nginx
configuration:
https://docs.posit.co/rspm/admin/proxy/#nginx-configuration
http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; ssl_prefer_server_ciphers on; ssl_ciphers -DES:-3DES:-IDEA:-RC2; location / { proxy_set_header X-RSPM-Request $scheme://$host:$server_port$request_uri; proxy_pass <http://localhost:4242>; } } }
Using Apache as a reverse proxy
Connect
Using what we know from the simple Connect and proxy set up, we will add the necessary lines to the appropriate apache
configuration file.
First, set up the apache
configuration per the appropriate documentation:
https://docs.posit.co/connect/admin/proxy/#simple-configuration_1
Then, using the SSLCipherSuite
syntax
https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html#onlystrong
and using the openssl
library's format described here:
https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
For the above request "we need to disable DES, 3DES, IDEA, and RC2 ciphers", this is what we want to see:
LoadModule ssl_module modules/mod_ssl.so Listen 80 <VirtualHost *:80> SSLCipherSuite -DES:-3DES:-IDEA:-RC2
RewriteEngine on # store variable values with dummy rewrite rules RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}] RewriteRule . - [E=http_host:%{HTTP_HOST}] RewriteRule . - [E=req_uri:%{REQUEST_URI}] # set header with variables RequestHeader set X-RSC-Request "%{req_scheme}e://%{http_host}e%{req_uri}e" # unprefixed websocket proxying RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/(.*) "ws://localhost:3939/$1" [P,L] <Location /> ProxyPass http://localhost:3939/ connectiontimeout=5 </Location> </VirtualHost>
Package Manager
For Package Manager, it will be the same two lines, added to the appropriate apache
configuration:
https://docs.posit.co/rspm/admin/proxy/#apache-configuration
LoadModule ssl_module modules/mod_ssl.so Listen 3737 <VirtualHost *:3737> SSLCipherSuite -DES:-3DES:-IDEA:-RC2 RewriteEngine on RequestHeader set X-RSPM-Request "%{REQUEST_SCHEME}s://%{HTTP_HOST}s%{REQUEST_URI}s" ProxyPass / <http://172.17.0.1:4242/> ProxyPassReverse / <http://172.17.0.1:4242/> </VirtualHost>
These are relatively simple changes to implement - if you have a need to cipher specific hardening, this is the process Posit will recommend.
Workbench
Workbench doesn't need a separate reverse proxy in front to implement per-cipher hardening - there is a proxy already built in. You can customise the default proxy by editing the file /etc/rstudio/nginx.server.conf
to look like this:
# /etc/rstudio/nginx.server.conf
ssl_prefer_server_ciphers on;
ssl_ciphers -DES:-3DES:-IDEA:-RC2;
Update
Note that newer versions of openssl
and TLS
might require a different syntax - shown here for nginx
:
ssl_protocols TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384;
ssl_prefer_server_ciphers off;
1: See this discussion in the Go language about removing per-cipher exclusions:
https://github.com/golang/go/issues/29349
Comments