Compare commits
7
Commits
master
..
94b9f0e5cb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94b9f0e5cb | ||
|
|
6d38221fa3 | ||
|
|
713cb9160e | ||
|
|
035d396c4f | ||
|
|
e9a1efbf89 | ||
|
|
1d905742bc | ||
|
|
956543cfc3 |
@@ -1,199 +0,0 @@
|
|||||||
name: build-and-publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
target: [trixie, raccoon]
|
|
||||||
include:
|
|
||||||
- target: trixie
|
|
||||||
image: debian:13
|
|
||||||
distro_dir: Trixie
|
|
||||||
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
|
||||||
nexus_user_secret: NEXUS_USER_TRIXIE
|
|
||||||
nexus_pass_secret: NEXUS_PASS_TRIXIE
|
|
||||||
- target: raccoon
|
|
||||||
image: ubuntu:26.04
|
|
||||||
distro_dir: Raccoon
|
|
||||||
nexus_repo_secret: NEXUS_REPO_RACCOON
|
|
||||||
nexus_user_secret: NEXUS_USER_RACCOON
|
|
||||||
nexus_pass_secret: NEXUS_PASS_RACCOON
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: ${{ matrix.image }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Bootstrap
|
|
||||||
run: |
|
|
||||||
apt-get update -qq
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
||||||
git ca-certificates nodejs
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
id: pkg
|
|
||||||
env:
|
|
||||||
TARGET: ${{ matrix.target }}
|
|
||||||
DISTRO_DIR: ${{ matrix.distro_dir }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
REPO_ROOT="$PWD" # captured before any cd in the build script
|
|
||||||
touch /.dockerenv
|
|
||||||
bash build/${TARGET}.sh new
|
|
||||||
bash build/${TARGET}.sh build
|
|
||||||
bash build/${TARGET}.sh postfix
|
|
||||||
|
|
||||||
NGINX_VER="$(nginx -v 2>&1 | awk -F/ '{print $2}')"
|
|
||||||
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
|
||||||
ARCH="amd64"
|
|
||||||
|
|
||||||
assemble_deb() {
|
|
||||||
local pkg_name="$1" unit_src="$2" conflicts="$3"
|
|
||||||
local pkg_dir="/opt/${pkg_name}_${VERSION}_${ARCH}"
|
|
||||||
local deb_dir="${pkg_dir}/DEBIAN"
|
|
||||||
|
|
||||||
mkdir -p "${pkg_dir}/usr/sbin" \
|
|
||||||
"${pkg_dir}/etc/systemd/system" \
|
|
||||||
"${pkg_dir}/usr/lib" \
|
|
||||||
"${pkg_dir}/usr/nginx_lua" \
|
|
||||||
"${pkg_dir}/usr/share/twiy/defaults/nginx" \
|
|
||||||
"${pkg_dir}/nginx/live" "${pkg_dir}/nginx/conf.d" \
|
|
||||||
"${pkg_dir}/nginx/config" "${pkg_dir}/nginx/modsec" \
|
|
||||||
"${pkg_dir}/nginx/modules"
|
|
||||||
|
|
||||||
cp /usr/sbin/nginx "${pkg_dir}/usr/sbin/"
|
|
||||||
# /nginx ships as an EMPTY, dpkg-owned skeleton (above): the dirs
|
|
||||||
# are tracked so upgrades from the old layout don't warn about
|
|
||||||
# "unable to delete old directory /nginx", but NO config file under
|
|
||||||
# it is tracked. The pristine configs go into a defaults stash;
|
|
||||||
# postinst places them into /nginx only when missing and never
|
|
||||||
# overwrites an admin-edited file (drops <file>.new instead).
|
|
||||||
# /hostdata is intentionally NOT packaged or seeded — postinst only
|
|
||||||
# ensures the directory exists and never removes it.
|
|
||||||
cp -R /nginx/. "${pkg_dir}/usr/share/twiy/defaults/nginx/" || true
|
|
||||||
cp "${unit_src}" "${pkg_dir}/etc/systemd/system/nginx.service"
|
|
||||||
cp -R /usr/nginx_lua "${pkg_dir}/usr/" || true
|
|
||||||
|
|
||||||
for d in /usr/local/aws-lc /usr/local/LuaJIT /usr/local/modsecurity /usr/local/zlib-ng; do
|
|
||||||
[ -d "$d" ] && cp -R "$d" "${pkg_dir}/usr/local/" || true
|
|
||||||
done
|
|
||||||
mkdir -p "${pkg_dir}/usr/local/lib"
|
|
||||||
cp -R /usr/local/lib/. "${pkg_dir}/usr/local/lib/" 2>/dev/null || true
|
|
||||||
|
|
||||||
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
|
|
||||||
case "$lib" in /usr/local/*) continue ;; esac
|
|
||||||
cp "$lib" "${pkg_dir}/usr/lib/" || true
|
|
||||||
done
|
|
||||||
|
|
||||||
mkdir -p "${deb_dir}"
|
|
||||||
printf 'Package: %s\nVersion: %s\nSection: base\nPriority: optional\nArchitecture: %s\nDepends: libjemalloc2, libsystemd0\nConflicts: %s\nReplaces: %s\nMaintainer: Julio <me@julio.al>\nDescription: Nginx L7 DDoS Protection (%s), built by RAWeb CI for %s.\n' \
|
|
||||||
"${pkg_name}" "${VERSION}" "${ARCH}" "${conflicts}" "${conflicts}" "${pkg_name}" "${TARGET}" \
|
|
||||||
> "${deb_dir}/control"
|
|
||||||
|
|
||||||
# Per-package maintainer scripts:
|
|
||||||
# twiy:
|
|
||||||
# preinst — backs up /nginx before an upgrade unpacks (so
|
|
||||||
# admin configs survive the migration off dpkg
|
|
||||||
# tracking).
|
|
||||||
# postinst — restores that backup, then seeds any MISSING
|
|
||||||
# /nginx default after asking the admin (Y/N per
|
|
||||||
# file); existing configs are never replaced.
|
|
||||||
# twiy-raweb:
|
|
||||||
# preinst/postinst — NEVER touch /nginx (no create, update,
|
|
||||||
# replace, remove, or chown). Only the binary,
|
|
||||||
# systemd unit, nginx user and log dir are updated.
|
|
||||||
if [ "${pkg_name}" = "twiy-raweb" ]; then
|
|
||||||
cp "${REPO_ROOT}/build/deb/preinst-raweb" "${deb_dir}/preinst"
|
|
||||||
cp "${REPO_ROOT}/build/deb/postinst-raweb" "${deb_dir}/postinst"
|
|
||||||
else
|
|
||||||
cp "${REPO_ROOT}/build/deb/preinst" "${deb_dir}/preinst"
|
|
||||||
cp "${REPO_ROOT}/build/deb/postinst" "${deb_dir}/postinst"
|
|
||||||
fi
|
|
||||||
chmod 755 "${deb_dir}/preinst" "${deb_dir}/postinst"
|
|
||||||
|
|
||||||
dpkg-deb --build "${pkg_dir}"
|
|
||||||
}
|
|
||||||
|
|
||||||
assemble_deb "twiy" "${REPO_ROOT}/static/${DISTRO_DIR}/nginx.service" "twiy-raweb"
|
|
||||||
assemble_deb "twiy-raweb" "${REPO_ROOT}/static/${DISTRO_DIR}/nginx-raweb.service" "twiy"
|
|
||||||
|
|
||||||
DEB_TWIY="/opt/twiy_${VERSION}_${ARCH}.deb"
|
|
||||||
DEB_RAWEB="/opt/twiy-raweb_${VERSION}_${ARCH}.deb"
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "deb_twiy=${DEB_TWIY}"
|
|
||||||
echo "deb_raweb=${DEB_RAWEB}"
|
|
||||||
echo "version=${VERSION}"
|
|
||||||
} >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
ls -la /opt/twiy*.deb
|
|
||||||
sha256sum /opt/twiy*.deb
|
|
||||||
|
|
||||||
- name: Publish
|
|
||||||
env:
|
|
||||||
NEXUS_USER: ${{ secrets[matrix.nexus_user_secret] }}
|
|
||||||
NEXUS_PASS: ${{ secrets[matrix.nexus_pass_secret] }}
|
|
||||||
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
|
||||||
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
|
||||||
DEB_TWIY: ${{ steps.pkg.outputs.deb_twiy }}
|
|
||||||
DEB_RAWEB: ${{ steps.pkg.outputs.deb_raweb }}
|
|
||||||
TARGET: ${{ matrix.target }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
umask 077
|
|
||||||
|
|
||||||
apt-get install -y -q --no-install-recommends curl python3 ca-certificates >/dev/null
|
|
||||||
|
|
||||||
SECDIR="$(mktemp -d -p /dev/shm twiy-XXXXXXXX 2>/dev/null \
|
|
||||||
|| mktemp -d -t twiy-XXXXXXXX)"
|
|
||||||
chmod 700 "$SECDIR"
|
|
||||||
cleanup() {
|
|
||||||
find "$SECDIR" -type f -exec shred -uz {} + 2>/dev/null || true
|
|
||||||
rm -rf "$SECDIR"
|
|
||||||
}
|
|
||||||
trap cleanup EXIT INT TERM HUP
|
|
||||||
|
|
||||||
NEXUS_HOST="$(printf '%s' "$NEXUS_URL" | awk -F/ '{print $3}')"
|
|
||||||
printf 'machine %s login %s password %s\n' \
|
|
||||||
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
|
|
||||||
unset NEXUS_USER NEXUS_PASS
|
|
||||||
|
|
||||||
publish_one() {
|
|
||||||
local deb="$1" pkg_name="$2"
|
|
||||||
|
|
||||||
local old_id
|
|
||||||
old_id="$(curl -fsS --netrc-file "$SECDIR/netrc" \
|
|
||||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
|
|
||||||
| PKG_NAME="$pkg_name" python3 -c '
|
|
||||||
import sys, json, os
|
|
||||||
for c in json.load(sys.stdin).get("items", []):
|
|
||||||
if c.get("name") == os.environ["PKG_NAME"]:
|
|
||||||
print(c["id"]); break
|
|
||||||
' || true)"
|
|
||||||
if [ -n "$old_id" ]; then
|
|
||||||
curl -fsS -X DELETE --netrc-file "$SECDIR/netrc" \
|
|
||||||
"$NEXUS_URL/service/rest/v1/components/$old_id" -o /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
local http
|
|
||||||
http="$(curl -sS --netrc-file "$SECDIR/netrc" \
|
|
||||||
-o "$SECDIR/upload.body" -w '%{http_code}' \
|
|
||||||
-X POST -F "apt.asset=@$deb" \
|
|
||||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO")"
|
|
||||||
case "$http" in
|
|
||||||
201|204) echo "[$TARGET] uploaded $(basename "$deb")" ;;
|
|
||||||
*) echo "[$TARGET] upload failed for $pkg_name (HTTP $http)"; cat "$SECDIR/upload.body"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
publish_one "$DEB_TWIY" "twiy"
|
|
||||||
publish_one "$DEB_RAWEB" "twiy-raweb"
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
name: Build and Publish NGINX
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install git dpkg-dev
|
||||||
|
|
||||||
|
- name: Clone the repository
|
||||||
|
run: |
|
||||||
|
cd $HOME
|
||||||
|
git clone https://github.com/theraw/The-World-Is-Yours.git
|
||||||
|
cd The-World-Is-Yours/
|
||||||
|
|
||||||
|
- name: Build NGINX
|
||||||
|
run: |
|
||||||
|
touch $HOME/.dockerenv
|
||||||
|
cd $HOME/The-World-Is-Yours/
|
||||||
|
sudo bash build/run.sh new
|
||||||
|
sudo bash build/run.sh build
|
||||||
|
sudo bash build/run.sh postfix
|
||||||
|
|
||||||
|
- name: Build .deb Package
|
||||||
|
id: build_deb
|
||||||
|
run: |
|
||||||
|
cd $HOME/The-World-Is-Yours/
|
||||||
|
sudo bash -c 'function create_deb() {
|
||||||
|
PKG_NAME="twiy"
|
||||||
|
VERSION=$(nginx -v 2>&1 | awk -F"/" "{print \$2}")
|
||||||
|
ARCH="amd64"
|
||||||
|
PKG_DIR="/opt/${PKG_NAME}_${VERSION}_${ARCH}"
|
||||||
|
DEB_DIR="${PKG_DIR}/DEBIAN"
|
||||||
|
mkdir -p ${PKG_DIR}/usr/sbin
|
||||||
|
mkdir -p ${PKG_DIR}/usr/local/nginx
|
||||||
|
mkdir -p ${PKG_DIR}/nginx
|
||||||
|
mkdir -p ${PKG_DIR}/etc/systemd/system
|
||||||
|
mkdir -p ${PKG_DIR}/var/log/nginx
|
||||||
|
mkdir -p ${PKG_DIR}/nginx/conf.d
|
||||||
|
mkdir -p ${PKG_DIR}/nginx/live
|
||||||
|
mkdir -p ${PKG_DIR}/nginx/modsec
|
||||||
|
mkdir -p ${PKG_DIR}/usr/lib
|
||||||
|
mkdir -p ${PKG_DIR}/usr/local/lib
|
||||||
|
mkdir -p ${PKG_DIR}/hostdata/default/public_html
|
||||||
|
mkdir -p ${PKG_DIR}/usr/nginx_lua
|
||||||
|
cp /usr/sbin/nginx ${PKG_DIR}/usr/sbin/
|
||||||
|
cp -R /nginx/* ${PKG_DIR}/nginx/
|
||||||
|
cp /etc/systemd/system/nginx.service ${PKG_DIR}/etc/systemd/system/
|
||||||
|
cp -R /hostdata/default ${PKG_DIR}/hostdata/
|
||||||
|
cp -R /usr/nginx_lua ${PKG_DIR}/usr/
|
||||||
|
for lib in $(ldd /usr/sbin/nginx | grep "=> /" | awk "{print \$3}"); do
|
||||||
|
cp "$lib" "${PKG_DIR}/usr/lib/"
|
||||||
|
done
|
||||||
|
for module in /opt/mod/*; do
|
||||||
|
if [ -f "$module" ]; then
|
||||||
|
for lib in $(ldd "$module" | grep "=> /" | awk "{print \$3}"); do
|
||||||
|
cp "$lib" "${PKG_DIR}/usr/lib/"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
mkdir -p ${DEB_DIR}
|
||||||
|
echo "Package: ${PKG_NAME}" > ${DEB_DIR}/control
|
||||||
|
echo "Version: ${VERSION}" >> ${DEB_DIR}/control
|
||||||
|
echo "Section: base" >> ${DEB_DIR}/control
|
||||||
|
echo "Priority: optional" >> ${DEB_DIR}/control
|
||||||
|
echo "Architecture: ${ARCH}" >> ${DEB_DIR}/control
|
||||||
|
echo "Maintainer: Julio <me@julio.al>" >> ${DEB_DIR}/control
|
||||||
|
echo "Description: Nginx L7 DDoS Protection! And many more features github.com/theraw/The-World-Is-Yours" >> ${DEB_DIR}/control
|
||||||
|
echo "#!/bin/bash" > ${DEB_DIR}/postinst
|
||||||
|
echo "useradd -r -d /usr/local/nginx -s /bin/false nginx || true" >> ${DEB_DIR}/postinst
|
||||||
|
chmod 755 ${DEB_DIR}/postinst
|
||||||
|
chmod -R 0755 ${DEB_DIR}
|
||||||
|
dpkg-deb --build ${PKG_DIR}
|
||||||
|
mv ${PKG_DIR}.deb /opt/${PKG_NAME}_${VERSION}_${ARCH}.deb
|
||||||
|
echo "Debian package created at /opt/${PKG_NAME}_${VERSION}_${ARCH}.deb"
|
||||||
|
echo "::set-output name=VERSION::${VERSION}"
|
||||||
|
}; create_deb'
|
||||||
|
|
||||||
|
- name: Create Git Tag
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.build_deb.outputs.VERSION }}
|
||||||
|
git config user.name "theraw"
|
||||||
|
git config user.email "me@julio.al"
|
||||||
|
git tag v$VERSION
|
||||||
|
git push origin v$VERSION
|
||||||
|
|
||||||
|
- name: Upload .deb Package as Release Asset
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: /opt/*.deb
|
||||||
|
tag_name: v${{ steps.build_deb.outputs.version }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
|
||||||
+24
-23
@@ -1,24 +1,25 @@
|
|||||||
.claude
|
/.phpunit.cache
|
||||||
.codex
|
/node_modules
|
||||||
|
/public/build
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/storage/*.key
|
||||||
|
/storage/pail
|
||||||
|
/vendor
|
||||||
.env
|
.env
|
||||||
.creds
|
.env.backup
|
||||||
.workers
|
.env.production
|
||||||
.local
|
.phpactor.json
|
||||||
.pi
|
.phpunit.result.cache
|
||||||
.gemini
|
Homestead.json
|
||||||
.cargo
|
Homestead.yaml
|
||||||
.claude.json
|
npm-debug.log
|
||||||
.copilot
|
yarn-error.log
|
||||||
.docker
|
/auth.json
|
||||||
.grok
|
/.fleet
|
||||||
.ollama
|
/.idea
|
||||||
Dockerfile
|
/.nova
|
||||||
docker-compose.yaml
|
/.vscode
|
||||||
docker-compose.yml
|
/.zed
|
||||||
PENDING_*.md
|
/.cache
|
||||||
PATCH_*.md
|
.cache
|
||||||
CLAUDE.md
|
|
||||||
GEMINI.md
|
|
||||||
AGENTS.md
|
|
||||||
docs
|
|
||||||
docs/*
|
|
||||||
|
|||||||
@@ -2,65 +2,74 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
- [x] Debian 13 (trixie) and Ubuntu 26.04 LTS (raccoon) supported
|
- [x] **Support Ubuntu 22.04**
|
||||||
- [x] nginx 1.31.3
|
- [x] **Latest Nginx 1.26.0**
|
||||||
- [x] HTTP/3 (QUIC) via AWS-LC
|
- [x] **HTTP/3**
|
||||||
- [x] ModSecurity v3 (libmodsecurity)
|
- [x] **Admin Panel** : Optional *(Not installed by default)*
|
||||||
- [x] Naxsi
|
- [X] **Home Page** *(Nginx stats/graph via nginx stub stats)*
|
||||||
- [x] Lua (LuaJIT 2.1)
|
- [X] **Vhosts Page** *(Create, Delete, Edit)*
|
||||||
- [x] Tenant Isolation.
|
- [X] **IP Management** *(add, edit, delete)* *selectable on vhost creation*
|
||||||
- [x] Cookie-based challenge
|
- [X] **Ports Management** *(add, edit, delete)* *selectable on vhost creation*
|
||||||
- [x] [Versions List](https://git.julio.al/theraw/The-World-Is-Yours/src/branch/master/version)
|
- [ ] **Nginx Settings Page** *(Only change existing nginx.conf values)*
|
||||||
|
- [ ] **Log Reporting Page** (Not set yet, might be all in one page or seperated pages for access logs, modsec logs)
|
||||||
|
- [x] **Php Selector** (a.k.a creation of dedicated fpm pool) *selectable on vhost creation*
|
||||||
|
- [ ] **One click App installer** *(WordPress)*
|
||||||
|
- [x] ModSecurity Support *(Ngx Mod)*
|
||||||
|
- [x] Naxsi Support *(Ngx Mod)*
|
||||||
|
- [x] Lua Support.
|
||||||
|
- [X] **AutoSSL** *(Lua Mod)*
|
||||||
|
- [ ] **Rate Limit** *(Lua Mod)*
|
||||||
|
- [ ] **Captcha** *(Lua Mod)*
|
||||||
|
- [x] Cookie Based Challenge *(Ngx Mod)*
|
||||||
|
- [x] [Versions List](https://github.com/theraw/The-World-Is-Yours/blob/master/version)
|
||||||
|
|
||||||
### Debian 13 (trixie)
|
# Installation methods.
|
||||||
```bash
|
|
||||||
sudo install -d /etc/apt/keyrings
|
|
||||||
sudo curl -fsSL https://apt.julio.al/repository/public/keys/raweb.asc -o /etc/apt/keyrings/raweb.asc
|
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/raweb.asc] https://apt.julio.al/repository/raweb-trixie trixie main" | sudo tee /etc/apt/sources.list.d/raweb.list
|
|
||||||
sudo apt update && sudo apt install twiy
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ubuntu 26.04 LTS (raccoon)
|
- 1 : **Repository (Easy)**
|
||||||
```bash
|
```bash
|
||||||
sudo install -d /etc/apt/keyrings
|
# Add repository and update system.
|
||||||
sudo curl -fsSL https://apt.julio.al/repository/public/keys/raweb.asc -o /etc/apt/keyrings/raweb.asc
|
echo '' > /etc/apt/sources.list.d/the-world-is-yours.list
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/raweb.asc] https://apt.julio.al/repository/raweb-raccoon raccoon main" | sudo tee /etc/apt/sources.list.d/raweb.list
|
apt-get update; apt-get upgrade -y
|
||||||
sudo apt update && sudo apt install twiy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compile from source by yourself.
|
# Install nginx.
|
||||||
|
apt-get install raweb -y
|
||||||
|
|
||||||
```bash
|
# Install admin panel.
|
||||||
apt-get -y install git && cd /root/ && git clone https://git.julio.al/theraw/The-World-Is-Yours.git && cd The-World-Is-Yours/
|
apt-get install raweb-admin -y
|
||||||
|
```
|
||||||
|
- 2 : **Manual .deb (Med)**
|
||||||
|
```bash
|
||||||
|
Download them from : https://github.com/theraw/The-World-Is-Yours/releases
|
||||||
|
```
|
||||||
|
- 3 : **Compile from source (Hard)**
|
||||||
|
```bash
|
||||||
|
apt-get -y install git && cd /root/ && git clone https://github.com/theraw/The-World-Is-Yours.git && cd The-World-Is-Yours/
|
||||||
|
|
||||||
# Debian 13
|
bash build/run.sh new
|
||||||
bash build/trixie.sh new
|
bash build/run.sh build
|
||||||
bash build/trixie.sh build
|
bash build/run.sh postfix
|
||||||
bash build/trixie.sh postfix
|
```
|
||||||
|
- 3.1 : **Compiling from source with changed versions**
|
||||||
|
```bash
|
||||||
|
# assuming you completed step 3.
|
||||||
|
# update "version" file then run again
|
||||||
|
bash build/run.sh new
|
||||||
|
bash build/run.sh build
|
||||||
|
```
|
||||||
|
|
||||||
# Ubuntu 26.04 LTS
|
|
||||||
bash build/raccoon.sh new
|
|
||||||
bash build/raccoon.sh build
|
|
||||||
bash build/raccoon.sh postfix
|
|
||||||
```
|
|
||||||
|
|
||||||
To try a different upstream version, edit `version` and re-run `new` then `build`.
|
|
||||||
|
|
||||||
## CLI Info
|
## CLI Info
|
||||||
|
```bash
|
||||||
|
bash build/run.sh new => Download all modules + nginx that are missing from /opt/. (If you make version changes to 'version' file then simply rerun this to download again)
|
||||||
|
bash build/run.sh build => This is going to simply compile nginx nothing else. (You can run this as many times as you need, its not going to replace configs)
|
||||||
|
bash build/run.sh postfix => This will redownload /nginx/nginx.conf everytime you run it. (Suggested to run only once when you install nginx via my repo for first time)
|
||||||
```
|
```
|
||||||
bash build/<distro>.sh new => Download all modules + nginx that are missing from /opt/.
|
|
||||||
(Re-run after changing the `version` file to fetch new versions.)
|
|
||||||
bash build/<distro>.sh build => Compile nginx. Re-runnable; will not touch your configs.
|
|
||||||
bash build/<distro>.sh postfix => Drop the default /nginx/nginx.conf, vhost, and systemd unit
|
|
||||||
into place. Run once on first install; re-running overwrites
|
|
||||||
/nginx/nginx.conf.
|
|
||||||
```
|
|
||||||
where `<distro>` is `trixie` or `raccoon`.
|
|
||||||
|
|
||||||
|
|
||||||
## Nginx info.
|
## Nginx Structure.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
=> Nginx Folder = /nginx/
|
=> Nginx Folder = /nginx/
|
||||||
=> --conf-path = /nginx/nginx.conf
|
=> --conf-path = /nginx/nginx.conf
|
||||||
=> --pid-path = /var/run/nginx.pid
|
=> --pid-path = /var/run/nginx.pid
|
||||||
@@ -70,54 +79,26 @@ where `<distro>` is `trixie` or `raccoon`.
|
|||||||
=> --error-log-path = /var/log/nginx/error.log
|
=> --error-log-path = /var/log/nginx/error.log
|
||||||
|
|
||||||
LUA RESTY CORE SCRIPTS = /usr/nginx_lua
|
LUA RESTY CORE SCRIPTS = /usr/nginx_lua
|
||||||
|
|
||||||
|
# Admin Panel Info
|
||||||
|
=> Folder = /nginx/admin/public_html
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tenant Isolation
|
|
||||||
|
|
||||||
Confines each site's **static** file serving to its own `root` directory. A symlink, `..`,
|
|
||||||
magic-link or cross-tenant path that escapes the site tree (e.g. a symlink to `/etc/passwd`)
|
|
||||||
is refused with **403**, kernel-enforced via `openat2(RESOLVE_BENEATH)`.
|
|
||||||
**On by default, no vhost config needed.** In-tree symlinks still work.
|
|
||||||
|
|
||||||
**Where the config lives (nothing to add on a fresh install)**
|
|
||||||
- `tenant_isolation` is compiled **default-on**, so it applies to every site with no directive.
|
|
||||||
- The `disable_symlinks if_not_owner from=$document_root;` backstop ships in the `http { }`
|
|
||||||
block of `/nginx/nginx.conf`, so **every** vhost inherits it. Do not add it per-site.
|
|
||||||
- Your site configs live in `/nginx/live/*` and inherit both layers automatically.
|
|
||||||
- Upgrading an old install that kept its own `/nginx/nginx.conf`? Add that one
|
|
||||||
`disable_symlinks` line to its `http { }` block once (or re-run `postfix` to refresh the config).
|
|
||||||
|
|
||||||
**Covered**
|
|
||||||
- Static files served by nginx (the normal file path).
|
|
||||||
- Backstopped at the real serving `open()` by `disable_symlinks if_not_owner`, which also
|
|
||||||
covers `gzip_static`, `autoindex`, `dav`, `mp4`/`flv`.
|
|
||||||
|
|
||||||
**Not covered**
|
|
||||||
- Dynamic content (PHP-FPM / NGINX Unit) is isolated separately per tenant (user / cgroup / namespace).
|
|
||||||
- Not fully race-free: a narrow probe->open timing window remains (closing it fully would
|
|
||||||
break `open_file_cache`), so it is *mitigated* by the `disable_symlinks` backstop, not eliminated.
|
|
||||||
|
|
||||||
**Optional per-vhost tuning**
|
|
||||||
- `tenant_isolation off;` turns it off for a `server`/`location`.
|
|
||||||
- `tenant_isolation_root /home/<user>;` widens the confinement root to the tenant home
|
|
||||||
(allows above-docroot in-tree symlinks, e.g. Laravel's `storage`).
|
|
||||||
|
|
||||||
## How to install lua scripts
|
## How to install lua scripts
|
||||||
```
|
|
||||||
. /root/The-World-Is-Yours/version
|
|
||||||
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-lrucache.git
|
|
||||||
cd /opt/mod/lua-resty-lrucache; make install PREFIX=${LUA_SCRIPTS}
|
|
||||||
nginx -s reload
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance
|
- Method 1
|
||||||
|
```bash
|
||||||
### vs. vanilla nginx (same version, default config)
|
. /root/The-World-Is-Yours/version
|
||||||
|
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-lrucache.git
|
||||||
| Area | Twiy | Vanilla nginx | Why |
|
cd /opt/mod/lua-resty-lrucache; make install PREFIX=${LUA_SCRIPTS}
|
||||||
|---|---|---|---|
|
nginx -s reload
|
||||||
| TLS handshake throughput | **+5-15%** | baseline | AWS-LC's tuned AES/ChaCha asm vs OpenSSL |
|
```
|
||||||
| WAF, Lua, HTTP/3 | included | not included | needs custom build |
|
- Method 2
|
||||||
|
```bash
|
||||||
|
# At first when you use this method you may get errors for missing lua scripts, you can install them with "luarocks".
|
||||||
|
apt-get install luarocks
|
||||||
|
luarocks install lua-resty-lrucache
|
||||||
|
```
|
||||||
|
|
||||||
# Support options.
|
# Support options.
|
||||||
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# postinst — twiy package ONLY (twiy-raweb uses postinst-raweb).
|
|
||||||
#
|
|
||||||
# Config files live under /nginx but are NOT tracked by dpkg. The package
|
|
||||||
# ships an empty /nginx skeleton (so dpkg keeps the dirs across upgrades) plus
|
|
||||||
# a pristine copy of every config under /usr/share/twiy/defaults/nginx.
|
|
||||||
#
|
|
||||||
# Config policy for twiy:
|
|
||||||
# - target present (identical OR admin-edited) -> NEVER replace; leave as-is.
|
|
||||||
# - target absent -> ASK the admin (per file,
|
|
||||||
# Y/N) and only create it on Y.
|
|
||||||
# We never drop <file>.new and we never overwrite an existing config, so an
|
|
||||||
# upgrade can never change an admin-edited config.
|
|
||||||
#
|
|
||||||
# /hostdata is left entirely to the admin: we only make sure the dir exists,
|
|
||||||
# and we never touch or remove its contents.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Ask the admin a yes/no question on the controlling terminal. Defaults to
|
|
||||||
# "no" (return 1) whenever we cannot prompt — noninteractive frontend or no
|
|
||||||
# usable terminal — so a config is never created without explicit consent.
|
|
||||||
prompt_yes_no() {
|
|
||||||
msg="$1"
|
|
||||||
if [ "${DEBIAN_FRONTEND:-}" = noninteractive ] || [ ! -r /dev/tty ]; then
|
|
||||||
echo "twiy: $msg -> skipped (noninteractive)"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
printf 'twiy: %s [y/N] ' "$msg" > /dev/tty
|
|
||||||
read ans < /dev/tty || ans=""
|
|
||||||
case "$ans" in
|
|
||||||
[Yy]|[Yy][Ee][Ss]) return 0 ;;
|
|
||||||
*) return 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
useradd -r -s /bin/false nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
# Existing dirs are left exactly as they are (mkdir -p is a no-op then).
|
|
||||||
mkdir -p /nginx /hostdata
|
|
||||||
|
|
||||||
# Migration: older releases shipped /nginx/* as dpkg-tracked files, so the
|
|
||||||
# upgrade unpack deletes them before this script runs. preinst stashed a copy
|
|
||||||
# first — restore the admin's own files now, without clobbering anything
|
|
||||||
# already present (cp -n). This only puts back what dpkg removed; it never
|
|
||||||
# introduces new packaged defaults, so no prompt is needed here.
|
|
||||||
if [ -d /var/backups/twiy-nginx ]; then
|
|
||||||
cp -an /var/backups/twiy-nginx/. /nginx/ 2>/dev/null || true
|
|
||||||
rm -rf /var/backups/twiy-nginx
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Seed packaged defaults:
|
|
||||||
# - target present -> do nothing (never replace, no .new).
|
|
||||||
# - target absent -> ask the admin; create it only if they answer yes.
|
|
||||||
seed_tree() {
|
|
||||||
stash="$1"
|
|
||||||
target="$2"
|
|
||||||
[ -d "$stash" ] || return 0
|
|
||||||
find "$stash" -type f | while IFS= read -r src; do
|
|
||||||
rel=${src#$stash/}
|
|
||||||
dst="$target/$rel"
|
|
||||||
if [ -e "$dst" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if prompt_yes_no "config '$dst' does not exist. Create it from the packaged default?"; then
|
|
||||||
install -d "$(dirname "$dst")"
|
|
||||||
cp -p "$src" "$dst"
|
|
||||||
echo "twiy: created $dst"
|
|
||||||
else
|
|
||||||
echo "twiy: skipped $dst"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
seed_tree /usr/share/twiy/defaults/nginx /nginx
|
|
||||||
|
|
||||||
install -d /nginx/conf.d /nginx/config
|
|
||||||
install -d -o nginx -g nginx -m 0755 /var/log/nginx
|
|
||||||
chown -R nginx:nginx /var/log/nginx /nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
systemctl daemon-reload 2>/dev/null || true
|
|
||||||
systemctl enable nginx.service 2>/dev/null || true
|
|
||||||
systemctl restart nginx.service 2>/dev/null || true
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# postinst — twiy-raweb package ONLY.
|
|
||||||
#
|
|
||||||
# STRICT RULE: this package MUST NOT touch /nginx in any way. It never creates,
|
|
||||||
# updates, replaces, removes, or re-owns any file or directory under /nginx.
|
|
||||||
# The admin owns /nginx entirely; an upgrade only refreshes the nginx binary
|
|
||||||
# (handled by dpkg), the systemd unit, the nginx system user, and the log dir.
|
|
||||||
#
|
|
||||||
# Note: the empty /nginx skeleton is still part of the package payload, so dpkg
|
|
||||||
# keeps those dirs across upgrades without ever removing or rewriting them. This
|
|
||||||
# script deliberately performs ZERO operations on /nginx — no mkdir, no seed,
|
|
||||||
# no restore, no chown.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
useradd -r -s /bin/false nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
# Log dir only — this is /var/log/nginx, NOT /nginx.
|
|
||||||
install -d -o nginx -g nginx -m 0755 /var/log/nginx
|
|
||||||
chown -R nginx:nginx /var/log/nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
systemctl daemon-reload 2>/dev/null || true
|
|
||||||
systemctl enable nginx.service 2>/dev/null || true
|
|
||||||
systemctl restart nginx.service 2>/dev/null || true
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# preinst — twiy package ONLY (twiy-raweb uses preinst-raweb, a no-op).
|
|
||||||
#
|
|
||||||
# Older releases shipped /nginx as dpkg-tracked files. When upgrading from one
|
|
||||||
# of those, dpkg deletes the old /nginx/* files during unpack (they are no
|
|
||||||
# longer part of the package) BEFORE postinst runs. Stash a copy of the live
|
|
||||||
# config tree first so postinst can restore any admin-edited config and it
|
|
||||||
# survives the migration. Never touched on a fresh install.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ "$1" = upgrade ] && [ -d /nginx ]; then
|
|
||||||
rm -rf /var/backups/twiy-nginx
|
|
||||||
mkdir -p /var/backups
|
|
||||||
cp -a /nginx /var/backups/twiy-nginx
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# preinst — twiy-raweb package ONLY.
|
|
||||||
#
|
|
||||||
# STRICT RULE: this package MUST NOT touch /nginx in any way. There is nothing
|
|
||||||
# to back up or migrate because nothing under /nginx is ever read, written, or
|
|
||||||
# restored by twiy-raweb. Intentionally a no-op.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
diff -urN nginx-1.31.0-pristine2/src/event/ngx_event_openssl.c nginx-1.31.0-manual/src/event/ngx_event_openssl.c
|
|
||||||
--- nginx-1.31.0-pristine2/src/event/ngx_event_openssl.c 2026-05-15 13:37:51.446080719 +0000
|
|
||||||
+++ nginx-1.31.0-manual/src/event/ngx_event_openssl.c 2026-05-15 13:38:11.254620535 +0000
|
|
||||||
@@ -2115,6 +2115,7 @@
|
|
||||||
|
|
||||||
sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
|
|
||||||
sc->buffer_size = ssl->buffer_size;
|
|
||||||
+ sc->dyn_rec = ssl->dyn_rec;
|
|
||||||
|
|
||||||
sc->session_ctx = ssl->ctx;
|
|
||||||
|
|
||||||
@@ -3086,6 +3087,41 @@
|
|
||||||
|
|
||||||
for ( ;; ) {
|
|
||||||
|
|
||||||
+ /* Dynamic record resizing:
|
|
||||||
+ We want the initial records to fit into one TCP segment
|
|
||||||
+ so we don't get TCP HoL blocking due to TCP Slow Start.
|
|
||||||
+ A connection always starts with small records, but after
|
|
||||||
+ a given amount of records sent, we make the records larger
|
|
||||||
+ to reduce header overhead.
|
|
||||||
+ After a connection has idled for a given timeout, begin
|
|
||||||
+ the process from the start. The actual parameters are
|
|
||||||
+ configurable. If dyn_rec_timeout is 0, we assume dyn_rec is off. */
|
|
||||||
+
|
|
||||||
+ if (c->ssl->dyn_rec.timeout > 0 ) {
|
|
||||||
+
|
|
||||||
+ if (ngx_current_msec - c->ssl->dyn_rec_last_write >
|
|
||||||
+ c->ssl->dyn_rec.timeout)
|
|
||||||
+ {
|
|
||||||
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
|
|
||||||
+ c->ssl->dyn_rec_records_sent = 0;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ if (c->ssl->dyn_rec_records_sent >
|
|
||||||
+ c->ssl->dyn_rec.threshold * 2)
|
|
||||||
+ {
|
|
||||||
+ buf->end = buf->start + c->ssl->buffer_size;
|
|
||||||
+
|
|
||||||
+ } else if (c->ssl->dyn_rec_records_sent >
|
|
||||||
+ c->ssl->dyn_rec.threshold)
|
|
||||||
+ {
|
|
||||||
+ buf->end = buf->start + c->ssl->dyn_rec.size_hi;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
while (in && buf->last < buf->end && send < limit) {
|
|
||||||
if (in->buf->last_buf || in->buf->flush) {
|
|
||||||
flush = 1;
|
|
||||||
@@ -3225,6 +3261,9 @@
|
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
|
|
||||||
+ c->ssl->dyn_rec_records_sent++;
|
|
||||||
+ c->ssl->dyn_rec_last_write = ngx_current_msec;
|
|
||||||
+
|
|
||||||
if (c->ssl->saved_read_handler) {
|
|
||||||
|
|
||||||
c->read->handler = c->ssl->saved_read_handler;
|
|
||||||
diff -urN nginx-1.31.0-pristine2/src/event/ngx_event_openssl.h nginx-1.31.0-manual/src/event/ngx_event_openssl.h
|
|
||||||
--- nginx-1.31.0-pristine2/src/event/ngx_event_openssl.h 2026-05-15 13:37:51.446142384 +0000
|
|
||||||
+++ nginx-1.31.0-manual/src/event/ngx_event_openssl.h 2026-05-15 13:38:11.246599371 +0000
|
|
||||||
@@ -101,10 +101,19 @@
|
|
||||||
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
|
|
||||||
|
|
||||||
|
|
||||||
+typedef struct {
|
|
||||||
+ ngx_msec_t timeout;
|
|
||||||
+ ngx_uint_t threshold;
|
|
||||||
+ size_t size_lo;
|
|
||||||
+ size_t size_hi;
|
|
||||||
+} ngx_ssl_dyn_rec_t;
|
|
||||||
+
|
|
||||||
+
|
|
||||||
struct ngx_ssl_s {
|
|
||||||
SSL_CTX *ctx;
|
|
||||||
ngx_log_t *log;
|
|
||||||
size_t buffer_size;
|
|
||||||
+ ngx_ssl_dyn_rec_t dyn_rec;
|
|
||||||
|
|
||||||
ngx_array_t certs;
|
|
||||||
|
|
||||||
@@ -142,6 +151,10 @@
|
|
||||||
unsigned no_send_shutdown:1;
|
|
||||||
unsigned shutdown_without_free:1;
|
|
||||||
unsigned handshake_buffer_set:1;
|
|
||||||
+
|
|
||||||
+ ngx_ssl_dyn_rec_t dyn_rec;
|
|
||||||
+ ngx_msec_t dyn_rec_last_write;
|
|
||||||
+ ngx_uint_t dyn_rec_records_sent;
|
|
||||||
unsigned session_timeout_set:1;
|
|
||||||
unsigned try_early_data:1;
|
|
||||||
unsigned in_early:1;
|
|
||||||
diff -urN nginx-1.31.0-pristine2/src/http/modules/ngx_http_ssl_module.c nginx-1.31.0-manual/src/http/modules/ngx_http_ssl_module.c
|
|
||||||
--- nginx-1.31.0-pristine2/src/http/modules/ngx_http_ssl_module.c 2026-05-15 13:37:51.444851287 +0000
|
|
||||||
+++ nginx-1.31.0-manual/src/http/modules/ngx_http_ssl_module.c 2026-05-15 13:38:11.254833775 +0000
|
|
||||||
@@ -313,6 +313,41 @@
|
|
||||||
offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
+ { ngx_string("ssl_dyn_rec_enable"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_flag_slot,
|
|
||||||
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_enable),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ { ngx_string("ssl_dyn_rec_timeout"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_msec_slot,
|
|
||||||
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_timeout),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ { ngx_string("ssl_dyn_rec_size_lo"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_size_slot,
|
|
||||||
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_lo),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ { ngx_string("ssl_dyn_rec_size_hi"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_size_slot,
|
|
||||||
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_hi),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ { ngx_string("ssl_dyn_rec_threshold"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_num_slot,
|
|
||||||
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_threshold),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
ngx_null_command
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -668,6 +703,11 @@
|
|
||||||
sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
|
|
||||||
sscf->stapling = NGX_CONF_UNSET;
|
|
||||||
sscf->stapling_verify = NGX_CONF_UNSET;
|
|
||||||
+ sscf->dyn_rec_enable = NGX_CONF_UNSET;
|
|
||||||
+ sscf->dyn_rec_timeout = NGX_CONF_UNSET_MSEC;
|
|
||||||
+ sscf->dyn_rec_size_lo = NGX_CONF_UNSET_SIZE;
|
|
||||||
+ sscf->dyn_rec_size_hi = NGX_CONF_UNSET_SIZE;
|
|
||||||
+ sscf->dyn_rec_threshold = NGX_CONF_UNSET_UINT;
|
|
||||||
|
|
||||||
return sscf;
|
|
||||||
}
|
|
||||||
@@ -739,6 +779,20 @@
|
|
||||||
ngx_conf_merge_str_value(conf->stapling_responder,
|
|
||||||
prev->stapling_responder, "");
|
|
||||||
|
|
||||||
+ ngx_conf_merge_value(conf->dyn_rec_enable, prev->dyn_rec_enable, 0);
|
|
||||||
+ ngx_conf_merge_msec_value(conf->dyn_rec_timeout, prev->dyn_rec_timeout,
|
|
||||||
+ 1000);
|
|
||||||
+ /* Default sizes for the dynamic record sizes are defined to fit maximal
|
|
||||||
+ TLS + IPv6 overhead in a single TCP segment for lo and 3 segments for hi:
|
|
||||||
+ 1369 = 1500 - 40 (IP) - 20 (TCP) - 10 (Time) - 61 (Max TLS overhead) */
|
|
||||||
+ ngx_conf_merge_size_value(conf->dyn_rec_size_lo, prev->dyn_rec_size_lo,
|
|
||||||
+ 1369);
|
|
||||||
+ /* 4229 = (1500 - 40 - 20 - 10) * 3 - 61 */
|
|
||||||
+ ngx_conf_merge_size_value(conf->dyn_rec_size_hi, prev->dyn_rec_size_hi,
|
|
||||||
+ 4229);
|
|
||||||
+ ngx_conf_merge_uint_value(conf->dyn_rec_threshold, prev->dyn_rec_threshold,
|
|
||||||
+ 40);
|
|
||||||
+
|
|
||||||
conf->ssl.log = cf->log;
|
|
||||||
|
|
||||||
if (conf->certificates) {
|
|
||||||
@@ -962,6 +1016,28 @@
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (conf->dyn_rec_enable) {
|
|
||||||
+ conf->ssl.dyn_rec.timeout = conf->dyn_rec_timeout;
|
|
||||||
+ conf->ssl.dyn_rec.threshold = conf->dyn_rec_threshold;
|
|
||||||
+
|
|
||||||
+ if (conf->buffer_size > conf->dyn_rec_size_lo) {
|
|
||||||
+ conf->ssl.dyn_rec.size_lo = conf->dyn_rec_size_lo;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ conf->ssl.dyn_rec.size_lo = conf->buffer_size;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (conf->buffer_size > conf->dyn_rec_size_hi) {
|
|
||||||
+ conf->ssl.dyn_rec.size_hi = conf->dyn_rec_size_hi;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ conf->ssl.dyn_rec.size_hi = conf->buffer_size;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ conf->ssl.dyn_rec.timeout = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return NGX_CONF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -urN nginx-1.31.0-pristine2/src/http/modules/ngx_http_ssl_module.h nginx-1.31.0-manual/src/http/modules/ngx_http_ssl_module.h
|
|
||||||
--- nginx-1.31.0-pristine2/src/http/modules/ngx_http_ssl_module.h 2026-05-15 13:37:51.445106976 +0000
|
|
||||||
+++ nginx-1.31.0-manual/src/http/modules/ngx_http_ssl_module.h 2026-05-15 13:38:11.252995002 +0000
|
|
||||||
@@ -66,6 +66,12 @@
|
|
||||||
ngx_flag_t stapling_verify;
|
|
||||||
ngx_str_t stapling_file;
|
|
||||||
ngx_str_t stapling_responder;
|
|
||||||
+
|
|
||||||
+ ngx_flag_t dyn_rec_enable;
|
|
||||||
+ ngx_msec_t dyn_rec_timeout;
|
|
||||||
+ size_t dyn_rec_size_lo;
|
|
||||||
+ size_t dyn_rec_size_hi;
|
|
||||||
+ ngx_uint_t dyn_rec_threshold;
|
|
||||||
} ngx_http_ssl_srv_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
Add sd_notify() integration to nginx master process so the systemd unit can
|
|
||||||
use Type=notify. nginx mainline ships #if (NGX_HAVE_SYSTEMD) guards in nothing
|
|
||||||
of its own — every distro carries its own patch. This is ours, kept minimal.
|
|
||||||
|
|
||||||
Send:
|
|
||||||
READY=1 after workers + cache manager are spawned (master enters loop)
|
|
||||||
RELOADING=1 when reconfigure starts
|
|
||||||
READY=1 again on every exit from a reconfigure, so the unit never gets
|
|
||||||
stuck in "reloading": after a successful reconfigure, after a
|
|
||||||
binary-upgrade respawn (ngx_new_binary), AND after a FAILED
|
|
||||||
reload (ngx_init_cycle() returns NULL on a bad config — nginx
|
|
||||||
keeps the old config running, so we must report ready again or
|
|
||||||
`systemctl reload` hangs until timeout and is marked failed).
|
|
||||||
STOPPING=1 in ngx_master_process_exit
|
|
||||||
|
|
||||||
Workers and the cache manager unset NOTIFY_SOCKET in ngx_worker_process_init()
|
|
||||||
so that only the master process can ever change the unit's state via sd_notify.
|
|
||||||
|
|
||||||
The build script provides -DNGX_HAVE_SYSTEMD and -lsystemd, so this patch
|
|
||||||
doesn't touch auto/ configure scripts — only the source.
|
|
||||||
|
|
||||||
--- a/src/os/unix/ngx_process_cycle.c
|
|
||||||
+++ b/src/os/unix/ngx_process_cycle.c
|
|
||||||
@@ -11,6 +11,10 @@
|
|
||||||
#include <ngx_channel.h>
|
|
||||||
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+#include <systemd/sd-daemon.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
|
|
||||||
ngx_int_t type);
|
|
||||||
static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
|
|
||||||
@@ -136,6 +140,10 @@
|
|
||||||
sigio = 0;
|
|
||||||
live = 1;
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "READY=1\nSTATUS=nginx is ready\n");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
for ( ;; ) {
|
|
||||||
if (delay) {
|
|
||||||
if (ngx_sigalrm) {
|
|
||||||
@@ -211,12 +219,20 @@
|
|
||||||
if (ngx_reconfigure) {
|
|
||||||
ngx_reconfigure = 0;
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "RELOADING=1\nSTATUS=nginx is reloading\n");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
if (ngx_new_binary) {
|
|
||||||
ngx_start_worker_processes(cycle, ccf->worker_processes,
|
|
||||||
NGX_PROCESS_RESPAWN);
|
|
||||||
ngx_start_cache_manager_processes(cycle, 0);
|
|
||||||
ngx_noaccepting = 0;
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "READY=1\nSTATUS=nginx is ready\n");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -225,6 +241,11 @@
|
|
||||||
cycle = ngx_init_cycle(cycle);
|
|
||||||
if (cycle == NULL) {
|
|
||||||
cycle = (ngx_cycle_t *) ngx_cycle;
|
|
||||||
+
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "READY=1\nSTATUS=nginx is ready\n");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -241,6 +262,10 @@
|
|
||||||
live = 1;
|
|
||||||
ngx_signal_worker_processes(cycle,
|
|
||||||
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
|
|
||||||
+
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "READY=1\nSTATUS=nginx is ready\n");
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_restart) {
|
|
||||||
@@ -657,6 +682,10 @@
|
|
||||||
{
|
|
||||||
ngx_uint_t i;
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ sd_notify(0, "STOPPING=1\nSTATUS=nginx is stopping\n");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ngx_delete_pidfile(cycle);
|
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
|
|
||||||
@@ -765,6 +794,16 @@
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
+#if (NGX_HAVE_SYSTEMD)
|
|
||||||
+ /*
|
|
||||||
+ * only the master process talks to systemd via sd_notify(); drop the
|
|
||||||
+ * inherited notification socket so workers and the cache manager cannot
|
|
||||||
+ * change the unit's state. Done after ngx_set_environment() so it applies
|
|
||||||
+ * to the final environ regardless of any "env" directives.
|
|
||||||
+ */
|
|
||||||
+ unsetenv("NOTIFY_SOCKET");
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
|
||||||
|
|
||||||
if (worker >= 0 && ccf->priority != 0) {
|
|
||||||
@@ -1,373 +0,0 @@
|
|||||||
--- a/src/http/modules/ngx_http_static_module.c
|
|
||||||
+++ b/src/http/modules/ngx_http_static_module.c
|
|
||||||
@@ -14,6 +14,97 @@
|
|
||||||
static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
|
|
||||||
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * twiy tenant isolation
|
|
||||||
+ * ---------------------
|
|
||||||
+ * Optional, kernel-enforced confinement of static file resolution to the
|
|
||||||
+ * tenant's document root (or an explicit tenant_isolation_root). Every static
|
|
||||||
+ * open is validated with openat2(RESOLVE_BENEATH|RESOLVE_NO_MAGICLINKS) anchored
|
|
||||||
+ * at the confinement root, so a symlink, ".." or magic-link that would escape
|
|
||||||
+ * the tenant tree is refused (403) at the syscall level -- independent of config
|
|
||||||
+ * correctness and free of the TOCTOU window of disable_symlinks.
|
|
||||||
+ *
|
|
||||||
+ * Compiled in only when the build applies the tenant-isolation patch. Per-vhost
|
|
||||||
+ * default is off unless NGX_TENANT_ISOLATION_DEFAULT_ON is defined at compile
|
|
||||||
+ * time: the twiy-raweb build defines it (always-on, override with
|
|
||||||
+ * `tenant_isolation off;`); a plain build leaves it off and opt-in via
|
|
||||||
+ * `tenant_isolation on;`. Runtime is inert on kernels without openat2 -- nginx's
|
|
||||||
+ * own disable_symlinks still applies.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef NGX_TENANT_ISOLATION_DEFAULT_ON
|
|
||||||
+#define NGX_TENANT_ISOLATION_DEFAULT_ON 0
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#if defined(__linux__)
|
|
||||||
+#include <sys/syscall.h>
|
|
||||||
+#if defined(SYS_openat2)
|
|
||||||
+#define NGX_TI_OPENAT2 1
|
|
||||||
+#endif
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#if (NGX_TI_OPENAT2)
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <fcntl.h>
|
|
||||||
+#include <stdint.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <limits.h>
|
|
||||||
+#if defined(__has_include)
|
|
||||||
+# if __has_include(<linux/openat2.h>)
|
|
||||||
+# include <linux/openat2.h>
|
|
||||||
+# define NGX_TI_HAVE_OPENAT2_H 1
|
|
||||||
+# endif
|
|
||||||
+#endif
|
|
||||||
+#ifndef NGX_TI_HAVE_OPENAT2_H
|
|
||||||
+struct open_how { uint64_t flags; uint64_t mode; uint64_t resolve; };
|
|
||||||
+#endif
|
|
||||||
+#ifndef RESOLVE_BENEATH
|
|
||||||
+#define RESOLVE_BENEATH 0x08
|
|
||||||
+#endif
|
|
||||||
+#ifndef RESOLVE_NO_MAGICLINKS
|
|
||||||
+#define RESOLVE_NO_MAGICLINKS 0x02
|
|
||||||
+#endif
|
|
||||||
+#ifndef O_PATH
|
|
||||||
+#define O_PATH 010000000
|
|
||||||
+#endif
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+typedef struct {
|
|
||||||
+ ngx_flag_t tenant_isolation;
|
|
||||||
+ ngx_str_t tenant_isolation_root;
|
|
||||||
+} ngx_http_static_loc_conf_t;
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf);
|
|
||||||
+static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent,
|
|
||||||
+ void *child);
|
|
||||||
+#if (NGX_TI_OPENAT2)
|
|
||||||
+static ngx_int_t ngx_http_static_tenant_check(ngx_http_request_t *r,
|
|
||||||
+ ngx_http_static_loc_conf_t *slcf, ngx_str_t *path, size_t root);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static ngx_command_t ngx_http_static_commands[] = {
|
|
||||||
+
|
|
||||||
+ { ngx_string("tenant_isolation"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
|
||||||
+ ngx_conf_set_flag_slot,
|
|
||||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_static_loc_conf_t, tenant_isolation),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ { ngx_string("tenant_isolation_root"),
|
|
||||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
|
||||||
+ ngx_conf_set_str_slot,
|
|
||||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_http_static_loc_conf_t, tenant_isolation_root),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
+ ngx_null_command
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+
|
|
||||||
static ngx_http_module_t ngx_http_static_module_ctx = {
|
|
||||||
NULL, /* preconfiguration */
|
|
||||||
ngx_http_static_init, /* postconfiguration */
|
|
||||||
@@ -24,15 +115,15 @@
|
|
||||||
NULL, /* create server configuration */
|
|
||||||
NULL, /* merge server configuration */
|
|
||||||
|
|
||||||
- NULL, /* create location configuration */
|
|
||||||
- NULL /* merge location configuration */
|
|
||||||
+ ngx_http_static_create_loc_conf, /* create location configuration */
|
|
||||||
+ ngx_http_static_merge_loc_conf /* merge location configuration */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ngx_module_t ngx_http_static_module = {
|
|
||||||
NGX_MODULE_V1,
|
|
||||||
&ngx_http_static_module_ctx, /* module context */
|
|
||||||
- NULL, /* module directives */
|
|
||||||
+ ngx_http_static_commands, /* module directives */
|
|
||||||
NGX_HTTP_MODULE, /* module type */
|
|
||||||
NULL, /* init master */
|
|
||||||
NULL, /* init module */
|
|
||||||
@@ -87,6 +178,21 @@
|
|
||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
||||||
|
|
||||||
+#if (NGX_TI_OPENAT2)
|
|
||||||
+ {
|
|
||||||
+ ngx_http_static_loc_conf_t *slcf;
|
|
||||||
+
|
|
||||||
+ slcf = ngx_http_get_module_loc_conf(r, ngx_http_static_module);
|
|
||||||
+
|
|
||||||
+ if (slcf->tenant_isolation == 1) {
|
|
||||||
+ rc = ngx_http_static_tenant_check(r, slcf, &path, root);
|
|
||||||
+ if (rc != NGX_OK) {
|
|
||||||
+ return rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
|
||||||
|
|
||||||
of.read_ahead = clcf->read_ahead;
|
|
||||||
@@ -278,6 +384,231 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+#if (NGX_TI_OPENAT2)
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Fallback for kernels/seccomp where openat2() is unavailable: canonicalize the
|
|
||||||
+ * mapped target with realpath() (which resolves symlinks via readlink/lstat --
|
|
||||||
+ * all permitted by the default service syscall set) and confirm it stays within
|
|
||||||
+ * the canonical confinement root. Blocks escaping symlinks/".."; carries the
|
|
||||||
+ * same TOCTOU caveat as nginx's own disable_symlinks (the openat2 path is
|
|
||||||
+ * race-free and is preferred whenever the kernel permits it).
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+static ngx_int_t
|
|
||||||
+ngx_http_static_tenant_check_realpath(ngx_http_request_t *r, u_char *root_buf,
|
|
||||||
+ ngx_str_t *path)
|
|
||||||
+{
|
|
||||||
+ char real[PATH_MAX], rroot[PATH_MAX];
|
|
||||||
+ size_t rl;
|
|
||||||
+
|
|
||||||
+ if (realpath((const char *) path->data, real) == NULL) {
|
|
||||||
+ /* nonexistent / dangling / unreadable: let nginx report 404/403 */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+ if (realpath((const char *) root_buf, rroot) == NULL) {
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ rl = ngx_strlen(rroot);
|
|
||||||
+ if (ngx_strncmp(real, rroot, rl) == 0
|
|
||||||
+ && (real[rl] == '\0' || real[rl] == '/'))
|
|
||||||
+ {
|
|
||||||
+ return NGX_OK; /* canonical target is in-tree */
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
||||||
+ "tenant_isolation: blocked escape for \"%V\" "
|
|
||||||
+ "(resolves outside \"%s\")", path, rroot);
|
|
||||||
+ return NGX_HTTP_FORBIDDEN;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Validate that `path` (already mapped from the request URI) resolves to a
|
|
||||||
+ * target beneath the tenant's confinement root, using openat2() so the kernel
|
|
||||||
+ * itself rejects escapes via symlink, "..", magic-link or absolute symlink.
|
|
||||||
+ *
|
|
||||||
+ * Confinement root = tenant_isolation_root if configured, else the document
|
|
||||||
+ * root portion of `path` (its first `root` bytes). Returns NGX_OK to let nginx
|
|
||||||
+ * proceed (in-tree target, or genuinely missing file -> nginx makes the 404),
|
|
||||||
+ * NGX_HTTP_FORBIDDEN on a blocked escape. If openat2 is unavailable (old kernel
|
|
||||||
+ * or a seccomp filter that ENOSYS/EPERMs it), it latches and uses the realpath
|
|
||||||
+ * fallback for the life of the worker instead of failing open.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+static ngx_int_t
|
|
||||||
+ngx_http_static_tenant_check(ngx_http_request_t *r,
|
|
||||||
+ ngx_http_static_loc_conf_t *slcf, ngx_str_t *path, size_t root)
|
|
||||||
+{
|
|
||||||
+ int dirfd;
|
|
||||||
+ long fd;
|
|
||||||
+ char *rel;
|
|
||||||
+ u_char *root_buf;
|
|
||||||
+ ngx_str_t croot;
|
|
||||||
+ ngx_err_t err;
|
|
||||||
+ struct open_how how;
|
|
||||||
+ static ngx_uint_t openat2_unavailable = 0; /* per-worker latch */
|
|
||||||
+
|
|
||||||
+ if (slcf->tenant_isolation_root.len) {
|
|
||||||
+ croot = slcf->tenant_isolation_root;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Require '/' (or end) right after the prefix so root "/home/u1" is not
|
|
||||||
+ * treated as a parent of "/home/u10/..." (would fail open). Length checked
|
|
||||||
+ * first to keep the read in bounds; a root ending in '/' implies it.
|
|
||||||
+ */
|
|
||||||
+ if (path->len < croot.len
|
|
||||||
+ || ngx_strncmp(path->data, croot.data, croot.len) != 0
|
|
||||||
+ || (croot.data[croot.len - 1] != '/'
|
|
||||||
+ && path->data[croot.len] != '/'
|
|
||||||
+ && path->data[croot.len] != '\0'))
|
|
||||||
+ {
|
|
||||||
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
||||||
+ "tenant_isolation: \"%V\" is outside root \"%V\"",
|
|
||||||
+ path, &croot);
|
|
||||||
+ return NGX_HTTP_FORBIDDEN;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ rel = (char *) path->data + croot.len;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ if (root == 0 || root >= path->len) {
|
|
||||||
+ /* cannot determine the document root: leave it to nginx */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ croot.data = path->data;
|
|
||||||
+ croot.len = root;
|
|
||||||
+ rel = (char *) path->data + root;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while (*rel == '/') {
|
|
||||||
+ rel++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (*rel == '\0') {
|
|
||||||
+ /* request maps to the confinement root itself: nothing to confine */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ root_buf = ngx_pnalloc(r->pool, croot.len + 1);
|
|
||||||
+ if (root_buf == NULL) {
|
|
||||||
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
+ }
|
|
||||||
+ ngx_memcpy(root_buf, croot.data, croot.len);
|
|
||||||
+ root_buf[croot.len] = '\0';
|
|
||||||
+
|
|
||||||
+ if (openat2_unavailable) {
|
|
||||||
+ return ngx_http_static_tenant_check_realpath(r, root_buf, path);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dirfd = open((const char *) root_buf, O_PATH|O_DIRECTORY|O_CLOEXEC);
|
|
||||||
+ if (dirfd < 0) {
|
|
||||||
+ /* root dir missing/unsearchable: let nginx's own open report it */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ngx_memzero(&how, sizeof(how));
|
|
||||||
+ how.flags = (uint64_t) (O_PATH|O_CLOEXEC);
|
|
||||||
+ how.resolve = (uint64_t) (RESOLVE_BENEATH|RESOLVE_NO_MAGICLINKS);
|
|
||||||
+
|
|
||||||
+ fd = syscall(SYS_openat2, dirfd, rel, &how, sizeof(how));
|
|
||||||
+
|
|
||||||
+ if (fd >= 0) {
|
|
||||||
+ (void) close((int) fd);
|
|
||||||
+ (void) close(dirfd);
|
|
||||||
+ return NGX_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ err = ngx_errno;
|
|
||||||
+ (void) close(dirfd);
|
|
||||||
+
|
|
||||||
+ switch (err) {
|
|
||||||
+
|
|
||||||
+ case NGX_ENOENT:
|
|
||||||
+ case NGX_ENOTDIR:
|
|
||||||
+ case NGX_ENAMETOOLONG:
|
|
||||||
+ /* genuinely-missing target: let nginx produce its normal 404 */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+
|
|
||||||
+ case NGX_EACCES:
|
|
||||||
+ case EMFILE:
|
|
||||||
+ case ENFILE:
|
|
||||||
+ case ENOMEM:
|
|
||||||
+ case ESTALE:
|
|
||||||
+ /* Not an escape: perm / fd exhaustion / stale NFS. Let nginx's own open
|
|
||||||
+ * surface the real 403/500/503 instead of masking it as a 403. */
|
|
||||||
+ return NGX_OK;
|
|
||||||
+
|
|
||||||
+ case EXDEV: /* RESOLVE_BENEATH: resolution would escape the root */
|
|
||||||
+ case NGX_ELOOP: /* magic-link / symlink loop refused */
|
|
||||||
+ case EAGAIN: /* lost a resolution race: fail closed */
|
|
||||||
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
|
||||||
+ "tenant_isolation: blocked escape for \"%V\"", path);
|
|
||||||
+ return NGX_HTTP_FORBIDDEN;
|
|
||||||
+
|
|
||||||
+ case NGX_ENOSYS:
|
|
||||||
+ case EOPNOTSUPP:
|
|
||||||
+ case EPERM:
|
|
||||||
+ case EINVAL:
|
|
||||||
+ /* openat2 unavailable or rejecting our flags (old kernel / seccomp, e.g.
|
|
||||||
+ * RestrictSUIDSGID). Latch to the realpath fallback instead of failing
|
|
||||||
+ * open or 403-ing every request. */
|
|
||||||
+ if (!openat2_unavailable) {
|
|
||||||
+ openat2_unavailable = 1;
|
|
||||||
+ ngx_log_error(NGX_LOG_WARN, r->connection->log, err,
|
|
||||||
+ "tenant_isolation: openat2 unavailable (an old kernel, "
|
|
||||||
+ "or the unit's RestrictSUIDSGID= seccomp ENOSYSes it), "
|
|
||||||
+ "using realpath fallback -- drop RestrictSUIDSGID for "
|
|
||||||
+ "race-free enforcement");
|
|
||||||
+ }
|
|
||||||
+ return ngx_http_static_tenant_check_realpath(r, root_buf, path);
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ /* Unexpected errno: fail closed. Benign non-escape errnos are handled
|
|
||||||
+ * above, so treat anything here as a possible escape. */
|
|
||||||
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
|
||||||
+ "tenant_isolation: openat2 failed with an unexpected error "
|
|
||||||
+ "for \"%V\", denying", path);
|
|
||||||
+ return NGX_HTTP_FORBIDDEN;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void *
|
|
||||||
+ngx_http_static_create_loc_conf(ngx_conf_t *cf)
|
|
||||||
+{
|
|
||||||
+ ngx_http_static_loc_conf_t *conf;
|
|
||||||
+
|
|
||||||
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_static_loc_conf_t));
|
|
||||||
+ if (conf == NULL) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ conf->tenant_isolation = NGX_CONF_UNSET;
|
|
||||||
+
|
|
||||||
+ return conf;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static char *
|
|
||||||
+ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
||||||
+{
|
|
||||||
+ ngx_http_static_loc_conf_t *prev = parent;
|
|
||||||
+ ngx_http_static_loc_conf_t *conf = child;
|
|
||||||
+
|
|
||||||
+ ngx_conf_merge_value(conf->tenant_isolation, prev->tenant_isolation,
|
|
||||||
+ NGX_TENANT_ISOLATION_DEFAULT_ON);
|
|
||||||
+ ngx_conf_merge_str_value(conf->tenant_isolation_root,
|
|
||||||
+ prev->tenant_isolation_root, "");
|
|
||||||
+
|
|
||||||
+ return NGX_CONF_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_static_init(ngx_conf_t *cf)
|
|
||||||
{
|
|
||||||
+44
-155
@@ -1,41 +1,15 @@
|
|||||||
. ./version
|
. ./version
|
||||||
set -e
|
set -e
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
function reqs() {
|
function reqs() {
|
||||||
apt-get update -y; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y
|
apt-get update -y; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y
|
||||||
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata dialog
|
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata dialog
|
||||||
# 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 golang-go ninja-build -y
|
apt-get install libtool pkg-config make cmake automake autoconf -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-dev mercurial libpcre2-dev libc-ares-dev libre2-dev libzstd-dev libjemalloc2 libsystemd-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 libpcre3-dev mercurial libpcre2-dev libc-ares-dev libre2-dev -y
|
||||||
mkdir -p $LUA_SCRIPTS
|
mkdir -p $LUA_SCRIPTS
|
||||||
}
|
}
|
||||||
function apply_patches() {
|
|
||||||
local nginx_src="/opt/nginx-${NGINX}"
|
|
||||||
local patch_dir="${SCRIPT_DIR}/patches"
|
|
||||||
[ -f "${nginx_src}/.patches_applied" ] && return 0
|
|
||||||
|
|
||||||
apply_one() {
|
|
||||||
local toggle="$1" file="$2"
|
|
||||||
if [ "$toggle" != "1" ]; then
|
|
||||||
echo "[patch] skip $file (toggle=$toggle)"; return 0
|
|
||||||
fi
|
|
||||||
if [ ! -f "${patch_dir}/${file}" ]; then
|
|
||||||
echo "[patch] MISSING ${patch_dir}/${file}"; return 1
|
|
||||||
fi
|
|
||||||
echo "[patch] applying ${file}"
|
|
||||||
( cd "$nginx_src" && patch -p1 < "${patch_dir}/${file}" )
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_one "${APPLY_PATCH_SYSTEMD_NOTIFY:-0}" "nginx-${NGINX}-systemd-notify.patch"
|
|
||||||
apply_one "${APPLY_PATCH_DYNAMIC_TLS_RECORDS:-0}" "nginx-${NGINX}-dynamic-tls-records.patch"
|
|
||||||
apply_one "${APPLY_PATCH_HTTP2_HPACK_ENC:-0}" "nginx-${NGINX}-http2-hpack-enc.patch"
|
|
||||||
apply_one "${APPLY_PATCH_TENANT_ISOLATION:-0}" "nginx-${NGINX}-tenant-isolation.patch"
|
|
||||||
|
|
||||||
touch "${nginx_src}/.patches_applied"
|
|
||||||
}
|
|
||||||
|
|
||||||
function clean_install() {
|
function clean_install() {
|
||||||
mkdir -p /opt/mod
|
mkdir -p /opt/mod
|
||||||
|
|
||||||
@@ -44,46 +18,19 @@ function clean_install() {
|
|||||||
cd /opt/ && wget https://nginx.org/download/nginx-${NGINX}.tar.gz
|
cd /opt/ && wget https://nginx.org/download/nginx-${NGINX}.tar.gz
|
||||||
tar xf nginx-${NGINX}.tar.gz && rm -Rf nginx-${NGINX}.tar.gz
|
tar xf nginx-${NGINX}.tar.gz && rm -Rf nginx-${NGINX}.tar.gz
|
||||||
fi
|
fi
|
||||||
apply_patches
|
|
||||||
|
|
||||||
# START OF SYSTEM REQUIRED LIBS
|
# START OF SYSTEM REQUIRED LIBS
|
||||||
# ============================================================================================================
|
# ============================================================================================================
|
||||||
# AWS-LC — TLS+QUIC backend. Replaces quictls/openssl. Built standalone
|
# OPENSSL
|
||||||
# (cmake+ninja) and installed to /usr/local/aws-lc/. nginx 1.29.2+ links
|
if [ ! -d /opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} ]; then
|
||||||
# against it via -I/-L; we no longer pass --with-openssl=PATH because we
|
cd /opt/mod; wget https://github.com/quictls/openssl/archive/refs/tags/opernssl-${SYSTEM_OPENSSL}.tar.gz
|
||||||
# don't want nginx's configure to rebuild OpenSSL itself.
|
cd /opt/mod && tar xf opernssl-${SYSTEM_OPENSSL}.tar.gz; rm -Rf opernssl-${SYSTEM_OPENSSL}.tar.gz
|
||||||
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-ng, --zlib-compat mode). Drop-in libz replacement with SIMD-
|
# ZLIB
|
||||||
# accelerated DEFLATE. Installed to /usr/local/zlib-ng/. nginx links via
|
if [ ! -d /opt/mod/zlib ]; then
|
||||||
# -I/-L below (no more --with-zlib=PATH; nginx finds libz via -L+rpath).
|
cd /opt/mod && wget http://zlib.net/current/zlib.tar.gz
|
||||||
if [ ! -d /opt/mod/zlib-ng-${SYSTEM_ZLIBNG} ]; then
|
cd /opt/mod && tar xf zlib.tar.gz; rm -Rf zlib.tar.gz; mv zlib-* zlib
|
||||||
cd /opt/mod && wget https://github.com/zlib-ng/zlib-ng/archive/refs/tags/${SYSTEM_ZLIBNG}.tar.gz
|
|
||||||
cd /opt/mod && tar xf ${SYSTEM_ZLIBNG}.tar.gz; rm -Rf ${SYSTEM_ZLIBNG}.tar.gz
|
|
||||||
fi
|
|
||||||
if [ ! -f /usr/local/zlib-ng/lib/libz.so ]; then
|
|
||||||
cd /opt/mod/zlib-ng-${SYSTEM_ZLIBNG} && \
|
|
||||||
cmake -GNinja -B build \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr/local/zlib-ng \
|
|
||||||
-DZLIB_COMPAT=ON \
|
|
||||||
-DBUILD_SHARED_LIBS=ON \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release && \
|
|
||||||
cmake --build build -j`nproc` && \
|
|
||||||
cmake --install build && \
|
|
||||||
ldconfig
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SYSTEM_LUAJIT
|
# SYSTEM_LUAJIT
|
||||||
@@ -96,22 +43,20 @@ function clean_install() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SYSTEM_MODSECURITY (v3 — libmodsecurity, what ModSecurity-nginx connector needs)
|
# SYSTEM_MODSECURITY
|
||||||
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
|
||||||
# Use the official release tarball (bundles the sljit submodule needed for
|
if [ ! -d /opt/mod/pcre2-pcre2-${SYSTEM_PCRE} ]; then
|
||||||
# JIT). The /archive/refs/tags/ tarball from GitHub is a raw source snapshot
|
cd /opt/mod && wget https://github.com/PCRE2Project/pcre2/archive/refs/tags/pcre2-${SYSTEM_PCRE}.tar.gz
|
||||||
# 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
|
||||||
@@ -130,36 +75,18 @@ 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 — must stay in lockstep with NGX_MOD_LUA. lua-resty-core
|
# NGX_LUA_CORE
|
||||||
# does a strict-equality check on ngx.config.ngx_lua_version at startup,
|
if [ ! -d /opt/mod/lua-resty-core ]; then
|
||||||
# so an upstream bump on master silently breaks the build. Pinning via
|
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-core.git
|
||||||
# the tagged tarball (dir name embeds the version) means changing
|
cd /opt/mod/lua-resty-core; make install PREFIX=${LUA_SCRIPTS}
|
||||||
# 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 — same pattern, pinned to LUA_SCRIPTS_LRUCACHE.
|
# NGX_LUA_LRUCACHE
|
||||||
if [ ! -d /opt/mod/lua-resty-lrucache-${LUA_SCRIPTS_LRUCACHE} ]; then
|
if [ ! -d /opt/mod/lua-resty-lrucache ]; then
|
||||||
cd /opt/mod/; wget https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v${LUA_SCRIPTS_LRUCACHE}.tar.gz
|
cd /opt/mod/; git clone https://github.com/openresty/lua-resty-lrucache.git
|
||||||
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; make install PREFIX=${LUA_SCRIPTS}
|
||||||
cd /opt/mod/lua-resty-lrucache-${LUA_SCRIPTS_LRUCACHE} && make install PREFIX=${LUA_SCRIPTS}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# NGX_MOD_LUA_MYSQL
|
# NGX_MOD_LUA_MYSQL
|
||||||
@@ -244,50 +171,27 @@ function clean_install() {
|
|||||||
cd /opt/mod/; git clone --recurse-submodules https://github.com/wargio/naxsi.git naxsi
|
cd /opt/mod/; git clone --recurse-submodules https://github.com/wargio/naxsi.git naxsi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# zstd module from https://github.com/theraw/zstd-nginx-module (NGX_MOD_ZSTD =
|
|
||||||
# git tag). Extract with --strip-components=1 into a fixed local dir name so the
|
|
||||||
# --add-module path never depends on the archive's top folder; guard on config
|
|
||||||
# so a partial extract re-fetches.
|
|
||||||
if [ ! -f /opt/mod/zstd-nginx-module-${NGX_MOD_ZSTD}/config ]; then
|
|
||||||
cd /opt/mod/
|
|
||||||
rm -rf zstd-nginx-module-${NGX_MOD_ZSTD}
|
|
||||||
wget -O zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz \
|
|
||||||
https://github.com/theraw/zstd-nginx-module/archive/refs/tags/${NGX_MOD_ZSTD}.tar.gz
|
|
||||||
mkdir -p zstd-nginx-module-${NGX_MOD_ZSTD}
|
|
||||||
tar xf zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz \
|
|
||||||
-C zstd-nginx-module-${NGX_MOD_ZSTD} --strip-components=1
|
|
||||||
rm -Rf zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# END OF NGINX MODULES
|
# END OF NGINX MODULES
|
||||||
# ============================================================================================================
|
# ============================================================================================================
|
||||||
}
|
}
|
||||||
|
|
||||||
test_nginx() {
|
test_nginx() {
|
||||||
# Tenant-isolation directive default: ON only when the patch is applied AND
|
|
||||||
# TENANT_ISOLATION_DEFAULT_ON=1 (the twiy-raweb posture). Injected into cc-opt.
|
|
||||||
local TI_CC_OPT=""
|
|
||||||
if [ "${APPLY_PATCH_TENANT_ISOLATION:-0}" = "1" ] && [ "${TENANT_ISOLATION_DEFAULT_ON:-0}" = "1" ]; then
|
|
||||||
TI_CC_OPT="-DNGX_TENANT_ISOLATION_DEFAULT_ON=1"
|
|
||||||
fi
|
|
||||||
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
||||||
--user=nginx \
|
--user=nginx \
|
||||||
--group=nginx \
|
--group=nginx \
|
||||||
--sbin-path=/usr/sbin/nginx \
|
--sbin-path=/usr/sbin/nginx \
|
||||||
--conf-path=/nginx/nginx.conf \
|
--conf-path=/nginx/nginx.conf \
|
||||||
--modules-path=/nginx/modules \
|
--modules-path=/nginx/modules \
|
||||||
--pid-path=/run/nginx.pid \
|
--pid-path=/var/run/nginx.pid \
|
||||||
--lock-path=/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 \
|
||||||
--http-client-body-temp-path=/run/nginx/temp/client_body \
|
--with-openssl=/opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} \
|
||||||
--http-proxy-temp-path=/run/nginx/temp/proxy \
|
--with-openssl-opt=enable-tls1_3 \
|
||||||
--http-fastcgi-temp-path=/run/nginx/temp/fastcgi \
|
|
||||||
--http-uwsgi-temp-path=/run/nginx/temp/uwsgi \
|
|
||||||
--http-scgi-temp-path=/run/nginx/temp/scgi \
|
|
||||||
--with-pcre \
|
--with-pcre \
|
||||||
--with-pcre-jit \
|
--with-pcre-jit \
|
||||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
--with-pcre=/opt/mod/pcre2-pcre2-${SYSTEM_PCRE} \
|
||||||
|
--with-zlib=/opt/mod/zlib \
|
||||||
--with-threads \
|
--with-threads \
|
||||||
--with-file-aio \
|
--with-file-aio \
|
||||||
--with-http_ssl_module \
|
--with-http_ssl_module \
|
||||||
@@ -326,37 +230,28 @@ test_nginx() {
|
|||||||
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
||||||
--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/zstd-nginx-module-${NGX_MOD_ZSTD} \
|
|
||||||
--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 -I/usr/local/aws-lc/include -I/usr/local/zlib-ng/include -DNGX_HAVE_SYSTEMD ${TI_CC_OPT}" \
|
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \
|
||||||
--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 -L/usr/local/zlib-ng/lib -lz -Wl,-rpath,/usr/local/zlib-ng/lib -lsystemd"
|
--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"
|
||||||
make clean
|
make clean
|
||||||
}
|
}
|
||||||
function build() {
|
function build() {
|
||||||
# Tenant-isolation directive default: ON only when the patch is applied AND
|
|
||||||
# TENANT_ISOLATION_DEFAULT_ON=1 (the twiy-raweb posture). Injected into cc-opt.
|
|
||||||
local TI_CC_OPT=""
|
|
||||||
if [ "${APPLY_PATCH_TENANT_ISOLATION:-0}" = "1" ] && [ "${TENANT_ISOLATION_DEFAULT_ON:-0}" = "1" ]; then
|
|
||||||
TI_CC_OPT="-DNGX_TENANT_ISOLATION_DEFAULT_ON=1"
|
|
||||||
fi
|
|
||||||
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
||||||
--user=nginx \
|
--user=nginx \
|
||||||
--group=nginx \
|
--group=nginx \
|
||||||
--sbin-path=/usr/sbin/nginx \
|
--sbin-path=/usr/sbin/nginx \
|
||||||
--conf-path=/nginx/nginx.conf \
|
--conf-path=/nginx/nginx.conf \
|
||||||
--modules-path=/nginx/modules \
|
--modules-path=/nginx/modules \
|
||||||
--pid-path=/run/nginx.pid \
|
--pid-path=/var/run/nginx.pid \
|
||||||
--lock-path=/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 \
|
||||||
--http-client-body-temp-path=/run/nginx/temp/client_body \
|
--with-openssl=/opt/mod/openssl-opernssl-${SYSTEM_OPENSSL} \
|
||||||
--http-proxy-temp-path=/run/nginx/temp/proxy \
|
--with-openssl-opt=enable-tls1_3 \
|
||||||
--http-fastcgi-temp-path=/run/nginx/temp/fastcgi \
|
|
||||||
--http-uwsgi-temp-path=/run/nginx/temp/uwsgi \
|
|
||||||
--http-scgi-temp-path=/run/nginx/temp/scgi \
|
|
||||||
--with-pcre \
|
--with-pcre \
|
||||||
--with-pcre-jit \
|
--with-pcre-jit \
|
||||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
--with-pcre=/opt/mod/pcre2-pcre2-${SYSTEM_PCRE} \
|
||||||
|
--with-zlib=/opt/mod/zlib \
|
||||||
--with-threads \
|
--with-threads \
|
||||||
--with-file-aio \
|
--with-file-aio \
|
||||||
--with-http_ssl_module \
|
--with-http_ssl_module \
|
||||||
@@ -395,16 +290,10 @@ function build() {
|
|||||||
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
||||||
--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/zstd-nginx-module-${NGX_MOD_ZSTD} \
|
|
||||||
--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 -I/usr/local/aws-lc/include -I/usr/local/zlib-ng/include -DNGX_HAVE_SYSTEMD ${TI_CC_OPT}" \
|
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \
|
||||||
--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 -L/usr/local/zlib-ng/lib -lz -Wl,-rpath,/usr/local/zlib-ng/lib -lsystemd"
|
--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"
|
||||||
# NOTE: kept as separate statements (not `make && make install && make clean`)
|
make -j`nproc` && 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() {
|
||||||
@@ -422,14 +311,14 @@ function post_build() {
|
|||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/nginx/live/default > /nginx/live/default
|
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/nginx/live/default > /nginx/live/default
|
||||||
mkdir -p /hostdata/default/public_html/ && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/index.html > /hostdata/default/public_html/index.html
|
mkdir -p /hostdata/default/public_html/ && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/index.html > /hostdata/default/public_html/index.html
|
||||||
mkdir -p /hostdata/default/public_html/cdn/modsec && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/aes.min.js > /hostdata/default/public_html/cdn/modsec/aes.min.js
|
mkdir -p /hostdata/default/public_html/cdn/modsec && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/aes.min.js > /hostdata/default/public_html/cdn/modsec/aes.min.js
|
||||||
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
install -m 0644 "${SRC_DIR}/static/Raccoon/nginx.service" /etc/systemd/system/nginx.service
|
|
||||||
if [ -f "/run/.containerenv" ] || [ -f "/.dockerenv" ] || [ -f "/home/runner/.dockerenv" ]; then
|
if [ -f "/run/.containerenv" ] || [ -f "/.dockerenv" ] || [ -f "/home/runner/.dockerenv" ]; then
|
||||||
echo "Skipping systemctl commands on GitHub runner"
|
echo "Skipping systemctl commands on GitHub runner"
|
||||||
mkdir -p /etc/systemd/system/
|
mkdir -p /etc/systemd/system/
|
||||||
|
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Jammy/nginx.service > /etc/systemd/system/nginx.service
|
||||||
else
|
else
|
||||||
|
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Jammy/nginx.service > /etc/systemd/system/nginx.service
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl restart nginx.service
|
systemctl start nginx.service
|
||||||
systemctl enable nginx.service
|
systemctl enable nginx.service
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
-462
@@ -1,462 +0,0 @@
|
|||||||
. ./version
|
|
||||||
set -e
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
function reqs() {
|
|
||||||
apt-get update -y; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y
|
|
||||||
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata dialog
|
|
||||||
# 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 iptables ipset
|
|
||||||
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 mercurial libpcre2-dev libc-ares-dev libre2-dev libzstd-dev libjemalloc2 libsystemd-dev -y
|
|
||||||
mkdir -p $LUA_SCRIPTS
|
|
||||||
}
|
|
||||||
function apply_patches() {
|
|
||||||
local nginx_src="/opt/nginx-${NGINX}"
|
|
||||||
local patch_dir="${SCRIPT_DIR}/patches"
|
|
||||||
[ -f "${nginx_src}/.patches_applied" ] && return 0
|
|
||||||
|
|
||||||
apply_one() {
|
|
||||||
local toggle="$1" file="$2"
|
|
||||||
if [ "$toggle" != "1" ]; then
|
|
||||||
echo "[patch] skip $file (toggle=$toggle)"; return 0
|
|
||||||
fi
|
|
||||||
if [ ! -f "${patch_dir}/${file}" ]; then
|
|
||||||
echo "[patch] MISSING ${patch_dir}/${file}"; return 1
|
|
||||||
fi
|
|
||||||
echo "[patch] applying ${file}"
|
|
||||||
( cd "$nginx_src" && patch -p1 < "${patch_dir}/${file}" )
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_one "${APPLY_PATCH_SYSTEMD_NOTIFY:-0}" "nginx-${NGINX}-systemd-notify.patch"
|
|
||||||
apply_one "${APPLY_PATCH_DYNAMIC_TLS_RECORDS:-0}" "nginx-${NGINX}-dynamic-tls-records.patch"
|
|
||||||
apply_one "${APPLY_PATCH_HTTP2_HPACK_ENC:-0}" "nginx-${NGINX}-http2-hpack-enc.patch"
|
|
||||||
apply_one "${APPLY_PATCH_TENANT_ISOLATION:-0}" "nginx-${NGINX}-tenant-isolation.patch"
|
|
||||||
|
|
||||||
touch "${nginx_src}/.patches_applied"
|
|
||||||
}
|
|
||||||
|
|
||||||
function clean_install() {
|
|
||||||
mkdir -p /opt/mod
|
|
||||||
|
|
||||||
# Nginx
|
|
||||||
if [ ! -d /opt/nginx-${NGINX} ]; then
|
|
||||||
cd /opt/ && wget https://nginx.org/download/nginx-${NGINX}.tar.gz
|
|
||||||
tar xf nginx-${NGINX}.tar.gz && rm -Rf nginx-${NGINX}.tar.gz
|
|
||||||
fi
|
|
||||||
apply_patches
|
|
||||||
|
|
||||||
# START OF SYSTEM REQUIRED LIBS
|
|
||||||
# ============================================================================================================
|
|
||||||
# AWS-LC — TLS+QUIC backend. Replaces quictls/openssl. Built standalone
|
|
||||||
# (cmake+ninja) and installed to /usr/local/aws-lc/. nginx 1.29.2+ links
|
|
||||||
# against it via -I/-L; we no longer pass --with-openssl=PATH because we
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# ZLIB (zlib-ng, --zlib-compat mode). Drop-in libz replacement with SIMD-
|
|
||||||
# accelerated DEFLATE. Installed to /usr/local/zlib-ng/. nginx links via
|
|
||||||
# -I/-L below (no more --with-zlib=PATH; nginx finds libz via -L+rpath).
|
|
||||||
if [ ! -d /opt/mod/zlib-ng-${SYSTEM_ZLIBNG} ]; then
|
|
||||||
cd /opt/mod && wget https://github.com/zlib-ng/zlib-ng/archive/refs/tags/${SYSTEM_ZLIBNG}.tar.gz
|
|
||||||
cd /opt/mod && tar xf ${SYSTEM_ZLIBNG}.tar.gz; rm -Rf ${SYSTEM_ZLIBNG}.tar.gz
|
|
||||||
fi
|
|
||||||
if [ ! -f /usr/local/zlib-ng/lib/libz.so ]; then
|
|
||||||
cd /opt/mod/zlib-ng-${SYSTEM_ZLIBNG} && \
|
|
||||||
cmake -GNinja -B build \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr/local/zlib-ng \
|
|
||||||
-DZLIB_COMPAT=ON \
|
|
||||||
-DBUILD_SHARED_LIBS=ON \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release && \
|
|
||||||
cmake --build build -j`nproc` && \
|
|
||||||
cmake --install build && \
|
|
||||||
ldconfig
|
|
||||||
fi
|
|
||||||
|
|
||||||
# SYSTEM_LUAJIT
|
|
||||||
if [ ! -d /opt/mod/luajit2-${SYSTEM_LUAJIT} ]; then
|
|
||||||
cd /opt/mod && wget https://github.com/openresty/luajit2/archive/refs/tags/v${SYSTEM_LUAJIT}.tar.gz
|
|
||||||
cd /opt/mod && tar xf v${SYSTEM_LUAJIT}.tar.gz && rm -Rf v${SYSTEM_LUAJIT}.tar.gz
|
|
||||||
if [ ! -d /usr/local/LuaJIT/include/luajit-2.1 ]; then
|
|
||||||
cd /opt/mod/luajit2-${SYSTEM_LUAJIT}/ && make clean && make install PREFIX=/usr/local/LuaJIT && ldconfig
|
|
||||||
# apt-get -y install liblua5.1-0-dev; apt-get -y install luarocks; luarocks install lua-resty-core
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# SYSTEM_MODSECURITY (v3 — libmodsecurity, what ModSecurity-nginx connector needs)
|
|
||||||
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 && tar xf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz; rm -Rf modsecurity-v${SYSTEM_MODSECURITY}.tar.gz
|
|
||||||
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
|
|
||||||
|
|
||||||
# SYSTEM_PCRE
|
|
||||||
# Use the official release tarball (bundles the sljit submodule needed for
|
|
||||||
# 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
|
|
||||||
fi
|
|
||||||
|
|
||||||
# LibInjection
|
|
||||||
if [ ! -d /opt/mod/libinjection ]; then
|
|
||||||
cd /opt/mod && git clone https://github.com/libinjection/libinjection.git
|
|
||||||
cd /opt/mod/libinjection && ./autogen.sh && ./configure && make -j`nproc` && make install
|
|
||||||
fi
|
|
||||||
# END OF SYSTEM REQUIRED LIBS
|
|
||||||
# ============================================================================================================
|
|
||||||
|
|
||||||
|
|
||||||
# START OF NGINX MODULES
|
|
||||||
# ============================================================================================================
|
|
||||||
# NGX_MOD_LUA
|
|
||||||
if [ ! -d /opt/mod/lua-nginx-module-${NGX_MOD_LUA} ]; then
|
|
||||||
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
|
|
||||||
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
|
|
||||||
|
|
||||||
# NGX_LUA_CORE — must stay in lockstep with NGX_MOD_LUA. lua-resty-core
|
|
||||||
# does a strict-equality check on ngx.config.ngx_lua_version at startup,
|
|
||||||
# so an upstream bump on master silently breaks the build. Pinning via
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# NGX_LUA_LRUCACHE — same pattern, pinned to LUA_SCRIPTS_LRUCACHE.
|
|
||||||
if [ ! -d /opt/mod/lua-resty-lrucache-${LUA_SCRIPTS_LRUCACHE} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v${LUA_SCRIPTS_LRUCACHE}.tar.gz
|
|
||||||
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
|
|
||||||
|
|
||||||
# NGX_MOD_LUA_MYSQL
|
|
||||||
if [ ! -d /opt/mod/lua-resty-mysql-${NGX_MOD_LUA_MYSQL} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/lua-resty-mysql/archive/refs/tags/v${NGX_MOD_LUA_MYSQL}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_LUA_MYSQL}.tar.gz; rm -Rf v${NGX_MOD_LUA_MYSQL}.tar.gz
|
|
||||||
cd /opt/mod/lua-resty-mysql-${NGX_MOD_LUA_MYSQL} && make install PREFIX=${LUA_SCRIPTS}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_LUA_SRCACHE
|
|
||||||
if [ ! -d /opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/srcache-nginx-module/archive/refs/tags/v${NGX_MOD_LUA_SRCACHE}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_LUA_SRCACHE}.tar.gz; rm -Rf v${NGX_MOD_LUA_SRCACHE}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_LUA_REDIS2
|
|
||||||
if [ ! -d /opt/mod/redis2-nginx-module ]; then
|
|
||||||
cd /opt/mod/; git clone --recursive https://github.com/openresty/redis2-nginx-module.git
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_LUA_LOCK 0.09
|
|
||||||
if [ ! -d /opt/mod/lua-resty-lock-${NGX_MOD_LUA_LOCK} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/lua-resty-lock/archive/refs/tags/v${NGX_MOD_LUA_LOCK}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_LUA_LOCK}.tar.gz; rm -Rf v${NGX_MOD_LUA_LOCK}.tar.gz
|
|
||||||
cd /opt/mod/lua-resty-lock-${NGX_MOD_LUA_LOCK} && make install PREFIX=${LUA_SCRIPTS}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_LUA_CACHE
|
|
||||||
if [ ! -d /opt/mod/lua-resty-cache ]; then
|
|
||||||
cd /opt/mod/; git clone --branch feature-srcache --recursive https://github.com/lloydzhou/lua-resty-cache
|
|
||||||
cd /opt/mod/lua-resty-cache && make install PREFIX=${LUA_SCRIPTS}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_DEVELKIT
|
|
||||||
if [ ! -d /opt/mod/ngx_devel_kit-${NGX_MOD_DEVELKIT} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v${NGX_MOD_DEVELKIT}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_DEVELKIT}.tar.gz; rm -Rf v${NGX_MOD_DEVELKIT}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_GEOIP2
|
|
||||||
if [ ! -d /opt/mod/ngx_http_geoip2_module-${NGX_MOD_GEOIP2} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/leev/ngx_http_geoip2_module/archive/refs/tags/${NGX_MOD_GEOIP2}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf ${NGX_MOD_GEOIP2}.tar.gz; rm -Rf ${NGX_MOD_GEOIP2}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_MODSECURITY
|
|
||||||
if [ ! -d /opt/mod/ModSecurity-nginx-${NGX_MOD_MODSECURITY} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/SpiderLabs/ModSecurity-nginx/archive/refs/tags/v${NGX_MOD_MODSECURITY}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_MODSECURITY}.tar.gz; rm -Rf v${NGX_MOD_MODSECURITY}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_HTTPFLV
|
|
||||||
if [ ! -d /opt/mod/nginx-http-flv-module-${NGX_MOD_HTTPFLV} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/winshining/nginx-http-flv-module/archive/refs/tags/v${NGX_MOD_HTTPFLV}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_HTTPFLV}.tar.gz; rm -Rf v${NGX_MOD_HTTPFLV}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_HEADERS_MORE
|
|
||||||
if [ ! -d /opt/mod/headers-more-nginx-module-${NGX_MOD_HEADERS_MORE} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/v${NGX_MOD_HEADERS_MORE}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_HEADERS_MORE}.tar.gz; rm -Rf v${NGX_MOD_HEADERS_MORE}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NGX_MOD_SETMISC
|
|
||||||
if [ ! -d /opt/mod/set-misc-nginx-module-${NGX_MOD_SETMISC} ]; then
|
|
||||||
cd /opt/mod/; wget https://github.com/openresty/set-misc-nginx-module/archive/refs/tags/v${NGX_MOD_SETMISC}.tar.gz
|
|
||||||
cd /opt/mod/; tar xf v${NGX_MOD_SETMISC}.tar.gz; rm -Rf v${NGX_MOD_SETMISC}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Testcookie
|
|
||||||
if [ ! -d /opt/mod/testcookie ]; then
|
|
||||||
cd /opt/mod/; git clone https://github.com/kyprizel/testcookie-nginx-module.git testcookie
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Brotli
|
|
||||||
if [ ! -d /opt/mod/ngx_brotli ]; then
|
|
||||||
cd /opt/mod/; git clone https://github.com/google/ngx_brotli.git ngx_brotli; cd /opt/mod/ngx_brotli && git submodule update --init
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Naxsi
|
|
||||||
if [ ! -d /opt/mod/naxsi ]; then
|
|
||||||
cd /opt/mod/; git clone --recurse-submodules https://github.com/wargio/naxsi.git naxsi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# zstd module from https://github.com/theraw/zstd-nginx-module (NGX_MOD_ZSTD =
|
|
||||||
# git tag). Extract with --strip-components=1 into a fixed local dir name so the
|
|
||||||
# --add-module path never depends on the archive's top folder; guard on config
|
|
||||||
# so a partial extract re-fetches.
|
|
||||||
if [ ! -f /opt/mod/zstd-nginx-module-${NGX_MOD_ZSTD}/config ]; then
|
|
||||||
cd /opt/mod/
|
|
||||||
rm -rf zstd-nginx-module-${NGX_MOD_ZSTD}
|
|
||||||
wget -O zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz \
|
|
||||||
https://github.com/theraw/zstd-nginx-module/archive/refs/tags/${NGX_MOD_ZSTD}.tar.gz
|
|
||||||
mkdir -p zstd-nginx-module-${NGX_MOD_ZSTD}
|
|
||||||
tar xf zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz \
|
|
||||||
-C zstd-nginx-module-${NGX_MOD_ZSTD} --strip-components=1
|
|
||||||
rm -Rf zstd-nginx-module-${NGX_MOD_ZSTD}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
# END OF NGINX MODULES
|
|
||||||
# ============================================================================================================
|
|
||||||
}
|
|
||||||
|
|
||||||
test_nginx() {
|
|
||||||
# Tenant-isolation directive default: ON only when the patch is applied AND
|
|
||||||
# TENANT_ISOLATION_DEFAULT_ON=1 (the twiy-raweb posture). Injected into cc-opt.
|
|
||||||
local TI_CC_OPT=""
|
|
||||||
if [ "${APPLY_PATCH_TENANT_ISOLATION:-0}" = "1" ] && [ "${TENANT_ISOLATION_DEFAULT_ON:-0}" = "1" ]; then
|
|
||||||
TI_CC_OPT="-DNGX_TENANT_ISOLATION_DEFAULT_ON=1"
|
|
||||||
fi
|
|
||||||
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
|
||||||
--user=nginx \
|
|
||||||
--group=nginx \
|
|
||||||
--sbin-path=/usr/sbin/nginx \
|
|
||||||
--conf-path=/nginx/nginx.conf \
|
|
||||||
--modules-path=/nginx/modules \
|
|
||||||
--pid-path=/run/nginx.pid \
|
|
||||||
--lock-path=/run/nginx.lock \
|
|
||||||
--error-log-path=/var/log/nginx/error.log \
|
|
||||||
--http-log-path=/var/log/nginx/access.log \
|
|
||||||
--http-client-body-temp-path=/run/nginx/temp/client_body \
|
|
||||||
--http-proxy-temp-path=/run/nginx/temp/proxy \
|
|
||||||
--http-fastcgi-temp-path=/run/nginx/temp/fastcgi \
|
|
||||||
--http-uwsgi-temp-path=/run/nginx/temp/uwsgi \
|
|
||||||
--http-scgi-temp-path=/run/nginx/temp/scgi \
|
|
||||||
--with-pcre \
|
|
||||||
--with-pcre-jit \
|
|
||||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
|
||||||
--with-threads \
|
|
||||||
--with-file-aio \
|
|
||||||
--with-http_ssl_module \
|
|
||||||
--with-http_v2_module \
|
|
||||||
--with-http_v3_module \
|
|
||||||
--with-http_realip_module \
|
|
||||||
--with-http_addition_module \
|
|
||||||
--with-http_xslt_module \
|
|
||||||
--with-http_image_filter_module \
|
|
||||||
--with-http_geoip_module \
|
|
||||||
--with-http_sub_module \
|
|
||||||
--with-http_dav_module \
|
|
||||||
--with-http_flv_module \
|
|
||||||
--with-http_mp4_module \
|
|
||||||
--with-http_gunzip_module \
|
|
||||||
--with-http_gzip_static_module \
|
|
||||||
--with-http_auth_request_module \
|
|
||||||
--with-http_random_index_module \
|
|
||||||
--with-http_secure_link_module \
|
|
||||||
--with-http_slice_module \
|
|
||||||
--with-http_stub_status_module \
|
|
||||||
--with-mail \
|
|
||||||
--with-mail_ssl_module \
|
|
||||||
--with-stream \
|
|
||||||
--with-stream_ssl_module \
|
|
||||||
--with-stream_realip_module \
|
|
||||||
--with-stream_geoip_module \
|
|
||||||
--add-module=/opt/mod/ngx_devel_kit-${NGX_MOD_DEVELKIT} \
|
|
||||||
--add-module=/opt/mod/set-misc-nginx-module-${NGX_MOD_SETMISC} \
|
|
||||||
--add-module=/opt/mod/ngx_http_geoip2_module-${NGX_MOD_GEOIP2} \
|
|
||||||
--add-module=/opt/mod/headers-more-nginx-module-${NGX_MOD_HEADERS_MORE} \
|
|
||||||
--add-module=/opt/mod/lua-nginx-module-${NGX_MOD_LUA} \
|
|
||||||
--add-module=/opt/mod/ModSecurity-nginx-${NGX_MOD_MODSECURITY} \
|
|
||||||
--add-module=/opt/mod/naxsi/naxsi_src \
|
|
||||||
--add-module=/opt/mod/nginx-http-flv-module-${NGX_MOD_HTTPFLV} \
|
|
||||||
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
|
||||||
--add-module=/opt/mod/redis2-nginx-module \
|
|
||||||
--add-module=/opt/mod/ngx_brotli \
|
|
||||||
--add-module=/opt/mod/zstd-nginx-module-${NGX_MOD_ZSTD} \
|
|
||||||
--add-module=/opt/mod/testcookie \
|
|
||||||
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/aws-lc/include -I/usr/local/zlib-ng/include -DNGX_HAVE_SYSTEMD ${TI_CC_OPT}" \
|
|
||||||
--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 -L/usr/local/zlib-ng/lib -lz -Wl,-rpath,/usr/local/zlib-ng/lib -lsystemd"
|
|
||||||
make clean
|
|
||||||
}
|
|
||||||
function build() {
|
|
||||||
# Tenant-isolation directive default: ON only when the patch is applied AND
|
|
||||||
# TENANT_ISOLATION_DEFAULT_ON=1 (the twiy-raweb posture). Injected into cc-opt.
|
|
||||||
local TI_CC_OPT=""
|
|
||||||
if [ "${APPLY_PATCH_TENANT_ISOLATION:-0}" = "1" ] && [ "${TENANT_ISOLATION_DEFAULT_ON:-0}" = "1" ]; then
|
|
||||||
TI_CC_OPT="-DNGX_TENANT_ISOLATION_DEFAULT_ON=1"
|
|
||||||
fi
|
|
||||||
cd /opt/nginx-${NGINX} && LUAJIT_LIB="/usr/local/LuaJIT/lib" LUAJIT_INC="/usr/local/LuaJIT/include/luajit-2.1/" CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --with-compat \
|
|
||||||
--user=nginx \
|
|
||||||
--group=nginx \
|
|
||||||
--sbin-path=/usr/sbin/nginx \
|
|
||||||
--conf-path=/nginx/nginx.conf \
|
|
||||||
--modules-path=/nginx/modules \
|
|
||||||
--pid-path=/run/nginx.pid \
|
|
||||||
--lock-path=/run/nginx.lock \
|
|
||||||
--error-log-path=/var/log/nginx/error.log \
|
|
||||||
--http-log-path=/var/log/nginx/access.log \
|
|
||||||
--http-client-body-temp-path=/run/nginx/temp/client_body \
|
|
||||||
--http-proxy-temp-path=/run/nginx/temp/proxy \
|
|
||||||
--http-fastcgi-temp-path=/run/nginx/temp/fastcgi \
|
|
||||||
--http-uwsgi-temp-path=/run/nginx/temp/uwsgi \
|
|
||||||
--http-scgi-temp-path=/run/nginx/temp/scgi \
|
|
||||||
--with-pcre \
|
|
||||||
--with-pcre-jit \
|
|
||||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
|
||||||
--with-threads \
|
|
||||||
--with-file-aio \
|
|
||||||
--with-http_ssl_module \
|
|
||||||
--with-http_v2_module \
|
|
||||||
--with-http_v3_module \
|
|
||||||
--with-http_realip_module \
|
|
||||||
--with-http_addition_module \
|
|
||||||
--with-http_xslt_module \
|
|
||||||
--with-http_image_filter_module \
|
|
||||||
--with-http_geoip_module \
|
|
||||||
--with-http_sub_module \
|
|
||||||
--with-http_dav_module \
|
|
||||||
--with-http_flv_module \
|
|
||||||
--with-http_mp4_module \
|
|
||||||
--with-http_gunzip_module \
|
|
||||||
--with-http_gzip_static_module \
|
|
||||||
--with-http_auth_request_module \
|
|
||||||
--with-http_random_index_module \
|
|
||||||
--with-http_secure_link_module \
|
|
||||||
--with-http_slice_module \
|
|
||||||
--with-http_stub_status_module \
|
|
||||||
--with-mail \
|
|
||||||
--with-mail_ssl_module \
|
|
||||||
--with-stream \
|
|
||||||
--with-stream_ssl_module \
|
|
||||||
--with-stream_realip_module \
|
|
||||||
--with-stream_geoip_module \
|
|
||||||
--add-module=/opt/mod/ngx_devel_kit-${NGX_MOD_DEVELKIT} \
|
|
||||||
--add-module=/opt/mod/set-misc-nginx-module-${NGX_MOD_SETMISC} \
|
|
||||||
--add-module=/opt/mod/ngx_http_geoip2_module-${NGX_MOD_GEOIP2} \
|
|
||||||
--add-module=/opt/mod/headers-more-nginx-module-${NGX_MOD_HEADERS_MORE} \
|
|
||||||
--add-module=/opt/mod/ModSecurity-nginx-${NGX_MOD_MODSECURITY} \
|
|
||||||
--add-module=/opt/mod/lua-nginx-module-${NGX_MOD_LUA} \
|
|
||||||
--add-module=/opt/mod/naxsi/naxsi_src \
|
|
||||||
--add-module=/opt/mod/nginx-http-flv-module-${NGX_MOD_HTTPFLV} \
|
|
||||||
--add-module=/opt/mod/srcache-nginx-module-${NGX_MOD_LUA_SRCACHE} \
|
|
||||||
--add-module=/opt/mod/redis2-nginx-module \
|
|
||||||
--add-module=/opt/mod/ngx_brotli \
|
|
||||||
--add-module=/opt/mod/zstd-nginx-module-${NGX_MOD_ZSTD} \
|
|
||||||
--add-module=/opt/mod/testcookie \
|
|
||||||
--with-cc-opt="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/aws-lc/include -I/usr/local/zlib-ng/include -DNGX_HAVE_SYSTEMD ${TI_CC_OPT}" \
|
|
||||||
--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 -L/usr/local/zlib-ng/lib -lz -Wl,-rpath,/usr/local/zlib-ng/lib -lsystemd"
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
function post_build() {
|
|
||||||
useradd nginx; unset NGINX; rm -rf /nginx/*.default;
|
|
||||||
mkdir -p /nginx/live
|
|
||||||
mkdir -p /nginx/conf.d
|
|
||||||
mkdir -p /nginx/config
|
|
||||||
mkdir -p /var/log/nginx
|
|
||||||
mkdir -p /nginx/modsec; curl -s https://raw.githubusercontent.com/nbs-system/naxsi/master/naxsi_config/naxsi_core.rules > /nginx/modsec/naxi.core
|
|
||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/l7.conf > /nginx/modsec/l7.conf
|
|
||||||
curl -s https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended > /nginx/modsec/modsecurity.conf
|
|
||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/tester.conf > /nginx/modsec/tester.conf
|
|
||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/unicode.mapping > /nginx/modsec/unicode.mapping
|
|
||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/nginx/nginx.conf > /nginx/nginx.conf
|
|
||||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/nginx/live/default > /nginx/live/default
|
|
||||||
mkdir -p /hostdata/default/public_html/ && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/index.html > /hostdata/default/public_html/index.html
|
|
||||||
mkdir -p /hostdata/default/public_html/cdn/modsec && curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/modsec/aes.min.js > /hostdata/default/public_html/cdn/modsec/aes.min.js
|
|
||||||
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
install -m 0644 "${SRC_DIR}/static/Trixie/nginx.service" /etc/systemd/system/nginx.service
|
|
||||||
if [ -f "/run/.containerenv" ] || [ -f "/.dockerenv" ] || [ -f "/home/runner/.dockerenv" ]; then
|
|
||||||
echo "Skipping systemctl commands on GitHub runner"
|
|
||||||
mkdir -p /etc/systemd/system/
|
|
||||||
else
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart nginx.service
|
|
||||||
systemctl enable nginx.service
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handling command-line arguments
|
|
||||||
case "$1" in
|
|
||||||
new)
|
|
||||||
reqs
|
|
||||||
clean_install
|
|
||||||
;;
|
|
||||||
test)
|
|
||||||
test_nginx
|
|
||||||
;;
|
|
||||||
build)
|
|
||||||
build
|
|
||||||
;;
|
|
||||||
postfix)
|
|
||||||
post_build
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option: $1"
|
|
||||||
echo "Usage: $0 {new|test|build|postfix}"
|
|
||||||
echo ""
|
|
||||||
echo " new: will download all modules & nginx (if you change a version from file, simply rerun this to download that)"
|
|
||||||
echo " test: Test nginx configuration"
|
|
||||||
echo " build: Build nginx, or Rebuild (mods/configs will not be redownloaded this will only build)"
|
|
||||||
echo " postfix: After first installation, run this to download nginx configs (it will replace nginx.conf if there already is one)"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Nginx]
|
||||||
|
Description=A high performance web server and a reverse proxy server
|
||||||
|
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
PIDFile=/var/run/nginx.pid
|
||||||
|
ExecStartPre=/usr/sbin/nginx -t
|
||||||
|
ExecStart=/usr/sbin/nginx
|
||||||
|
ExecReload=/usr/sbin/nginx -s reload
|
||||||
|
ExecStop=/bin/kill -s QUIT $MAINPID
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=A high performance web server and a reverse proxy server
|
||||||
|
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
PIDFile=/var/run/nginx.pid
|
||||||
|
ExecStartPre=/usr/sbin/nginx -t
|
||||||
|
ExecStart=/usr/sbin/nginx
|
||||||
|
ExecReload=/usr/sbin/nginx -s reload
|
||||||
|
ExecStop=/bin/kill -s QUIT $MAINPID
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=A high performance web server and a reverse proxy server (twiy)
|
|
||||||
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
PIDFile=/run/nginx.pid
|
|
||||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
|
||||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /run/nginx/temp /run/nginx/temp/client_body /run/nginx/temp/proxy /run/nginx/temp/fastcgi /run/nginx/temp/uwsgi /run/nginx/temp/scgi /var/log/nginx
|
|
||||||
ExecStartPre=/usr/sbin/nginx -t
|
|
||||||
ExecStart=/usr/sbin/nginx -c /nginx/nginx.conf
|
|
||||||
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /run/nginx.pid)"
|
|
||||||
ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|
||||||
TimeoutStartSec=10
|
|
||||||
LimitNOFILE=65535
|
|
||||||
|
|
||||||
# === hardening: deny-everything by default, allowlist via bind mounts ===
|
|
||||||
# TemporaryFileSystem=/ replaces the visible filesystem with an empty tmpfs.
|
|
||||||
# Everything not bind-mounted below is invisible to nginx workers — even
|
|
||||||
# read access. Compromise of a worker can no longer enumerate /etc/passwd,
|
|
||||||
# /home/*, /var/lib/*, /root, /opt, etc.
|
|
||||||
TemporaryFileSystem=/
|
|
||||||
|
|
||||||
# Read-only: nginx binary, dynamic linker, all linked libs, system config,
|
|
||||||
# CA bundles, Let's Encrypt certs (live/ + archive/ both under /etc).
|
|
||||||
BindReadOnlyPaths=/usr
|
|
||||||
BindReadOnlyPaths=/lib
|
|
||||||
BindReadOnlyPaths=/lib64
|
|
||||||
BindReadOnlyPaths=/bin
|
|
||||||
BindReadOnlyPaths=/sbin
|
|
||||||
BindReadOnlyPaths=/etc
|
|
||||||
|
|
||||||
# Read-write: nginx runtime state.
|
|
||||||
# /run nginx.pid, nginx.lock, /run/nginx/temp/*, PHP-FPM sock
|
|
||||||
# /var/log/nginx access.log, error.log
|
|
||||||
# /nginx config dir (read-mostly but reload writes some state)
|
|
||||||
BindPaths=/run
|
|
||||||
BindPaths=/var/log/nginx
|
|
||||||
BindPaths=/nginx
|
|
||||||
|
|
||||||
NoNewPrivileges=true
|
|
||||||
ProtectKernelTunables=true
|
|
||||||
ProtectKernelModules=true
|
|
||||||
ProtectKernelLogs=true
|
|
||||||
ProtectControlGroups=true
|
|
||||||
ProtectClock=true
|
|
||||||
ProtectHostname=true
|
|
||||||
PrivateDevices=true
|
|
||||||
PrivateTmp=true
|
|
||||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
|
||||||
RestrictNamespaces=true
|
|
||||||
RestrictRealtime=true
|
|
||||||
# RestrictSUIDSGID=true <- deliberately OFF (see NOTE): it breaks openat2(2)
|
|
||||||
LockPersonality=true
|
|
||||||
SystemCallArchitectures=native
|
|
||||||
SystemCallFilter=@system-service
|
|
||||||
SystemCallErrorNumber=EPERM
|
|
||||||
|
|
||||||
# NOTE deliberately OFF:
|
|
||||||
# MemoryDenyWriteExecute=true breaks LuaJIT (JIT writable+executable pages)
|
|
||||||
# SystemCallFilter=~@resources breaks nginx workers' prlimit64()
|
|
||||||
# RestrictSUIDSGID=true its seccomp filter makes openat2(2) return
|
|
||||||
# ENOSYS (cannot be re-allowed via
|
|
||||||
# SystemCallFilter), which disables the
|
|
||||||
# tenant_isolation race-free openat2 path and
|
|
||||||
# forces the realpath() fallback. Workers are
|
|
||||||
# unprivileged + NoNewPrivileges=true, so a
|
|
||||||
# worker-created setuid/setgid file is owned by
|
|
||||||
# nginx (not root) and grants no escalation.
|
|
||||||
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=A high performance web server and a reverse proxy server (twiy)
|
|
||||||
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
PIDFile=/run/nginx.pid
|
|
||||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
|
||||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /run/nginx/temp /run/nginx/temp/client_body /run/nginx/temp/proxy /run/nginx/temp/fastcgi /run/nginx/temp/uwsgi /run/nginx/temp/scgi /var/log/nginx
|
|
||||||
ExecStartPre=/usr/sbin/nginx -t
|
|
||||||
ExecStart=/usr/sbin/nginx -c /nginx/nginx.conf
|
|
||||||
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /run/nginx.pid)"
|
|
||||||
ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|
||||||
TimeoutStartSec=10
|
|
||||||
LimitNOFILE=65535
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=A high performance web server and a reverse proxy server (twiy)
|
|
||||||
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
PIDFile=/run/nginx.pid
|
|
||||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
|
||||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /run/nginx/temp /run/nginx/temp/client_body /run/nginx/temp/proxy /run/nginx/temp/fastcgi /run/nginx/temp/uwsgi /run/nginx/temp/scgi /var/log/nginx
|
|
||||||
ExecStartPre=/usr/sbin/nginx -t
|
|
||||||
ExecStart=/usr/sbin/nginx -c /nginx/nginx.conf
|
|
||||||
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /run/nginx.pid)"
|
|
||||||
ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|
||||||
TimeoutStartSec=10
|
|
||||||
LimitNOFILE=65535
|
|
||||||
|
|
||||||
# === hardening: deny-everything by default, allowlist via bind mounts ===
|
|
||||||
# TemporaryFileSystem=/ replaces the visible filesystem with an empty tmpfs.
|
|
||||||
# Everything not bind-mounted below is invisible to nginx workers — even
|
|
||||||
# read access. Compromise of a worker can no longer enumerate /etc/passwd,
|
|
||||||
# /home/*, /var/lib/*, /root, /opt, etc.
|
|
||||||
TemporaryFileSystem=/
|
|
||||||
|
|
||||||
# Read-only: nginx binary, dynamic linker, all linked libs, system config,
|
|
||||||
# CA bundles, Let's Encrypt certs (live/ + archive/ both under /etc).
|
|
||||||
BindReadOnlyPaths=/usr
|
|
||||||
BindReadOnlyPaths=/lib
|
|
||||||
BindReadOnlyPaths=/lib64
|
|
||||||
BindReadOnlyPaths=/bin
|
|
||||||
BindReadOnlyPaths=/sbin
|
|
||||||
BindReadOnlyPaths=/etc
|
|
||||||
|
|
||||||
# Read-write: nginx runtime state.
|
|
||||||
# /run nginx.pid, nginx.lock, /run/nginx/temp/*, PHP-FPM sock
|
|
||||||
# /var/log/nginx access.log, error.log
|
|
||||||
# /nginx config dir (read-mostly but reload writes some state)
|
|
||||||
BindPaths=/run
|
|
||||||
BindPaths=/var/log/nginx
|
|
||||||
BindPaths=/nginx
|
|
||||||
|
|
||||||
NoNewPrivileges=true
|
|
||||||
ProtectKernelTunables=true
|
|
||||||
ProtectKernelModules=true
|
|
||||||
ProtectKernelLogs=true
|
|
||||||
ProtectControlGroups=true
|
|
||||||
ProtectClock=true
|
|
||||||
ProtectHostname=true
|
|
||||||
PrivateDevices=true
|
|
||||||
PrivateTmp=true
|
|
||||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
|
||||||
RestrictNamespaces=true
|
|
||||||
RestrictRealtime=true
|
|
||||||
# RestrictSUIDSGID=true <- deliberately OFF (see NOTE): it breaks openat2(2)
|
|
||||||
LockPersonality=true
|
|
||||||
SystemCallArchitectures=native
|
|
||||||
SystemCallFilter=@system-service
|
|
||||||
SystemCallErrorNumber=EPERM
|
|
||||||
|
|
||||||
# NOTE deliberately OFF:
|
|
||||||
# MemoryDenyWriteExecute=true breaks LuaJIT (JIT writable+executable pages)
|
|
||||||
# SystemCallFilter=~@resources breaks nginx workers' prlimit64()
|
|
||||||
# RestrictSUIDSGID=true its seccomp filter makes openat2(2) return
|
|
||||||
# ENOSYS (cannot be re-allowed via
|
|
||||||
# SystemCallFilter), which disables the
|
|
||||||
# tenant_isolation race-free openat2 path and
|
|
||||||
# forces the realpath() fallback. Workers are
|
|
||||||
# unprivileged + NoNewPrivileges=true, so a
|
|
||||||
# worker-created setuid/setgid file is owned by
|
|
||||||
# nginx (not root) and grants no escalation.
|
|
||||||
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=A high performance web server and a reverse proxy server (twiy)
|
|
||||||
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
PIDFile=/run/nginx.pid
|
|
||||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
|
||||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /run/nginx/temp /run/nginx/temp/client_body /run/nginx/temp/proxy /run/nginx/temp/fastcgi /run/nginx/temp/uwsgi /run/nginx/temp/scgi /var/log/nginx
|
|
||||||
ExecStartPre=/usr/sbin/nginx -t
|
|
||||||
ExecStart=/usr/sbin/nginx -c /nginx/nginx.conf
|
|
||||||
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /run/nginx.pid)"
|
|
||||||
ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|
||||||
TimeoutStartSec=10
|
|
||||||
LimitNOFILE=65535
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
+14
-77
@@ -1,7 +1,8 @@
|
|||||||
|
# Suggestions? => https://github.com/theraw/The-World-Is-Yours/issues
|
||||||
|
# Problems? => https://github.com/theraw/The-World-Is-Yours/issues
|
||||||
user nginx;
|
user nginx;
|
||||||
pid /run/nginx.pid;
|
pid /var/run/nginx.pid;
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
worker_cpu_affinity auto;
|
|
||||||
worker_rlimit_nofile 65535;
|
worker_rlimit_nofile 65535;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
@@ -21,70 +22,25 @@ http {
|
|||||||
# =================== END L7 =========================== #
|
# =================== END L7 =========================== #
|
||||||
|
|
||||||
# ===================== LOGS =========================== #
|
# ===================== LOGS =========================== #
|
||||||
map $upstream_cache_status $log_cache_status {
|
log_format main 'DATE: $time_local FROM: $remote_addr | STATUS: $status | TO: $request | CACHE: $upstream_cache_status | A: $http_user_agent';
|
||||||
"" "STATIC";
|
|
||||||
default $upstream_cache_status;
|
|
||||||
}
|
|
||||||
more_set_headers "X-Cache-Status: $log_cache_status";
|
|
||||||
log_format main 'DATE: $time_local FROM: $remote_addr | STATUS: $status | TO: $request | CACHE: $log_cache_status | A: $http_user_agent';
|
|
||||||
# =================== END LOGS ========================= #
|
# =================== END LOGS ========================= #
|
||||||
|
|
||||||
# ==================== GENERAL ========================= #
|
# ==================== GENERAL ========================= #
|
||||||
client_header_buffer_size 4k;
|
client_body_buffer_size 2M;
|
||||||
large_client_header_buffers 4 16k;
|
client_header_buffer_size 2M;
|
||||||
client_body_buffer_size 16k;
|
client_body_timeout 90s;
|
||||||
|
client_header_timeout 90s;
|
||||||
client_max_body_size 2M;
|
client_max_body_size 2M;
|
||||||
client_body_timeout 30s;
|
keepalive_timeout 15s;
|
||||||
client_header_timeout 30s;
|
|
||||||
send_timeout 30s;
|
|
||||||
reset_timedout_connection on;
|
|
||||||
keepalive_timeout 65s;
|
|
||||||
keepalive_requests 2000;
|
|
||||||
max_headers 100;
|
|
||||||
port_in_redirect off;
|
port_in_redirect off;
|
||||||
sendfile on;
|
sendfile on;
|
||||||
sendfile_max_chunk 1m;
|
server_names_hash_bucket_size 6969;
|
||||||
|
server_name_in_redirect off;
|
||||||
|
server_tokens off;
|
||||||
tcp_nodelay on;
|
tcp_nodelay on;
|
||||||
tcp_nopush on;
|
tcp_nopush on;
|
||||||
server_tokens off;
|
types_hash_max_size 2048;
|
||||||
server_name_in_redirect off;
|
resolver 1.1.1.1 1.0.0.1;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
# Symlink backstop for tenant_isolation, checked at the serving open(): catches
|
|
||||||
# the probe->open race and the paths the patch skips (gzip_static, autoindex,
|
|
||||||
# dav, mp4/flv). if_not_owner allows a tenant's own symlinks, blocks ones whose
|
|
||||||
# target has a different owner (docroot/x -> /etc/passwd => 403).
|
|
||||||
disable_symlinks if_not_owner from=$document_root;
|
|
||||||
|
|
||||||
# ===================== TLS ============================ #
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers off;
|
|
||||||
ssl_session_cache shared:SSL:200m;
|
|
||||||
ssl_session_timeout 1d;
|
|
||||||
ssl_session_tickets off;
|
|
||||||
ssl_stapling on;
|
|
||||||
ssl_stapling_verify on;
|
|
||||||
|
|
||||||
# Cloudflare dynamic TLS record sizing (build/patches/nginx-X-dynamic-tls-records.patch).
|
|
||||||
# Small records up front cut TTFB by ~1 RTT, then ramp up to amortise TLS
|
|
||||||
# overhead once the connection is past head-of-line blocking.
|
|
||||||
ssl_dyn_rec_enable on;
|
|
||||||
ssl_dyn_rec_size_lo 1369;
|
|
||||||
ssl_dyn_rec_size_hi 4229;
|
|
||||||
ssl_dyn_rec_threshold 40;
|
|
||||||
ssl_dyn_rec_timeout 1000;
|
|
||||||
# ===================== 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;
|
||||||
|
|
||||||
@@ -92,25 +48,6 @@ http {
|
|||||||
default upgrade;
|
default upgrade;
|
||||||
'' close;
|
'' close;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==================== COMPRESSION ===================== #
|
|
||||||
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;
|
|
||||||
|
|
||||||
zstd on;
|
|
||||||
zstd_comp_level 4;
|
|
||||||
zstd_min_length 256;
|
|
||||||
zstd_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 ================= #
|
||||||
|
|||||||
@@ -1,102 +1,51 @@
|
|||||||
export NGINX="1.31.3"
|
export NGINX="1.26.0"
|
||||||
|
|
||||||
# Lua Path
|
|
||||||
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.29"
|
export NGX_MOD_LUA="0.10.27"
|
||||||
|
|
||||||
# https://github.com/vision5/ngx_devel_kit/tags
|
# https://github.com/vision5/ngx_devel_kit/tags
|
||||||
export NGX_MOD_DEVELKIT="0.3.4"
|
export NGX_MOD_DEVELKIT="0.3.3"
|
||||||
|
|
||||||
# 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.4"
|
export NGX_MOD_MODSECURITY="1.0.3"
|
||||||
|
|
||||||
# https://github.com/winshining/nginx-http-flv-module/releases
|
# https://github.com/winshining/nginx-http-flv-module/releases
|
||||||
export NGX_MOD_HTTPFLV="1.2.13"
|
export NGX_MOD_HTTPFLV="1.2.11"
|
||||||
|
|
||||||
# https://github.com/openresty/headers-more-nginx-module/tags
|
# https://github.com/openresty/headers-more-nginx-module/tags
|
||||||
export NGX_MOD_HEADERS_MORE="0.39"
|
export NGX_MOD_HEADERS_MORE="0.37"
|
||||||
|
|
||||||
# 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.32"
|
export LUA_SCRIPTS_RESTYCORE="0.1.28"
|
||||||
|
|
||||||
# https://github.com/openresty/lua-resty-lrucache/tags
|
# https://github.com/openresty/lua-resty-lrucache/tags
|
||||||
export LUA_SCRIPTS_LRUCACHE="0.15"
|
export LUA_SCRIPTS_LRUCACHE="0.13"
|
||||||
|
|
||||||
# https://github.com/openresty/luajit2/tags
|
# https://github.com/openresty/luajit2/tags
|
||||||
export SYSTEM_LUAJIT="2.1-20260311"
|
export SYSTEM_LUAJIT="2.1-20231117"
|
||||||
|
|
||||||
# https://github.com/PCRE2Project/pcre2/releases
|
# https://github.com/PCRE2Project/pcre2/releases
|
||||||
export SYSTEM_PCRE="10.47"
|
export SYSTEM_PCRE="10.43"
|
||||||
|
|
||||||
# https://github.com/aws/aws-lc/tags
|
# https://github.com/openssl/openssl
|
||||||
# AWS-LC = Amazon's BoringSSL fork. Supported natively in nginx since 1.29.2.
|
export SYSTEM_OPENSSL="3.1.5-quic1"
|
||||||
# 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 3.0.12
|
# https://github.com/SpiderLabs/ModSecurity/releases
|
||||||
export SYSTEM_MODSECURITY="3.0.14"
|
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.29"
|
export NGX_MOD_LUA_MYSQL="0.27"
|
||||||
|
|
||||||
# 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"
|
||||||
|
|
||||||
# https://github.com/openresty/srcache-nginx-module/tags
|
# https://github.com/openresty/srcache-nginx-module/tags
|
||||||
export NGX_MOD_LUA_SRCACHE="0.33"
|
export NGX_MOD_LUA_SRCACHE="0.33"
|
||||||
|
|
||||||
# https://github.com/eilandert/zstd-nginx-module/tags
|
|
||||||
export NGX_MOD_ZSTD="v1.1"
|
|
||||||
|
|
||||||
# https://github.com/zlib-ng/zlib-ng/releases
|
|
||||||
# Drop-in libz replacement with SIMD-accelerated DEFLATE. Built in --zlib-compat
|
|
||||||
# mode, installed to /usr/local/zlib-ng/. ~2-3x faster gzip CPU vs stock zlib.
|
|
||||||
export SYSTEM_ZLIBNG="2.3.3"
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Patches applied on top of upstream nginx source (committed at build/patches/).
|
|
||||||
# 1 = apply, 0 = skip. Each patch's filename embeds the nginx version it was
|
|
||||||
# authored against — bumping NGINX above means reviewing/refreshing every patch
|
|
||||||
# in build/patches/.
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Required for Type=notify in the systemd unit. Mainline nginx has the
|
|
||||||
# #if (NGX_HAVE_SYSTEMD) guards but no actual sd_notify call sites; every distro
|
|
||||||
# carries their own patch. Without this, `Type=notify` times out at startup.
|
|
||||||
export APPLY_PATCH_SYSTEMD_NOTIFY=1
|
|
||||||
|
|
||||||
# Cloudflare's dynamic TLS records: ssl_dyn_rec_* directives. Varies TLS record
|
|
||||||
# size based on connection state. -1 RTT TTFB on first byte, +reduced overhead
|
|
||||||
# at steady state. Patch shipped at build/patches/.
|
|
||||||
export APPLY_PATCH_DYNAMIC_TLS_RECORDS=1
|
|
||||||
|
|
||||||
# Cloudflare's HPACK dynamic-table encoder: --with-http_v2_hpack_enc. Smaller
|
|
||||||
# HTTP/2 response headers on the wire. Upstream patch is stale (last touched
|
|
||||||
# 2017; nginx 1.31 has already absorbed parts of it upstream and the remaining
|
|
||||||
# hunks reference internals that have drifted). Patch NOT yet shipped — would
|
|
||||||
# need a full rebase. Keep toggle here for the day someone ports it.
|
|
||||||
export APPLY_PATCH_HTTP2_HPACK_ENC=0
|
|
||||||
|
|
||||||
# Tenant isolation: kernel-enforced (openat2 RESOLVE_BENEATH|NO_MAGICLINKS)
|
|
||||||
# confinement of static-file resolution to each tenant's document root, so a
|
|
||||||
# symlink/".."/magic-link that would escape the tenant tree is refused with 403
|
|
||||||
# at the syscall level (no TOCTOU, unlike disable_symlinks). Patch shipped at
|
|
||||||
# build/patches/nginx-${NGINX}-tenant-isolation.patch; self-contained in
|
|
||||||
# ngx_http_static_module.c (adds the `tenant_isolation` + `tenant_isolation_root`
|
|
||||||
# directives). Optional for a plain nginx build — set =0 to exclude entirely.
|
|
||||||
export APPLY_PATCH_TENANT_ISOLATION=1
|
|
||||||
|
|
||||||
# When the patch is applied, also compile the `tenant_isolation` directive
|
|
||||||
# default-ON (-DNGX_TENANT_ISOLATION_DEFAULT_ON=1) so EVERY vhost is confined
|
|
||||||
# unless it sets `tenant_isolation off;`. This is the twiy-raweb posture. Set =0
|
|
||||||
# to ship the patch but leave the directive opt-in per vhost (`tenant_isolation
|
|
||||||
# on;`) — the "default nginx" posture. Inert at runtime on kernels w/o openat2.
|
|
||||||
export TENANT_ISOLATION_DEFAULT_ON=1
|
|
||||||
|
|||||||
Reference in New Issue
Block a user