Custom-built NGINX with enhanced performance, modern protocol support, Docker image builds, and security-focused features.
Luna-HTTP/S is based on NGINX mainline and adds a curated build configuration with OpenSSL 3.5.x, TLS 1.3, post-quantum cryptography support, HTTP/2, HTTP/3 / QUIC, Brotli, real client IP handling, GeoIP2, advanced header manipulation, and response body substitution support.
Project information is available at lunahttps.tiekoetter.net.
- Based on NGINX mainline
- OpenSSL with TLS 1.3 + kTLS for modern transport security and improved performance
- Post-quantum cryptography capable out of the box through OpenSSL 3.5.x, including support for ML-KEM, ML-DSA, and SLH-DSA
- HTTP/2 support
- HTTP/3 / QUIC support for reduced latency and faster connections
- Brotli compression for reduced bandwidth usage and faster page loads
- ngx_http_realip_module for preserving trusted proxy client addresses
- ngx_http_geoip2_module for GeoIP-based request handling
- headers-more-nginx-module for advanced header control
- ngx_http_substitutions_filter_module for RegEx-based response body filtering and substitution
- Docker image builds published through GitHub Container Registry
- Custom Luna branding for generated server headers and error pages
This build is tailored for high-performance environments and is compiled with additional modules and experimental protocol support.
Included modules:
- ngx_http_realip_module
- ngx_brotli
- ngx_http_geoip2_module
- headers-more-nginx-module
- ngx_http_substitutions_filter_module
The build uses the repository submodules under:
luna/modules/
OpenSSL is downloaded and prepared by:
luna/openssl-downloader.sh
The OpenSSL LTS version and tarball SHA256 are pinned in:
luna/openssl-version.env
Luna-HTTP/S is built with OpenSSL 3.5.x, which includes support for post-quantum cryptography algorithms such as ML-KEM, ML-DSA, and SLH-DSA.
This makes the build post-quantum capable out of the box and suitable for testing hybrid TLS key exchange and future-facing cryptographic deployments.
Actual post-quantum behavior depends on client support, TLS group configuration, OpenSSL defaults, and interoperability with the connecting peer.
With server_tokens off;:
Server: luna-http/s
With server_tokens on;:
Server: luna-http/s+<nginx-version>
The branding patch is applied to HTTP/1.x, HTTP/2, HTTP/3, and generated NGINX error pages using:
luna/branding-patch.sh
The Docker image is published to GitHub Container Registry:
docker pull ghcr.io/tiekoetter/lunahttps:latestExample docker-compose.yml:
services:
lunahttps:
image: ghcr.io/tiekoetter/lunahttps:latest
container_name: lunahttps
restart: unless-stopped
ports:
- "80:80/tcp"
- "443:443/tcp"
- "443:443/udp"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
- ./html:/usr/share/nginx/html:ro
- ./logs:/var/log/nginxFor HTTP/3 / QUIC, make sure UDP 443 is exposed and allowed through the firewall.
Example HTTPS server block with HTTP/2 and HTTP/3:
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http2 on;
server_name example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
ssl_protocols TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
root /usr/share/nginx/html;
index index.html;
}For a non-standard public HTTPS port, adjust the Alt-Svc port accordingly, for example:
add_header Alt-Svc 'h3=":8443"; ma=86400' always;You can build Luna-HTTP/S directly on a host using the provided build script.
git clone --recurse-submodules https://github.com/tiekoetter/lunahttps.git
cd lunahttps
sudo ./build.shIf the repository was cloned without submodules, initialize them first:
git submodule update --init --recursiveDocker builds also expect the submodules to be initialized in the build context. The Dockerfile uses the same build script in Docker mode:
./build.sh --dockerThat mode performs the shared download, verification, patch, configure, build, and install flow without validating or restarting a host system service.
In default host mode, the build script will:
- download and verify the pinned OpenSSL release,
- download the configured NGINX mainline version,
- apply Luna source and branding patches,
- configure NGINX with the selected modules,
- build and install NGINX,
- validate the installed configuration,
- restart the system NGINX service.
The current NGINX version is configured in:
readonly NGINX_VERSION="..."inside:
build.sh
After installation or container startup, check the compiled features:
nginx -Vor inside Docker:
docker exec lunahttps nginx -VValidate the active configuration:
nginx -tor:
docker exec lunahttps nginx -tTest HTTP/1.1, HTTP/2, and HTTP/3 branding:
curl -I --http1.1 http://example.com/
curl -k -I --http1.1 https://example.com/
curl -k -I --http2 https://example.com/
curl -k -I --http3-only https://example.com/Expected with server_tokens off;:
Server: luna-http/s
For HTTP/2 and HTTP/3, header names are usually lowercase:
server: luna-http/s
The repository uses GitHub Actions for CI and Docker image publishing.
CI validates:
- shell scripts with ShellCheck,
- required submodules,
- Docker image build,
- compiled NGINX modules,
- runtime HTTP/1.1 and HTTP/2 branding,
- generated error page branding,
- HTTP/3 branding when the GitHub Actions runner curl supports HTTP/3.
Docker image publishing runs after CI succeeds on the main branch, and can also be started manually.
Additional maintenance workflows may open PRs for:
- NGINX mainline version bumps,
- OpenSSL LTS version/hash bumps,
- Debian base image codename updates,
- submodule updates.
.
├── build.sh
├── Dockerfile
├── luna
│ ├── branding-patch.sh
│ ├── openssl-downloader.sh
│ └── modules
└── .github
└── workflows
Important paths:
build.sh Host build/install script
Dockerfile Container image build
luna/branding-patch.sh Luna server/error-page branding patch
luna/openssl-downloader.sh OpenSSL download/preparation script
luna/openssl-version.env Pinned OpenSSL LTS version and SHA256
luna/modules/ NGINX third-party modules as submodules
HTTP/3 / QUIC requires:
- NGINX built with
--with-http_v3_module, - a QUIC-capable TLS stack,
- TLS 1.3,
- UDP port 443 exposed and reachable,
- a
listen ... quicdirective in the HTTPS server block.
For Docker deployments, publishing TCP 443 alone is not enough. UDP 443 must also be published:
ports:
- "443:443/tcp"
- "443:443/udp"The Luna-HTTP/S build scripts, Dockerfile, CI workflows, and Luna-specific patches in this repository are licensed under the BSD 2-Clause License.
NGINX, OpenSSL, and bundled third-party modules remain subject to their respective upstream licenses.