Monthly Archives: February 2014

PCI Compliant ScreenConnect Setup Using Nginx

Written by William Roush on February 19, 2014 at 9:26 pm

ScreenConnect’s Mono server fails PCI compliance scans from Qualys for a list of reasons out of the box. We’re going to configure a Nginx proxy to make it compliant!

There are a few things we’ll want before configuring ScreenConnect, we need two public IP addresses (one for your website, one for the ScreenConnect relay server). We’ll want a 3rd party cert from your favorite cert provider. I’m also going to assume you’re running Windows so I’ll include extra instructions, skip those if you know what you’re doing and just need to get to the Nginx configuration.

Get Your Certificate

mkdir /opt/certs
cd /opt/certs

# Generate your server's private key.
openssl genrsa -out screenconnect.example.com.key 2048

# Make a new request.
openssl req -new -key screenconnect.example.com.key -out screenconnect.example.com.csr

Go ahead and log into your server using WinSCP and copy your .csr file to your desktop, and go get a certificate from your Certificate Authority (.crt) and load that back to the server.

Recommended ScreenConnect Configuration

In your ScreenConnect directory you have a “web.config” file. You’ll want to edit (or add if not found) the following properties under the “appsettings” section of the configuration file.

<add key="WebServerListenUri" value="http://127.0.0.1:8040/" />
<add key="WebServerAddressableUri" value="https://screenconnect.example.com" />

We want to configure the web server address to listen on the first IP address we have, additionally pick a port that we’ll use for the internal proxy. I went ahead with the default port 8040. You’ll also need to set the URI to the domain for your first IP (should match the domain on your certificate).

<add key="RelayListenUri" value="relay://[2nd IP]:443/" />
<add key="RelayAddressableUri" value="relay://screenconnectrelay.example.com:443/" />

Additionally we’ll configure our relay server to listen on the second IP, we’ll set it to use port 443 which will help us punch through most firewalls, and we’ll want to set the URI to a second domain name we have pointed at the IP address we specified.

Nginx Configuration

# Defining our ScreenConnect server.
upstream screenconnect {
  server 127.0.0.1:8040;
}

server {
  # Bindings
  listen [1st IP]:80;
  server_name screenconnect.example.com;

  location / {
    # Redirect all non-SSL to SSL-only.
    rewrite ^ https://screenconnect.example.com/ permanent;
  }
}

server {
  # Bindings
  listen [1st IP]:443 default_server ssl;
  server_name screenconnect.example.com;

  # Certificate information
  ssl_certificate /etc/ssl/certs/private/screenconnect.example.com.crt;
  ssl_certificate_key /etc/ssl/certs/private/screenconnect.example.com.key;

  # Limit ciphers to PCI DSS compliant ciphers.
  ssl_ciphers RC4:HIGH:!aNULL:!MD5:!kEDH;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;

  location / {
    # Redirect to local screenconnect
    proxy_pass http://screenconnect;
    proxy_redirect off;
    proxy_buffering off;

    # We're going to set some proxy headers.
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

    # If we get these errors, we want to move to the next upstream.
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

    # If there are errors we're going to intercept them.
    proxy_intercept_errors  on;

    # If there are any 400/500 errors, we'll redirect to the root page to catch the Mono error page.
    error_page 401 402 403 404 405 500 501 502 503 504 /;
  }
}

I’ve run a server with a similar setup through a Qualys PCI compliance scan (which the ScreenConnect server failed horribly prior to the changes), and it passed with flying colors.

Additionally remember to lock down your IP tables so you’re only open where you absolutely need to be, mainly 80 and 443 on your primary IP and 443 on your second IP. Add SSH into the mix if you use that to remotely connect to your servers (only accessible from inside of your company network though!).

1/19/2015 Update: No more SSLv3 due to POODLE.