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 be run as a Windows Service by FireDaemon Pro.


Why would you want to do this? FireDaemon Fusion is an application server built using the Pion and Boost libraries. In order to secure web and application servers, it is generally considered best practice to place an upstream web application firewall or 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. Furthermore, 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 can encrypt traffic to and from the client using a publicly signed TLS certificate. The Fusion Master and Slave nodes might be configured to use an internal CA or self-signed TLS certificates.

The Nginx configuration is relatively straightforward. The example below enforces TLS 1.3, restricts the cipher suite, and requires a post-quantum key exchange. The configuration below is specific to FireDaemon Pro 6 and FireDaemon Fusion 8. If you are looking for more guidance on configuring Nginx or TLS please check out Mozilla's Server Side TLS Configurator and Scott Helme's TLS Cheat Sheet.


FireDaemon Fusion 8 Nginx TLS and Proxy Pass Configuration

# Nginx reverse proxy virtual server setup for FireDaemon Fusion 8.0 or later
# Adjust hostnames, ports, paths and other configuration parameters as you see fit
#
# The configuration works with Nginx 1.29.0 or later compiled against OpenSSL 3.5.0 or later
#
# You would access Fusion via a 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 default_server;
    listen      [::]:443 ssl ipv6only=on;
    http2       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;

    # Generate certs via https://www.sslforfree.com
    # Remember, the chained cert is the
    #     - server cert followed by the
    #     - intermediate cert followed by the
    #     - root cert
    ssl_certificate                 ssl/chained.crt;
    ssl_certificate_key             ssl/server.key;
    ssl_protocols                   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                     ssl/dhparam.pem;

    # Restrict the TLS 1.3 cipher suite
    ssl_ciphers                     "ECDHE-ECDSA-AES256-GCM-SHA384";
    # Specify post-quantum hybrid key exchange
    #     - X25519 = ECDH
    #     - MLKEM768 = FIPS 203
    # Test the configuration with:
    #     - openssl s_client -groups X25519MLKEM768 -connect <hostname>:443
    ssl_ecdh_curve                  X25519MLKEM768;

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

    # Enable HSTS to avoid protocol downgrade attacks and cookie hijacking
    # Maximum age is 47 days, which is to comply with the maximum certificate
    # age from 10 March 2029
    add_header                      Strict-Transport-Security "max-age=4060800; 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
    }
}