HARDENED
Return
nginx-fips

nginx-fips

latest

A hardened Nginx web server configured to run unprivileged with the hardenedeu user (UID 10000), featuring security-hardened configurations, FIPS and optimized for containerized deployments.

Getting Started

To pull the image:

docker pull registry.hardened.eu/library/nginx-fips:latest

Example: Running FIPS-Compliant Nginx with Custom Configuration

The Hardened B.V. nginx-fips image runs unprivileged with the hardenedeu user (UID 10000) for enhanced security. This FIPS-compliant variant uses FIPS-approved cryptographic algorithms and configurations, making it suitable for environments requiring Federal Information Processing Standards compliance.

Default Configuration

The image includes a hardened nginx configuration with the following default server block:

server {
    listen 8080 default_server;
    listen [::]:8080 default_server;

    # Everything is a 404
    location / {
        return 404;
    }

    # You may need this to prevent return 404 recursion.
    location = /404.html {
        internal;
    }
}

Running the Container

docker run -p 8080:8080 registry.hardened.eu/library/nginx-fips:latest

Adding Custom Virtual Hosts

To add your own virtual host configuration, create a custom Dockerfile:

FROM registry.hardened.eu/library/nginx-fips:latest

# Copy your custom nginx configuration
COPY my-site.conf /etc/nginx/http.d/

# Copy your website files
COPY website/ /usr/share/nginx/html/

# Ensure proper permissions for the hardenedeu user
RUN chown -R 10000:10000 /usr/share/nginx/html /etc/nginx/http.d/

FIPS Compliance Verification

To verify that the nginx environment is using FIPS-compliant OpenSSL and cryptographic algorithms:

# Check OpenSSL FIPS status
docker run --rm registry.hardened.eu/library/nginx-fips:latest openssl version -a

# Verify FIPS provider is loaded
docker run --rm registry.hardened.eu/library/nginx-fips:latest openssl list -providers

Expected output should indicate FIPS provider usage and reference the FIPS configuration file.

Security Hardening Features

The nginx-fips image includes several security enhancements:

  • FIPS Compliance: Uses FIPS-approved cryptographic algorithms and configurations
  • Unprivileged Operation: Runs as non-root user (hardenedeu, UID 10000)
  • Hardened Configuration: Uses nginx.conf.hardened with security optimizations
  • Minimal Default: Default configuration returns 404 to prevent information disclosure
  • Container-Optimized: Configured for containerized environments
  • Logging: All logs are sent to stdout for container-friendly logging

Volume Mounts

For persistent configurations and logs:

docker run -p 8080:8080 \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /path/to/sites:/etc/nginx/http.d:ro \
  -v /path/to/html:/usr/share/nginx/html:ro \
  registry.hardened.eu/library/nginx-fips:latest

Health Checks

The container is configured to respond to health checks on port 8080. You can verify the container is running:

curl -I http://localhost:8080

Expected response: HTTP/1.1 404 Not Found

Custom SSL/TLS Configuration with FIPS Compliance

For HTTPS support with FIPS-approved algorithms, mount your certificates and update the configuration. Note that the default configuration uses port 8080, but SSL/TLS typically uses port 8443:

server {
    listen 8443 ssl;
    server_name example.com;
    http2 on;
    
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    
    # FIPS-compliant SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    root /usr/share/nginx/html;
    index index.html;
}

More complex sample using the Mozilla SSL config generator (contact us for a reference implementation):

# https://ssl-config.mozilla.org, nginx intermediate

http {

    server {
        listen 8443 ssl;
        listen [::]:8443 ssl;
        http2 on;
        ssl_certificate /path/to/signed_cert_plus_intermediates;
        ssl_certificate_key /path/to/private_key;

        # HSTS (ngx_http_headers_module is required) (63072000 seconds)
        add_header Strict-Transport-Security "max-age=63072000" always;
    }

    # intermediate configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ecdh_curve X25519:prime256v1:secp384r1;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # see also ssl_session_ticket_key alternative to stateful session cache
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions

    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
    ssl_dhparam "/path/to/dhparam";

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    # replace with the IP address of your resolver;
    # async 'resolver' is important for proper operation of OCSP stapling
    resolver 127.0.0.1;
}

Run with SSL/TLS:

docker run -p 8443:8443 \
  -v /path/to/ssl:/etc/nginx/ssl:ro \
  -v /path/to/sites:/etc/nginx/http.d:ro \
  registry.hardened.eu/library/nginx-fips:latest

Verifying Image Signatures

All Hardened B.V. images are signed using cosign. You can verify the signature using the following steps:

Save the public key:

cat >hardened.pub <<EOL
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbxhUFlXkIIbDzdRAR9rc6kDPNb+k
J48lhqqlOMyiq3jkbKXNj2sEFMduFlNh63MrZA59PKf4TjS1AiCrvaFXNA==
-----END PUBLIC KEY-----
EOL

Verify the image signature:

cosign verify --key hardened.pub registry.hardened.eu/library/nginx-fips:latest

The verification will show the signature details and confirm the image’s authenticity.

To verify the SBOM, run the following command:

cosign verify-attestation --type spdxjson --key hardened.pub registry.hardened.eu/library/nginx-fips:latest

To download the SBOM, run the same command and decode it:

cosign verify-attestation --type spdxjson --key hardened.pub registry.hardened.eu/library/nginx-fips:latest | jq -r .payload | base64 -d | jq -r .predicate > nginx-fips-spdx.json

Trademarks

This software is packaged by Hardened B.V. All trademarks are property of their respective owners. Use of these images does not imply any affiliation or endorsement.