A hardened Nginx web server configured to run unprivileged with the hardenedeu user (UID 10000), featuring security-hardened configurations and optimized for containerized deployments.
Getting Started
To pull the image:
docker pull registry.hardened.eu/library/nginx:latest
Example: Running Nginx with Custom Configuration
The Hardened B.V. nginx image runs unprivileged with the hardenedeu
user (UID 10000) for enhanced security. The default configuration provides a minimal setup that returns 404 for all requests, serving as a secure starting point.
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:latest
Adding Custom Virtual Hosts
To add your own virtual host configuration, create a custom Dockerfile:
FROM registry.hardened.eu/library/nginx: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/
Security Hardening Features
The nginx image includes several security enhancements:
nginx.conf.hardened
with security optimizationsVolume 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: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
For HTTPS support, 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;
# SSL configuration optimized for security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
root /usr/share/nginx/html;
index index.html;
# Security headers, use the Mozilla SSL config generator
# add_header X-Frame-Options "SAMEORIGIN" always;
# add_header X-Content-Type-Options "nosniff" always;
# add_header X-XSS-Protection "1; mode=block" always;
# add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
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: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: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: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:latest | jq -r .payload | base64 -d | jq -r .predicate > nginx-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.