Nginx is a high performance load balancer, web server and reverse proxy. You can configure Nginx to accept and reverse proxy requests to FireDaemon Fusion. nginx can also be run directly under FireDaemon Pro.


Why would you want to do this? FireDaemon Fusion is an application server built using Pion and Boost. In order to secure web and application servers it's considered best practice to place an upstream reverse proxy between the client and the application server. This provides a level of abstraction and control over traffic entering your network before hitting your backend servers. Further, it allows you to access multiple servers via a single URL.


In the configuration example below, a single nginx server has been deployed behind the firewall to forward requests to a FireDaemon Fusion "master node". The master node facilitates centralised management of other servers running FireDaemon Fusion. Additionally, the Nginx Reverse Proxy might encrypt traffic to/from the client using a publicly signed TLS certificate. The Fusion Master and Slaves nodes might be configured to use an internal CA or self-signed TLS certificates.

The Nginx configuration is quite straight forward. In a virtual server setup the following configuration. This configuration below is specific to FireDaemon Pro 4 and FireDaemon Fusion 6. If you are looking for more guidance on configuring Nginx TLS please check out Mozilla's Server Side TLS Configurator, Scott Helme's TLS Cheat Sheet and Michael Lustfield's guide.


FireDaemon Fusion 6 nginx TLS and Proxy Pass Configuration

# nginx reverse proxy virtual server setup for FireDaemon Fusion 6.5.25 or later
# Adjust hostnames, ports, paths and other configuration parameters as you see fit
#
# You would access Fusion via reverse proxy by pointing your browser at
# https://firedaemon.com/fusion

server {
    server_name firedaemon.com;

    # This SSL config should give you an A or A+ on Qualys SSL Server Test
    # https://www.ssllabs.com/ssltest/
    listen      443 ssl http2 default_server;
    listen      [::]:443 ssl http2 ipv6only=on;

    charset utf-8;

    # Mitigate a bug in Nginx where it doesn't adhere to RFC7230
    # https://trac.nginx.org/nginx/ticket/2184
    ignore_invalid_headers off;  

    # Mitigate BREACH vulnerability and CRIME attack
    gzip off;

    # Cert generated via https://www.sslforfree.com
    # Remember chained key is server key followed by intermediate and root
    ssl_certificate                 /etc/nginx/ssl/firedaemon_com_chained.crt;
    ssl_certificate_key             /etc/nginx/ssl/firedaemon_com.key;
    ssl_protocols                   TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers       on;
    ssl_session_cache               shared:SSL:10m;
    ssl_session_timeout             10m;
    ssl_session_tickets             off;
    # nginx will use the default DHE parameters provided by OpenSSL
    # This forces nginx to use a 4096-bit key
    # Generated with openssl dhparam -out dhparam.pem 4096
    # Generates a safe probable prime that passes the Muller-Rabin test
    # Assists in mitigating Logjam. Not relevant if ECDH ciphers are used exclusively
    ssl_dhparam                     /etc/nginx/ssl/dhparam.pem;
    # Cipher suite is subject to change and will end up being
    # a tradeoff between security and compatibility.
    ssl_ciphers                     "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    # Specify the curve to use in ECDH key exchange to NIST P-521
    ssl_ecdh_curve                  secp384r1;

    # Enable OSCP Stapling
    ssl_stapling                    on;
    ssl_stapling_verify             on;
    ssl_trusted_certificate         /etc/nginx/ssl/firedaemon_com_chained.crt;
    resolver                        8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout                10s;

    # Enable Strict Transport Security to avoid protocol downgrade attacks and cookie hijacking
    add_header                      Strict-Transport-Security "max-age=15552000; includeSubdomains";
    # Avoid clickjacking
    add_header                      X-Frame-Options DENY;
    # Stop MIME content sniffing
    add_header                      X-Content-Type-Options nosniff;

    # Configuration locations below are FireDaemon Fusion specific
    location /fusion/504.html {
        internal;
        alias                      html/50x.html;
        add_header                 Cache-Control no-cache always;
    }

    location /fusion/ {
        proxy_pass                 https://fusion.firedaemon.dmz:20604/;
        error_page                 504 /fusion/504.html;

        # proxy_buffering             on;
        # proxy_buffer_size           1k;
        # proxy_buffers               24 4k;
        # proxy_busy_buffers_size     8k;
        # proxy_temp_file_write_size  32k;

        proxy_connect_timeout       7s;
        proxy_http_version          1.1;
        proxy_set_header            Connection        "";
        proxy_set_header            X-Forwarded-Proto $scheme;
        proxy_set_header            X-Real-IP         $remote_addr;
        proxy_set_header            X-Forwarded-Host  $host:$server_port;
        proxy_set_header            X-Forwarded-For   $proxy_add_x_forwarded_for;

        proxy_set_header           com.firedaemon.fusion-vstem /fusion;
    }

    # Uncomment these lines if you want to serve the default nginx landing page
    # location / {
    #        root   html;
    #        index  index.html index.htm;
    #}
}

# Redirect to HTTPS
server {
        server_name     firedaemon.com;

        listen          80 default_server;
        listen          [::]:80;
        access_log      off;
        error_log       off;

        return          301 https://$server_name$request_uri;
}

Below is a simple Caddy configuration that achieves the same goal.

https://localhost:8088 {
    tls self_signed

    # tls {
    # alpn http/1.1
    # }

    log access.log
    proxy /fusion/ https://localhost:20600/ {
        without /fusion
        header_upstream Connection ""
        transparent
        header_upstream com.firedaemon.fusion-vstem /fusion
        insecure_skip_verify
    }
}