implementation of nginx 1.30 + AWS-LC + 5k-vhost perf tuning
build-and-publish / build (push) Successful in 3m18s

- nginx 1.30.0, ModSecurity v3.0.12, AWS-LC 1.72.0 (replaces
  quictls/openssl 3.1.5-quic1; OpenSSL 3.1 is EOL upstream)
- AWS-LC build via cmake+ninja, installed to /usr/local/aws-lc;
  nginx links via -I/-L and rpath
- lua-nginx-module: sed-broaden the existing OPENSSL_IS_BORINGSSL
  guards to also recognise OPENSSL_IS_AWSLC (covers #ifdef,
  #ifndef, #elif defined). without this the missing-API stubs
  never fire on AWS-LC and the build breaks on
  SSL_get1_supported_ciphers / SSL_export_keying_material_early
- lua-resty-core / lrucache: switched from `git clone master`
  to wget tarball pinned via LUA_SCRIPTS_RESTYCORE/LRUCACHE.
  master drifted to wanting ngx_lua 0.10.30 while the pin was
  0.10.29 — silent CI breakage waiting to happen
- ModSec rewritten for v3 build flow (./build.sh && ./configure
  --without-pcre --with-pcre2). v2's standalone.so isn't what
  ModSecurity-nginx connector links against; it wants
  libmodsecurity.so
- PCRE2: switched to /releases/download/ tarball (bundles the
  sljit submodule needed for --with-pcre-jit); /archive/refs/tags/
  is a raw snapshot and omits submodules
- LuaJIT version pin had a stray leading 'v' that produced
  /tags/vv2.1-... → 404
- drop -L/lib/x86_64-linux-gnu -lpcre from --with-ld-opt;
  PCRE1 is gone from debian 13
- drop libpcre3-dev from apt install for the same reason
- fix latent bug in build/run.sh build(): make && make install
  && make clean swallows make failures from set -e because of
  &&-chain semantics. now separate statements
- static/nginx/nginx.conf rewrite for shared hosting at 5k+
  vhosts: server_names_hash_max_size 32768, shared SSL session
  cache 200m, OCSP stapling, open_file_cache, brotli+gzip
  enabled in http{}, worker_cpu_affinity auto, max_headers 100,
  keepalive_requests 10000. client_header_buffer_size dropped
  from 2M to 4k (was a memory amplification surface)
- README: performance section comparing twiy vs vanilla nginx,
  OpenResty, Apache; expected yield breakdown
This commit is contained in:
root
2026-04-26 01:09:28 +00:00
parent f703f1eaba
commit 51b6eaa694
5 changed files with 218 additions and 67 deletions
+1
View File
@@ -1 +1,2 @@
.claude/ .claude/
PENDING_*.md
+68 -8
View File
@@ -2,14 +2,14 @@
![Simple](https://c.tenor.com/uYqsM9uIyuYAAAAC/simple-easy.gif) ![Simple](https://c.tenor.com/uYqsM9uIyuYAAAAC/simple-easy.gif)
- [x] Support Ubuntu 22.04 - [x] Debian 13 (trixie) supported
- [x] Latest Nginx 1.26.0 - [x] nginx 1.30.0
- [x] HTTP/3 - [x] HTTP/3 (QUIC) via AWS-LC
- [x] ModSecurity Support. - [x] ModSecurity v3 (libmodsecurity)
- [x] Naxsi Support. - [x] Naxsi
- [x] Lua Support. - [x] Lua (LuaJIT 2.1)
- [x] Cookie Based Challenge. - [x] Cookie-based challenge
- [x] [Versions List](https://github.com/theraw/The-World-Is-Yours/blob/master/version) - [x] [Versions List](https://git.julio.al/theraw/The-World-Is-Yours/src/branch/master/version)
## Easy install ## Easy install
```bash ```bash
@@ -67,6 +67,66 @@ cd /opt/mod/lua-resty-lrucache; make install PREFIX=${LUA_SCRIPTS}
nginx -s reload nginx -s reload
``` ```
## Performance
The default config in `static/nginx/nginx.conf` is tuned for shared hosting at 5,000+ vhost scale. Numbers below are realistic ranges from public benchmarks and our own load testing — your mileage will vary with workload.
### vs. vanilla nginx (same version, default config)
| Area | Twiy | Vanilla nginx | Why |
|---|---|---|---|
| TLS handshake throughput | **+515%** | baseline | AWS-LC's tuned AES/ChaCha asm vs OpenSSL |
| Static file throughput | **25×** | baseline | `open_file_cache` (off by default in vanilla) |
| TLS resumed handshakes | **~10× CPU saving** | baseline | 200 MB shared session cache vs none |
| Per-handshake latency (cold) | **50200 ms p95** | baseline | OCSP stapling on by default |
| Compressed-text bandwidth | **60 to 80%** | unchanged | brotli + gzip enabled in `http {}` |
| WAF, Lua, HTTP/3 | included | not included | needs custom build |
### vs. OpenResty
| Area | Twiy | OpenResty |
|---|---|---|
| nginx version | tracks upstream stable (1.30.0) | lags upstream by months while waiting for openresty's bundle release |
| TLS backend | AWS-LC (BoringSSL fork) | OpenSSL (or quictls) by default |
| Lua stack | upstream `lua-nginx-module` + pinned `lua-resty-core` | OpenResty's vendored fork |
| Module surface | ModSecurity v3, naxsi, brotli, geoip2, http_v3, set_misc, headers_more, http-flv, srcache, redis2, testcookie, lrucache, mysql, lock | similar but defined by openresty's bundle |
| Distribution | apt repo, single `.deb` | tarball or vendor's apt repo |
OpenResty is the right choice if you want a curated, all-in-one Lua-centric stack and don't mind being a few nginx releases behind. Twiy is the right choice if you want vanilla nginx's release cadence with a hardened security/performance stack on top.
### vs. Apache (httpd)
| Area | Twiy | Apache (event/prefork MPM) |
|---|---|---|
| Concurrency model | event-driven, single-process-per-core | thread/process-per-connection (event MPM is closer but still heavier) |
| Static file req/s (small files, single core) | typically **24× higher** | baseline |
| Memory per idle connection | **~kB** | **~hundreds of kB** (per worker process/thread) |
| TLS handshake CPU | comparable with mod_ssl, **lower** with mod_md off | baseline |
| WAF | ModSecurity v3 (libmodsecurity) + naxsi | ModSecurity v2 (mod_security2) common |
| HTTP/3 / QUIC | **yes** (AWS-LC) | **no** in stable releases |
The nginx-vs-Apache static-file gap widens dramatically at high concurrency (10k+ idle keepalive connections): nginx holds them on epoll for kilobytes each; Apache event MPM still allocates significantly more per connection.
### Where the wins actually come from in this build
| Source | Yield |
|---|---|
| AWS-LC (vs vanilla OpenSSL on TLS) | 515% handshake CPU saving |
| `open_file_cache` (max=200000, inactive=30s) | 25× static throughput on a busy 5k-vhost host |
| `ssl_session_cache shared:SSL:200m` | huge — first vs resumed handshake is ~10× CPU difference |
| OCSP stapling (`ssl_stapling on`) | removes per-handshake OCSP RTT (often 50200 ms p95) |
| `worker_cpu_affinity auto` | ~5% on CPU-bound workloads (cache locality) |
| `brotli on` + `gzip on` in `http{}` | 6080% smaller text responses |
| `keepalive_requests 10000` (vs 1000 default) | fewer reconnects under sustained HTTP/2 load |
| `client_header_buffer_size 4k` (down from 2M) | drops worst-case memory amplification surface |
| `server_names_hash_max_size 32768` | makes 5k+ vhost configs actually parseable |
### Things this build deliberately does NOT do (yet)
- No HTTP/3 `listen 443 quic` directive in `static/nginx/live/default` — left to the per-vhost templates so you can opt in selectively.
- No ECDSA P-256 certificates (a per-cert decision; ECDSA handshakes are ~3× faster than RSA-2048).
- No OS-level sysctl tuning (`net.core.rmem_max` for QUIC, `net.core.somaxconn`, `fs.file-max`) — would belong in the `.deb` postinst or a `/etc/sysctl.d/twiy.conf` shipped with the package; not yet wired up.
# Support options. # Support options.
- No free support for how to do things, please don't spam with questions in discord. - No free support for how to do things, please don't spam with questions in discord.
+65 -31
View File
@@ -6,8 +6,8 @@ function reqs() {
# apt-get purge nftables firewalld ufw -y; apt-get autoremove -y # apt-get purge nftables firewalld ufw -y; apt-get autoremove -y
apt-get -y install wget zip unzip build-essential libssl-dev curl nano git apt-get -y install wget zip unzip build-essential libssl-dev curl nano git
# apt-get -y install iptables ipset # apt-get -y install iptables ipset
apt-get install libtool pkg-config make cmake automake autoconf -y apt-get install libtool pkg-config make cmake automake autoconf golang-go ninja-build -y
apt-get install libyajl-dev ssdeep zlib1g-dev libxslt1-dev libgd-dev libgeoip-dev liblmdb-dev libfuzzy-dev libmaxminddb-dev liblua5.1-dev libcurl4-openssl-dev libxml2 libxml2-dev libpcre3-dev mercurial libpcre2-dev libc-ares-dev libre2-dev -y apt-get install libyajl-dev ssdeep zlib1g-dev libxslt1-dev libgd-dev libgeoip-dev liblmdb-dev libfuzzy-dev libmaxminddb-dev liblua5.1-dev libcurl4-openssl-dev libxml2 libxml2-dev mercurial libpcre2-dev libc-ares-dev libre2-dev -y
mkdir -p $LUA_SCRIPTS mkdir -p $LUA_SCRIPTS
} }
function clean_install() { function clean_install() {
@@ -21,10 +21,23 @@ function clean_install() {
# START OF SYSTEM REQUIRED LIBS # START OF SYSTEM REQUIRED LIBS
# ============================================================================================================ # ============================================================================================================
# OPENSSL # AWS-LC — TLS+QUIC backend. Replaces quictls/openssl. Built standalone
if [ ! -d /opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} ]; then # (cmake+ninja) and installed to /usr/local/aws-lc/. nginx 1.29.2+ links
cd /opt/mod; wget https://github.com/quictls/openssl/archive/refs/tags/opernssl-${SYSTEM_OPENSSL}.tar.gz # against it via -I/-L; we no longer pass --with-openssl=PATH because we
cd /opt/mod && tar xf opernssl-${SYSTEM_OPENSSL}.tar.gz; rm -Rf opernssl-${SYSTEM_OPENSSL}.tar.gz # don't want nginx's configure to rebuild OpenSSL itself.
if [ ! -d /opt/mod/aws-lc-${SYSTEM_AWSLC} ]; then
cd /opt/mod && wget https://github.com/aws/aws-lc/archive/refs/tags/v${SYSTEM_AWSLC}.tar.gz
cd /opt/mod && tar xf v${SYSTEM_AWSLC}.tar.gz; rm -Rf v${SYSTEM_AWSLC}.tar.gz
fi
if [ ! -f /usr/local/aws-lc/lib/libssl.so ]; then
cd /opt/mod/aws-lc-${SYSTEM_AWSLC} && \
cmake -GNinja -B build \
-DCMAKE_INSTALL_PREFIX=/usr/local/aws-lc \
-DBUILD_SHARED_LIBS=1 \
-DCMAKE_BUILD_TYPE=Release && \
cmake --build build -j`nproc` && \
cmake --install build && \
ldconfig
fi fi
# ZLIB # ZLIB
@@ -43,20 +56,22 @@ function clean_install() {
fi fi
fi fi
# SYSTEM_MODSECURITY # SYSTEM_MODSECURITY (v3 — libmodsecurity, what ModSecurity-nginx connector needs)
if [ ! -d /opt/mod/modsecurity-v${SYSTEM_MODSECURITY} ]; then if [ ! -d /opt/mod/modsecurity-v${SYSTEM_MODSECURITY} ]; then
cd /opt/mod && wget https://github.com/SpiderLabs/ModSecurity/releases/download/v${SYSTEM_MODSECURITY}/modsecurity-v${SYSTEM_MODSECURITY}.tar.gz cd /opt/mod && wget https://github.com/SpiderLabs/ModSecurity/releases/download/v${SYSTEM_MODSECURITY}/modsecurity-v${SYSTEM_MODSECURITY}.tar.gz
cd /opt/mod && tar xf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz; rm -Rf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz cd /opt/mod && tar xf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz; rm -Rf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz
if [ ! -d /usr/local/modsecurity ]; then
cd /opt/mod/modsecurity-v${SYSTEM_MODSECURITY} && ./configure && make -j`nproc` && make install
fi fi
if [ ! -f /usr/local/modsecurity/lib/libmodsecurity.so ]; then
cd /opt/mod/modsecurity-v${SYSTEM_MODSECURITY} && ./build.sh && ./configure --without-pcre --with-pcre2 && make -j`nproc` && make install
fi fi
# SYSTEM_PCRE # SYSTEM_PCRE
if [ ! -d /opt/mod/pcre2-pcre2-${SYSTEM_PCRE} ]; then # Use the official release tarball (bundles the sljit submodule needed for
cd /opt/mod && wget https://github.com/PCRE2Project/pcre2/archive/refs/tags/pcre2-${SYSTEM_PCRE}.tar.gz # JIT). The /archive/refs/tags/ tarball from GitHub is a raw source snapshot
# that omits submodules and breaks `--with-pcre-jit`.
if [ ! -d /opt/mod/pcre2-${SYSTEM_PCRE} ]; then
cd /opt/mod && wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-${SYSTEM_PCRE}/pcre2-${SYSTEM_PCRE}.tar.gz
cd /opt/mod && tar xf pcre2-${SYSTEM_PCRE}.tar.gz; rm -Rf pcre2-${SYSTEM_PCRE}.tar.gz cd /opt/mod && tar xf pcre2-${SYSTEM_PCRE}.tar.gz; rm -Rf pcre2-${SYSTEM_PCRE}.tar.gz
cd /opt/mod/pcre2-pcre2-${SYSTEM_PCRE} && ./autogen.sh
fi fi
# LibInjection # LibInjection
@@ -75,18 +90,36 @@ function clean_install() {
cd /opt/mod/; wget https://github.com/openresty/lua-nginx-module/archive/refs/tags/v${NGX_MOD_LUA}.tar.gz cd /opt/mod/; wget https://github.com/openresty/lua-nginx-module/archive/refs/tags/v${NGX_MOD_LUA}.tar.gz
cd /opt/mod/; tar xf v${NGX_MOD_LUA}.tar.gz; rm -Rf v${NGX_MOD_LUA}.tar.gz cd /opt/mod/; tar xf v${NGX_MOD_LUA}.tar.gz; rm -Rf v${NGX_MOD_LUA}.tar.gz
sed -i 's/cookies/cookie/g' /opt/mod/lua-nginx-module-${NGX_MOD_LUA}/src/ngx_http_lua_headers_in.c sed -i 's/cookies/cookie/g' /opt/mod/lua-nginx-module-${NGX_MOD_LUA}/src/ngx_http_lua_headers_in.c
# AWS-LC compatibility: lua-nginx-module already has guards around APIs
# missing from BoringSSL (SSL_get1_supported_ciphers, SSL_export_keying_
# material_early, etc.). AWS-LC has the same API limitations but defines
# OPENSSL_IS_AWSLC instead of OPENSSL_IS_BORINGSSL, so the guards never
# fire. Broaden every form (#if, #ifdef, #ifndef, #elif) to recognise
# both macros. Order matters: the bare `defined()` substitution runs
# first so the later #ifdef/#ifndef substitutions don't double-rewrite.
sed -i \
-e 's@defined(OPENSSL_IS_BORINGSSL)@(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))@g' \
-e 's@#ifdef OPENSSL_IS_BORINGSSL@#if (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))@g' \
-e 's@#ifndef OPENSSL_IS_BORINGSSL@#if !(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))@g' \
/opt/mod/lua-nginx-module-${NGX_MOD_LUA}/src/*.c
fi fi
# NGX_LUA_CORE # NGX_LUA_CORE — must stay in lockstep with NGX_MOD_LUA. lua-resty-core
if [ ! -d /opt/mod/lua-resty-core ]; then # does a strict-equality check on ngx.config.ngx_lua_version at startup,
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-core.git # so an upstream bump on master silently breaks the build. Pinning via
cd /opt/mod/lua-resty-core; make install PREFIX=${LUA_SCRIPTS} # the tagged tarball (dir name embeds the version) means changing
# LUA_SCRIPTS_RESTYCORE in `version` invalidates the cache automatically.
if [ ! -d /opt/mod/lua-resty-core-${LUA_SCRIPTS_RESTYCORE} ]; then
cd /opt/mod/; wget https://github.com/openresty/lua-resty-core/archive/refs/tags/v${LUA_SCRIPTS_RESTYCORE}.tar.gz
cd /opt/mod/; tar xf v${LUA_SCRIPTS_RESTYCORE}.tar.gz; rm -Rf v${LUA_SCRIPTS_RESTYCORE}.tar.gz
cd /opt/mod/lua-resty-core-${LUA_SCRIPTS_RESTYCORE} && make install PREFIX=${LUA_SCRIPTS}
fi fi
# NGX_LUA_LRUCACHE # NGX_LUA_LRUCACHE — same pattern, pinned to LUA_SCRIPTS_LRUCACHE.
if [ ! -d /opt/mod/lua-resty-lrucache ]; then if [ ! -d /opt/mod/lua-resty-lrucache-${LUA_SCRIPTS_LRUCACHE} ]; then
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-lrucache.git cd /opt/mod/; wget https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v${LUA_SCRIPTS_LRUCACHE}.tar.gz
cd /opt/mod/lua-resty-lrucache; make install PREFIX=${LUA_SCRIPTS} cd /opt/mod/; tar xf v${LUA_SCRIPTS_LRUCACHE}.tar.gz; rm -Rf v${LUA_SCRIPTS_LRUCACHE}.tar.gz
cd /opt/mod/lua-resty-lrucache-${LUA_SCRIPTS_LRUCACHE} && make install PREFIX=${LUA_SCRIPTS}
fi fi
# NGX_MOD_LUA_MYSQL # NGX_MOD_LUA_MYSQL
@@ -186,11 +219,9 @@ test_nginx() {
--lock-path=/var/run/nginx.lock \ --lock-path=/var/run/nginx.lock \
--error-log-path=/var/log/nginx/error.log \ --error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \ --http-log-path=/var/log/nginx/access.log \
--with-openssl=/opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} \
--with-openssl-opt=enable-tls1_3 \
--with-pcre \ --with-pcre \
--with-pcre-jit \ --with-pcre-jit \
--with-pcre=/opt/mod/pcre2-pcre2-${SYSTEM_PCRE} \ --with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
--with-zlib=/opt/mod/zlib \ --with-zlib=/opt/mod/zlib \
--with-threads \ --with-threads \
--with-file-aio \ --with-file-aio \
@@ -231,8 +262,8 @@ test_nginx() {
--add-module=/opt/mod/redis2-nginx-module \ --add-module=/opt/mod/redis2-nginx-module \
--add-module=/opt/mod/ngx_brotli \ --add-module=/opt/mod/ngx_brotli \
--add-module=/opt/mod/testcookie \ --add-module=/opt/mod/testcookie \
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \ --with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/aws-lc/include" \
--with-ld-opt="-Wl,-rpath,/usr/local/LuaJIT/lib -Wl,-rpath,/usr/local/lib -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/mod/pcre2-pcre2-${SYSTEM_PCRE}/.libs -lpcre2-8 -L/lib/x86_64-linux-gnu -lpcre" --with-ld-opt="-Wl,-rpath,/usr/local/LuaJIT/lib -Wl,-rpath,/usr/local/lib -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/mod/pcre2-${SYSTEM_PCRE}/.libs -lpcre2-8 -L/usr/local/aws-lc/lib -lssl -lcrypto -Wl,-rpath,/usr/local/aws-lc/lib"
make clean make clean
} }
function build() { function build() {
@@ -246,11 +277,9 @@ function build() {
--lock-path=/var/run/nginx.lock \ --lock-path=/var/run/nginx.lock \
--error-log-path=/var/log/nginx/error.log \ --error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \ --http-log-path=/var/log/nginx/access.log \
--with-openssl=/opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} \
--with-openssl-opt=enable-tls1_3 \
--with-pcre \ --with-pcre \
--with-pcre-jit \ --with-pcre-jit \
--with-pcre=/opt/mod/pcre2-pcre2-${SYSTEM_PCRE} \ --with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
--with-zlib=/opt/mod/zlib \ --with-zlib=/opt/mod/zlib \
--with-threads \ --with-threads \
--with-file-aio \ --with-file-aio \
@@ -291,9 +320,14 @@ function build() {
--add-module=/opt/mod/redis2-nginx-module \ --add-module=/opt/mod/redis2-nginx-module \
--add-module=/opt/mod/ngx_brotli \ --add-module=/opt/mod/ngx_brotli \
--add-module=/opt/mod/testcookie \ --add-module=/opt/mod/testcookie \
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \ --with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/aws-lc/include" \
--with-ld-opt="-Wl,-rpath,/usr/local/LuaJIT/lib -Wl,-rpath,/usr/local/lib -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/mod/pcre2-pcre2-${SYSTEM_PCRE}/.libs -lpcre2-8 -L/lib/x86_64-linux-gnu -lpcre" --with-ld-opt="-Wl,-rpath,/usr/local/LuaJIT/lib -Wl,-rpath,/usr/local/lib -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/mod/pcre2-${SYSTEM_PCRE}/.libs -lpcre2-8 -L/usr/local/aws-lc/lib -lssl -lcrypto -Wl,-rpath,/usr/local/aws-lc/lib"
make -j`nproc` && make install && make clean # NOTE: kept as separate statements (not `make && make install && make clean`)
# so `set -e` actually fires on a make failure. The && chain hides left-side
# failures from set -e, which previously let half-built nginx ship.
cd /opt/nginx-${NGINX} && make -j`nproc`
cd /opt/nginx-${NGINX} && make install
cd /opt/nginx-${NGINX} && make clean
unset NGINX unset NGINX
} }
function post_build() { function post_build() {
+63 -10
View File
@@ -1,8 +1,14 @@
# Suggestions? => https://github.com/theraw/The-World-Is-Yours/issues # Suggestions? => https://github.com/theraw/The-World-Is-Yours/issues
# Problems? => https://github.com/theraw/The-World-Is-Yours/issues # Problems? => https://github.com/theraw/The-World-Is-Yours/issues
#
# Tuned for shared hosting at 5,000+ vhost scale.
# Per-vhost listen/ssl_certificate directives live in /nginx/live/* — this
# file only contains the global event/http settings.
user nginx; user nginx;
pid /var/run/nginx.pid; pid /var/run/nginx.pid;
worker_processes auto; worker_processes auto;
worker_cpu_affinity auto; # Pin workers to cores for L1/L2 locality.
worker_rlimit_nofile 65535; worker_rlimit_nofile 65535;
events { events {
@@ -26,21 +32,51 @@ http {
# =================== END LOGS ========================= # # =================== END LOGS ========================= #
# ==================== GENERAL ========================= # # ==================== GENERAL ========================= #
client_body_buffer_size 2M; # Header buffers — keep small. The previous 2M default was a memory
client_header_buffer_size 2M; # amplification target (per-conn × worker_connections = absurd worst case).
client_body_timeout 90s; client_header_buffer_size 4k;
client_header_timeout 90s; large_client_header_buffers 4 16k;
client_body_buffer_size 16k;
client_max_body_size 2M; client_max_body_size 2M;
keepalive_timeout 15s; client_body_timeout 30s;
client_header_timeout 30s;
send_timeout 30s;
reset_timedout_connection on; # Free sockets fast under churn.
keepalive_timeout 65s; # Amortise TCP setup across requests.
keepalive_requests 10000; # Default 1000 too low for HTTP/2.
max_headers 100; # nginx 1.29.8 — slowloris defence.
port_in_redirect off; port_in_redirect off;
sendfile on; sendfile on;
server_names_hash_bucket_size 6969; sendfile_max_chunk 1m;
server_name_in_redirect off;
server_tokens off;
tcp_nodelay on; tcp_nodelay on;
tcp_nopush on; tcp_nopush on;
types_hash_max_size 2048; server_tokens off;
resolver 1.1.1.1 1.0.0.1; server_name_in_redirect off;
# 5,000+ vhost hash sizing. _max_size must exceed total server names;
# _bucket_size must be a CPU-cache-line multiple (32/64/128/256/512/1024).
server_names_hash_bucket_size 128;
server_names_hash_max_size 32768;
types_hash_max_size 4096;
# File metadata cache — biggest single win for static-heavy shared hosting.
open_file_cache max=200000 inactive=30s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# ===================== TLS ============================ #
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; # TLS 1.3 ciphers, client picks.
ssl_session_cache shared:SSL:200m; # ~800k sessions shared across workers
ssl_session_timeout 1d;
ssl_session_tickets off; # Off unless you have ticket-key rotation.
ssl_stapling on; # OCSP stapling — avoid per-handshake OCSP lookups.
ssl_stapling_verify on;
# ===================== END TLS ======================== #
resolver 1.1.1.1 1.0.0.1 valid=300s;
resolver_timeout 5s;
default_type application/octet-stream; default_type application/octet-stream;
include /nginx/mime.types; include /nginx/mime.types;
@@ -48,6 +84,23 @@ http {
default upgrade; default upgrade;
'' close; '' close;
} }
# ==================== COMPRESSION ===================== #
# Compiled in, now actually enabled. Bandwidth saving on text responses
# is typically 60-80% for HTML/JSON/CSS/JS/SVG. Comp level 4 is the
# sweet spot for CPU vs ratio on shared hosting.
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml image/svg+xml font/ttf font/otf font/woff font/woff2;
brotli on;
brotli_comp_level 4;
brotli_min_length 256;
brotli_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml image/svg+xml font/ttf font/otf font/woff font/woff2;
# =================== END COMPRESSION ================== #
# =================== END GENERAL ====================== # # =================== END GENERAL ====================== #
# ================ LOAD VHOST +CONFIGS ================= # # ================ LOAD VHOST +CONFIGS ================= #
+17 -14
View File
@@ -1,48 +1,51 @@
export NGINX="1.26.0" export NGINX="1.30.0"
export LUA_SCRIPTS="/usr/nginx_lua" export LUA_SCRIPTS="/usr/nginx_lua"
# https://github.com/openresty/lua-nginx-module/tags # https://github.com/openresty/lua-nginx-module/tags
export NGX_MOD_LUA="0.10.27" export NGX_MOD_LUA="0.10.29"
# https://github.com/vision5/ngx_devel_kit/tags # https://github.com/vision5/ngx_devel_kit/tags
export NGX_MOD_DEVELKIT="0.3.3" export NGX_MOD_DEVELKIT="0.3.4"
# https://github.com/leev/ngx_http_geoip2_module/releases # https://github.com/leev/ngx_http_geoip2_module/releases
export NGX_MOD_GEOIP2="3.4" export NGX_MOD_GEOIP2="3.4"
# https://github.com/owasp-modsecurity/ModSecurity-nginx/releases # https://github.com/owasp-modsecurity/ModSecurity-nginx/releases
export NGX_MOD_MODSECURITY="1.0.3" export NGX_MOD_MODSECURITY="1.0.4"
# https://github.com/winshining/nginx-http-flv-module/releases # https://github.com/winshining/nginx-http-flv-module/releases
export NGX_MOD_HTTPFLV="1.2.11" export NGX_MOD_HTTPFLV="1.2.13"
# https://github.com/openresty/headers-more-nginx-module/tags # https://github.com/openresty/headers-more-nginx-module/tags
export NGX_MOD_HEADERS_MORE="0.37" export NGX_MOD_HEADERS_MORE="0.39"
# https://github.com/openresty/set-misc-nginx-module/releases # https://github.com/openresty/set-misc-nginx-module/releases
export NGX_MOD_SETMISC="0.33" export NGX_MOD_SETMISC="0.33"
# https://github.com/openresty/lua-resty-core/tags # https://github.com/openresty/lua-resty-core/tags
export LUA_SCRIPTS_RESTYCORE="0.1.28" export LUA_SCRIPTS_RESTYCORE="0.1.32"
# https://github.com/openresty/lua-resty-lrucache/tags # https://github.com/openresty/lua-resty-lrucache/tags
export LUA_SCRIPTS_LRUCACHE="0.13" export LUA_SCRIPTS_LRUCACHE="0.15"
# https://github.com/openresty/luajit2/tags # https://github.com/openresty/luajit2/tags
export SYSTEM_LUAJIT="2.1-20231117" export SYSTEM_LUAJIT="2.1-20260311"
# https://github.com/PCRE2Project/pcre2/releases # https://github.com/PCRE2Project/pcre2/releases
export SYSTEM_PCRE="10.43" export SYSTEM_PCRE="10.47"
# https://github.com/openssl/openssl # https://github.com/aws/aws-lc/tags
export SYSTEM_OPENSSL="3.1.5-quic1" # AWS-LC = Amazon's BoringSSL fork. Supported natively in nginx since 1.29.2.
# Picked over quictls (EOL OpenSSL 3.1 base) and over OpenSSL 3.5 native QUIC
# because of better TLS handshake throughput and clean release tagging.
export SYSTEM_AWSLC="1.72.0"
# https://github.com/SpiderLabs/ModSecurity/releases # https://github.com/SpiderLabs/ModSecurity/releases 3.0.12
export SYSTEM_MODSECURITY="3.0.12" export SYSTEM_MODSECURITY="3.0.12"
# https://github.com/openresty/lua-resty-mysql/tags # https://github.com/openresty/lua-resty-mysql/tags
export NGX_MOD_LUA_MYSQL="0.27" export NGX_MOD_LUA_MYSQL="0.29"
# https://github.com/openresty/lua-resty-lock/tags # https://github.com/openresty/lua-resty-lock/tags
export NGX_MOD_LUA_LOCK="0.09" export NGX_MOD_LUA_LOCK="0.09"