nginx-shadow
is a custom NGINX build that includes support for HTTP/3 (QUIC) along with additional modules and patches to enhance server security. This build conceals server details by hiding the Server
header and masking version information, making it harder for attackers to identify the server software.
- Compiling NGINX with the latest stable version and updated core dependencies:
- Changes in NGINX source code
-
Removed mountains of useless modules to improve performance and security
-
Built-in Modules:
- β
select_module
: Provides support for theselect()
system call for event handling. - β
poll_module
: Provides support for thepoll()
system call for event handling. - β
thread_pool_module
: Enables support for multi-threaded processing. - β
file_aio_module
: Enables asynchronous file I/O for improved disk performance. - β
http_ssl_module
: Adds HTTPS support using SSL/TLS. - β
http_v2_module
: Implements support for the HTTP/2 protocol. - β
http_v3_module
: Provides support for HTTP/3 (QUIC), enabling modern transport protocols. - β
http_realip_module
: Allows handling of client IP addresses from reverse proxy headers. - β
http_auth_request_module
: Facilitates external authentication mechanisms. - β
http_stub_status_module
: Displays server statistics for real-time performance monitoring. - β
stream_module
: Supports proxying of TCP/UDP streams for non-HTTP protocols. - β
stream_ssl_module
: Adds SSL/TLS support to the Stream module for secure streaming. - β
stream_realip_module
: Extends the Real IP handling to Stream connections.
- β
-
Third-party Modules:
- β Headers More: Modify HTTP headers for enhanced control.
- β Brotli: High-performance compression for faster content delivery.
- β GeoIP2: Location-based routing and access control.
- β VTS/STS/Stream STS: HTTP/TLS/STREAM traffic monitoring.
- β Devel Kit: Adds advanced development features for custom extensions.
- β Set Misc: Provides additional variable manipulation capabilities.
- β³ TBA: TBA
gcr.io/distroless/base:nonroot
During the build process, a patch is applied to the NGINX source code with the following modifications:
-
Removal of the
Server
Header:- By default, NGINX sends the
Server
header containing its name and version in HTTP responses. This patch removes the header to prevent server identification by attackers.
- By default, NGINX sends the
-
Modification of Default Static Responses:
- The default
"Welcome to nginx!"
message and other static content are altered to conceal any references to NGINX.
- The default
-
Modification of Error Responses:
- Error messages like
404 Not Found
and500 Internal Server Error
are adjusted to remove any references to NGINX or its version. This ensures that no server information is exposed in error responses.
- Error messages like
These changes enhance the server's security by preventing automated tools from detecting the server type and version, reducing the risk of targeted attacks.
Name | Version/Commit/Tag | Repository | Description |
---|---|---|---|
NGINX | 1.26.2 | nginx | High-performance web server and reverse proxy |
BoringSSL | c691779 | boringssl | Optimized SSL library for enhanced security and HTTP/3 (QUIC) |
PCRE2 | 10.44 | pcre2 | Advanced regular expression matching with JIT optimization |
Zlib | 1.3.1 | zlib | General-purpose compression library for gzip and HTTP/2 |
Name | Version/Commit/Tag | Repository | Description |
---|---|---|---|
ngx_headers_more | 0.37 | ngx_headers_more | Allows for modifying HTTP headers dynamically |
ngx_set_misc | 0.33 | ngx_set_misc | Provides advanced variable and data manipulation capabilities |
nginx-module-vts | 0.2.2 | nginx-module-vts | Monitors and visualizes HTTP traffic statistics |
nginx-module-sts | 0.1.1 | nginx-module-sts | TLS traffic monitoring for HTTP |
nginx-module-stream-sts | 0.1.1 | nginx-module-stream-sts | Monitors stream protocol traffic |
ngx_brotli | a71f931 | ngx_brotli | High-performance compression using the Brotli algorithm |
ngx_http_geoip2_module | 3.4 | ngx_http_geoip2_module | Provides IP geolocation-based routing and access control |
ngx_devel_kit | 0.3.3 | ngx_devel_kit | Provides essential utilities for developing advanced NGINX modules |
nginx version: (nginx-shadow)
built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309)
built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nonroot --group=nonroot --build=nginx-shadow --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_auth_request_module --with-http_stub_status_module --with-stream --with-stream_ssl_module --with-stream_realip_module --without-http_ssi_module --without-http_userid_module --without-http_mirror_module --without-http_autoindex_module --without-http_split_clients_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --without-http_grpc_module --without-http_memcached_module --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --add-module=/app/ngx_devel_kit --add-module=/app/set-misc-nginx-module --add-module=/app/headers-more-nginx-module --add-module=/app/nginx-module-vts --add-module=/app/nginx-module-sts --add-module=/app/nginx-module-stream-sts --add-module=/app/ngx_brotli --add-module=/app/ngx_http_geoip2_module --with-cc=c++ --with-cc-opt='-I/app/boringssl/include -I/app/pcre2/include -O2 -x c' --with-ld-opt='-L/app/ngx_brotli/deps/brotli/out -L/app/boringssl/build/ssl -L/app/boringssl/build/crypto -L/app/pcre2/lib -Wl,-rpath,/app/boringssl/build/ssl' --with-pcre-jit --with-zlib=/app/zlib --with-debug
To create a patch for NGINX:
cd sandbox
diff -ruN nginx-1.26.2/ nginx-1.26.2_changes/ > ../build/nginx-1.26.2.patch
To build the Docker image:
cd build
docker build . -t nginx-shadow:0.0.1 --progress=plain
To run the container using the built image:
docker run -d -p 80:80 -p 443:443 --name nginx-shadow nginx-shadow:0.0.1
http {
brotli on;
gzip on;
http2 on;
http3 on;
quic_gso on;
quic_retry on;
ssl_certificate /path/to/cert_plus_intermediate;
ssl_certificate_key /path/to/key;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305; # change `ECDSA` to `RSA` if you use RSA certificate
ssl_early_data on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
server {
listen 80 reuseport;
listen [::]:80 reuseport; # delete if ipv6 is unavailable
return 444;
}
server {
listen 443 reuseport ssl;
listen [::]:443 reuseport ssl;
listen 443 reuseport quic;
listen [::]:443 reuseport quic;
ssl_reject_handshake on;
}
server {
listen 80;
listen [::]:80;
server_name example.com dynamic.example.com php.example.com www.example.com;
return 308 https://$host$request_uri;
}
server { # example for static site
listen 443;
listen [::]:443;
listen 443 quic;
listen [::]:443 quic;
server_name example.com;
root /path/to/static/site;
add_header Alt-Svc 'h3=":443"; ma=86400';
}
server { # example for dynamic site
listen 443;
listen [::]:443;
listen 443 quic;
listen [::]:443 quic;
server_name dynamic.example.com;
add_header Alt-Svc 'h3=":443"; ma=86400';
location / {
proxy_pass http://ip:port;
}
}
server { # example for dynamic site with php
listen 443;
listen [::]:443;
listen 443 quic;
listen [::]:443 quic;
server_name php.example.com;
root /path/to/php/site;
index index.php;
add_header Alt-Svc 'h3=":443"; ma=86400';
location ~ ^.+\.php$ {
include fastcgi_params;
fastcgi_param HTTP_PROXY '';
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/path/to/php/sock;
}
}
server {
listen 443;
listen [::]:443;
listen 443 quic;
listen [::]:443 quic;
server_name www.example.com;
add_header Alt-Svc 'h3=":443"; ma=86400';
return 308 https://example.com$request_uri;
}
}
TODO
TODO
TODO
TODO
- Official NGINX Documentation
- HTTP/3 Check
- HTTP/3 Explained
- Cloudflare blog post about their zlib lib
This project is released under the MIT License.