Using SSL with Passenger in Production

This article covers how to configure your webserver to serve your app over https in a production deployment, and how to check it for correctness.

Obtain a Trusted SSL Certificate

In order to have your production SSL configuration trusted by your users' browsers, you need a certificate signed by a trusted Certificate Authority (CA). While you have many choices in this regard, most of them cost money. One free option that you have though is to obtain your certificate from the Let's Encrypt organization.

Choose your tradeoffs

A secure production ready configuration is an exercise in tradeoffs; broad compatibility and speed for strongest security. A great resource in this regard is the Mozilla SSL Configuration Generator which will provide you with up-to-date web server configurations that either maximize compatibility or security. The following configuration was designed to be more broadly compatible, but your situation may warrant maximum security.

Configure Apache

The following is a partial example configuration for the Apache Web Server, meant to highlight the SSL configuration options you are likely to need in production. Replace example.com with your domain, and set the paths to your certificates, key, and app.

ServerTokens Prod
SSLStrictSNIVHostCheck off # Necessary if you have more than one domain served from this webserver
<VirtualHost *:80>
    #redirect http traffic to https
    Redirect permanent / https://www.example.com/
    ServerName example.com
    ServerAlias www.example.com
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot "/path/to/app/public"
    <Directory "/path/to/app/public">
        Options None
        Require all granted # apache 2.4
        Order allow,deny # apache 2.2
        Allow from all # apache 2.2
    </Directory>
    PassengerAppEnv production
    PassengerAppRoot "/path/to/app"
    PassengerHighPerformance on

    SSLEngine on
    SSLCertificateFile      /path/to/signed_certificate # certificate for this server or wildcard certificate
    SSLCertificateKeyFile   /path/to/private/key # private key for certificate
    SSLCertificateChainFile /path/to/intermediate_certificate # additional certificates provided by CA for compatibility
    SSLProtocol             all -SSLv2 -SSLv3
    SSLHonorCipherOrder     on
    SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS

    ServerSignature off
    SSLCompression off # not all combination of Apache+OpenSSL allow this option
    SSLSessionTickets off # apache 2.4
    SSLUseStapling on # apache 2.4
    SSLStaplingResponderTimeout 5 # apache 2.4
    SSLStaplingReturnResponderErrors off # apache 2.4
    SSLStaplingCache shmcb:/var/run/ocsp(128000) # apache 2.4

    <IfModule headers_module>
        Header always edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
    </IfModule>
    #...
</VirtualHost>

Test With SSL Labs

Qualys provides an excellent free test of your server's SSL configuration, you can use it here to check your setup for known issues. While a score of A or A+ is a good indication that you setup your config correctly, it is not a guarantee, so it's important to be informed or consult with someone who is.

You should also keep in mind that a secure configuration is a moving target, you have to stay up to date on the latest vulnerabilities that are discovered, and update your configuration accordingly.