ubuntu 26.04
This commit is contained in:
+105
-165
@@ -1,16 +1,19 @@
|
||||
# =============================================================================
|
||||
# build-and-publish
|
||||
# build-and-publish (multi-distro matrix)
|
||||
#
|
||||
# Compiles a custom nginx (with ModSecurity, naxsi, lua, brotli, geoip2, etc.),
|
||||
# packages the result as a Debian .deb named `twiy`, and uploads it to a
|
||||
# Sonatype Nexus apt-hosted repository so users can install via `apt`.
|
||||
# Builds twiy as a Debian .deb for each target distro in parallel:
|
||||
# - trixie (Debian 13) -> uploaded to NEXUS_REPO_TRIXIE
|
||||
# - raccoon (Ubuntu 26.04 LTS) -> uploaded to NEXUS_REPO_RACCOON
|
||||
#
|
||||
# Triggers:
|
||||
# * Every push to master.
|
||||
# * Manual run from the Actions UI (workflow_dispatch).
|
||||
# Each matrix job spins up a Docker container of the target distro on the
|
||||
# Gitea runner host, builds nginx + modules INSIDE the container so apt deps
|
||||
# and ldd resolution match what end users have, then uploads the resulting
|
||||
# .deb to that distro's Nexus apt-hosted repository.
|
||||
#
|
||||
# Required repository secrets (see the "Publish to Nexus" step for details):
|
||||
# NEXUS_USER, NEXUS_PASS, NEXUS_URL, NEXUS_REPO
|
||||
# Required repository secrets:
|
||||
# NEXUS_USER, NEXUS_PASS, NEXUS_URL (shared)
|
||||
# NEXUS_REPO_TRIXIE (Debian 13 target)
|
||||
# NEXUS_REPO_RACCOON (Ubuntu 26.04 target)
|
||||
# =============================================================================
|
||||
name: build-and-publish
|
||||
|
||||
@@ -21,64 +24,67 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Pinned to ubuntu-22.04 because the build script targets the toolchain
|
||||
# versions that ship with that release. Bumping this needs validation
|
||||
# against the modules pinned in /version.
|
||||
# Runner is just a docker host; build OS is determined by matrix.image.
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
# If trixie fails, still finish raccoon (and vice versa) — surface both.
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: [trixie, raccoon]
|
||||
include:
|
||||
- target: trixie
|
||||
image: debian:13
|
||||
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
||||
- target: raccoon
|
||||
image: ubuntu:26.04
|
||||
nexus_repo_secret: NEXUS_REPO_RACCOON
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Minimal toolchain to: build nginx (build-essential), package the
|
||||
# output (dpkg-dev, fakeroot), and fetch sources (git, curl, wget).
|
||||
# gnupg is kept in case a future step needs to verify upstream sigs.
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
git curl wget ca-certificates dpkg-dev fakeroot \
|
||||
build-essential gnupg
|
||||
|
||||
- name: Compile nginx and modules
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Touch /.dockerenv so build/run.sh's container-detection branch is
|
||||
# taken: it skips `systemctl start nginx` (the runner has no systemd).
|
||||
# The .deb's own postinst handles service start on the user's host.
|
||||
sudo touch /.dockerenv
|
||||
sudo bash build/run.sh new # download sources for nginx + modules
|
||||
sudo bash build/run.sh build # configure, compile, install
|
||||
sudo bash build/run.sh postfix # drop default configs into /nginx
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# Assemble the .deb by hand (we don't use debhelper because the build
|
||||
# script already places everything at its final paths under the runner's
|
||||
# root; we just need to mirror those paths into PKG_DIR and add control
|
||||
# metadata).
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
- name: Assemble .deb package
|
||||
- name: Build nginx and assemble .deb inside ${{ matrix.image }}
|
||||
id: pkg
|
||||
env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
IMAGE: ${{ matrix.image }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p dist
|
||||
# The whole compile + .deb assembly happens inside the target distro
|
||||
# container. Output is dropped into ./dist/ (mounted from the runner)
|
||||
# so the publish step on the host can grab it.
|
||||
sudo docker run --rm \
|
||||
-v "$PWD:/repo" \
|
||||
-w /repo \
|
||||
-e TARGET="$TARGET" \
|
||||
"$IMAGE" \
|
||||
bash -euxc '
|
||||
# build script handles its own apt-get install (per-distro list)
|
||||
touch /.dockerenv
|
||||
bash build/${TARGET}.sh new
|
||||
bash build/${TARGET}.sh build
|
||||
bash build/${TARGET}.sh postfix
|
||||
|
||||
PKG_NAME="twiy"
|
||||
NGINX_VER="$(nginx -v 2>&1 | awk -F'/' '{print $2}')"
|
||||
# Append the CI run number as the Debian revision so each rebuild
|
||||
# produces a strictly-greater version (e.g. 1.26.0-3 > 1.26.0-2 >
|
||||
# 1.26.0). Without this, `apt upgrade twiy` would be a no-op when
|
||||
# upstream nginx hasn't moved, so packaging fixes wouldn't reach
|
||||
# users who already have the package installed.
|
||||
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}"
|
||||
NGINX_VER="$(nginx -v 2>&1 | awk -F/ "{print \$2}")"
|
||||
# Append CI run number AND target so each rebuild is a strictly-
|
||||
# greater Debian revision. Without this, `apt upgrade twiy` would
|
||||
# be a no-op when upstream nginx hasnt moved, so packaging fixes
|
||||
# wouldnt reach users who already have the package installed.
|
||||
# The ~target suffix keeps trixie/raccoon versions distinct in
|
||||
# case any introspection ever compares them.
|
||||
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
||||
ARCH="amd64"
|
||||
PKG_DIR="/opt/${PKG_NAME}_${VERSION}_${ARCH}"
|
||||
DEB_DIR="${PKG_DIR}/DEBIAN"
|
||||
|
||||
# The `*_temp` dirs under /usr/local/nginx are nginx's compiled-in
|
||||
# The *_temp dirs under /usr/local/nginx are nginxs compiled-in
|
||||
# defaults for client_body / proxy / fastcgi / uwsgi / scgi temp
|
||||
# storage (no --http-*-temp-path was passed to ./configure). They
|
||||
# must exist before `nginx -t` runs, so we ship them empty in the
|
||||
# .deb and the postinst chowns them to the nginx user.
|
||||
sudo mkdir -p "${PKG_DIR}/usr/sbin" "${PKG_DIR}/nginx" \
|
||||
mkdir -p "${PKG_DIR}/usr/sbin" "${PKG_DIR}/nginx" \
|
||||
"${PKG_DIR}/etc/systemd/system" "${PKG_DIR}/var/log/nginx" \
|
||||
"${PKG_DIR}/usr/lib" "${PKG_DIR}/usr/local/lib" \
|
||||
"${PKG_DIR}/hostdata/default/public_html" \
|
||||
@@ -89,31 +95,22 @@ jobs:
|
||||
"${PKG_DIR}/usr/local/nginx/uwsgi_temp" \
|
||||
"${PKG_DIR}/usr/local/nginx/scgi_temp"
|
||||
|
||||
# Pull every artifact the build produced into the package tree.
|
||||
# `|| true` on the recursive copies tolerates a missing source dir
|
||||
# (e.g. when rebuilding without re-running postfix locally).
|
||||
sudo cp /usr/sbin/nginx "${PKG_DIR}/usr/sbin/"
|
||||
sudo cp -R /nginx/* "${PKG_DIR}/nginx/" || true
|
||||
sudo cp /etc/systemd/system/nginx.service "${PKG_DIR}/etc/systemd/system/"
|
||||
sudo cp -R /hostdata/default "${PKG_DIR}/hostdata/" || true
|
||||
sudo cp -R /usr/nginx_lua "${PKG_DIR}/usr/" || true
|
||||
cp /usr/sbin/nginx "${PKG_DIR}/usr/sbin/"
|
||||
cp -R /nginx/* "${PKG_DIR}/nginx/" || true
|
||||
cp /etc/systemd/system/nginx.service "${PKG_DIR}/etc/systemd/system/"
|
||||
cp -R /hostdata/default "${PKG_DIR}/hostdata/" || true
|
||||
cp -R /usr/nginx_lua "${PKG_DIR}/usr/" || true
|
||||
|
||||
# Bundle every shared library nginx links against. This makes the
|
||||
# package self-contained: users don't need our exact build-host
|
||||
# versions of libssl, libluajit, libmodsecurity, etc. The grep
|
||||
# filters out the vDSO and the dynamic linker (which never appear
|
||||
# as `=> /...`).
|
||||
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
|
||||
sudo cp "$lib" "${PKG_DIR}/usr/lib/" || true
|
||||
# Bundle every shared library nginx links against. ldd resolves
|
||||
# against THIS containers libraries (not the runner host) so the
|
||||
# .deb gets the correct per-distro libs.
|
||||
for lib in $(ldd /usr/sbin/nginx | grep "=> /" | awk "{print \$3}"); do
|
||||
cp "$lib" "${PKG_DIR}/usr/lib/" || true
|
||||
done
|
||||
|
||||
# ---- DEBIAN/control --------------------------------------------------
|
||||
# Minimum metadata dpkg requires. The .deb bundles every shared library
|
||||
# nginx links against (see the ldd loop above), so the only Depends we
|
||||
# declare is libjemalloc2 — the systemd unit LD_PRELOADs it for the
|
||||
# nginx workers; without it, the unit would fail to start.
|
||||
sudo mkdir -p "${DEB_DIR}"
|
||||
sudo tee "${DEB_DIR}/control" >/dev/null <<EOF
|
||||
# ---- DEBIAN/control --------------------------------------------
|
||||
mkdir -p "${DEB_DIR}"
|
||||
cat > "${DEB_DIR}/control" <<EOF
|
||||
Package: ${PKG_NAME}
|
||||
Version: ${VERSION}
|
||||
Section: base
|
||||
@@ -121,31 +118,14 @@ jobs:
|
||||
Architecture: ${ARCH}
|
||||
Depends: libjemalloc2
|
||||
Maintainer: Julio <me@julio.al>
|
||||
Description: Nginx L7 DDoS Protection (The-World-Is-Yours), built by RAWeb CI.
|
||||
Description: Nginx L7 DDoS Protection (The-World-Is-Yours), built by RAWeb CI for ${TARGET}.
|
||||
EOF
|
||||
|
||||
# ---- DEBIAN/postinst -------------------------------------------------
|
||||
# Runs after dpkg unpacks the files. Designed to be safe to re-run:
|
||||
# `apt install --reinstall twiy` and `apt upgrade twiy` both invoke
|
||||
# this script and must not fail.
|
||||
#
|
||||
# Every step that may legitimately fail on a re-run (user already
|
||||
# exists, service already enabled, host has no systemd, etc.) ends
|
||||
# in `|| true`, and we `exit 0` explicitly so a flaky systemctl
|
||||
# never aborts a dpkg transaction.
|
||||
sudo tee "${DEB_DIR}/postinst" >/dev/null <<'EOF'
|
||||
# ---- DEBIAN/postinst -------------------------------------------
|
||||
cat > "${DEB_DIR}/postinst" <<"EOFPOSTINST"
|
||||
#!/bin/bash
|
||||
# Idempotent: safe on first install, upgrade, and reinstall.
|
||||
|
||||
# System user nginx workers run as. -r = system account (no aging,
|
||||
# UID below SYS_UID_MAX), no shell, home set to nginx's prefix.
|
||||
useradd -r -d /usr/local/nginx -s /bin/false nginx 2>/dev/null || true
|
||||
|
||||
# nginx was compiled without --http-*-temp-path, so it defaults to
|
||||
# <prefix>/<name> (/usr/local/nginx/client_body_temp etc.). The dirs
|
||||
# already ship in the .deb, but `install -d` is the cleanest way to
|
||||
# set owner/group/mode in one shot and is a no-op when the dir
|
||||
# already exists with the right attributes.
|
||||
install -d -o nginx -g nginx -m 0755 \
|
||||
/usr/local/nginx \
|
||||
/usr/local/nginx/client_body_temp \
|
||||
@@ -154,27 +134,30 @@ jobs:
|
||||
/usr/local/nginx/uwsgi_temp \
|
||||
/usr/local/nginx/scgi_temp \
|
||||
/var/log/nginx
|
||||
|
||||
# Recursive chown picks up any user-supplied configs already under
|
||||
# /nginx (vhosts, certs) so reloads don't trip on permissions.
|
||||
chown -R nginx:nginx /var/log/nginx /nginx /usr/local/nginx 2>/dev/null || true
|
||||
|
||||
# Refresh systemd's view of unit files we just dropped, then bring
|
||||
# the service up. `restart` (rather than `start`) handles the case
|
||||
# where a previous broken install left the unit failed.
|
||||
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
|
||||
EOF
|
||||
sudo chmod 755 "${DEB_DIR}/postinst"
|
||||
EOFPOSTINST
|
||||
chmod 755 "${DEB_DIR}/postinst"
|
||||
|
||||
# Build the .deb and hand ownership back to the runner user so the
|
||||
# next step can read it without sudo.
|
||||
sudo dpkg-deb --build "${PKG_DIR}"
|
||||
DEB_FILE="${PKG_DIR}.deb"
|
||||
sudo chown "$(id -u):$(id -g)" "${DEB_FILE}"
|
||||
dpkg-deb --build "${PKG_DIR}"
|
||||
cp "${PKG_DIR}.deb" /repo/dist/
|
||||
|
||||
# Hand ownership back to the runner UID so the host job can read.
|
||||
chown $(stat -c "%u:%g" /repo) /repo/dist/$(basename "${PKG_DIR}.deb")
|
||||
|
||||
# Stash version for the publish step.
|
||||
echo "${PKG_NAME}_${VERSION}_${ARCH}.deb" > /repo/dist/${TARGET}.name
|
||||
echo "${VERSION}" > /repo/dist/${TARGET}.version
|
||||
echo "${PKG_NAME}" > /repo/dist/${TARGET}.pkg
|
||||
'
|
||||
|
||||
# Surface the artifact paths for the next step.
|
||||
DEB_FILE="$PWD/dist/$(cat dist/${TARGET}.name)"
|
||||
PKG_NAME="$(cat dist/${TARGET}.pkg)"
|
||||
VERSION="$(cat dist/${TARGET}.version)"
|
||||
{
|
||||
echo "deb_file=${DEB_FILE}"
|
||||
echo "version=${VERSION}"
|
||||
@@ -185,73 +168,44 @@ jobs:
|
||||
sha256sum "${DEB_FILE}"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# Publish the built .deb to a Sonatype Nexus apt-hosted repository.
|
||||
#
|
||||
# Threat model for this step (the workflow file is public):
|
||||
# * Credentials come exclusively from repository secrets, never source.
|
||||
# * Credentials must never appear in argv (visible via /proc/<pid>/cmdline
|
||||
# to any local user) or in the runner's persistent filesystem.
|
||||
# * If the job is cancelled or killed, secrets must still be wiped.
|
||||
#
|
||||
# To run this in your own fork, set four repository secrets:
|
||||
# NEXUS_USER — Nexus account with write access to the apt repo
|
||||
# NEXUS_PASS — its password (or token)
|
||||
# NEXUS_URL — base URL, e.g. https://apt.example.com
|
||||
# NEXUS_REPO — the apt-hosted repository name in Nexus
|
||||
# Publish to Nexus (runs on the runner host, not in the build container).
|
||||
# Same security posture as the previous workflow:
|
||||
# * tmpfs scratch dir for credentials
|
||||
# * trap covers EXIT INT TERM HUP
|
||||
# * netrc auth (no -u user:pass on cmdline → no /proc leak)
|
||||
# * NEXUS_HOST derived from NEXUS_URL so forks don't have to edit YAML
|
||||
# The matrix-driven secret indirection picks the right per-distro repo.
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
- name: Publish to Nexus
|
||||
- name: Publish to Nexus (${{ matrix.target }})
|
||||
env:
|
||||
NEXUS_USER: ${{ secrets.NEXUS_USER }}
|
||||
NEXUS_PASS: ${{ secrets.NEXUS_PASS }}
|
||||
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
||||
NEXUS_REPO: ${{ secrets.NEXUS_REPO }}
|
||||
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
||||
DEB_FILE: ${{ steps.pkg.outputs.deb_file }}
|
||||
PKG_NAME: ${{ steps.pkg.outputs.pkg_name }}
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
umask 077 # any file we create is rw for us only
|
||||
umask 077
|
||||
|
||||
# ---- Secret-handling scratch dir ------------------------------------
|
||||
# /dev/shm is tmpfs (RAM-backed). Even if the runner's disk is later
|
||||
# imaged or recovered, secrets written here never touch persistent
|
||||
# storage. Fall back to /tmp on minimal images that lack /dev/shm.
|
||||
SECDIR="$(mktemp -d -p /dev/shm twiy-XXXXXXXX 2>/dev/null \
|
||||
|| mktemp -d -t twiy-XXXXXXXX)"
|
||||
chmod 700 "$SECDIR"
|
||||
|
||||
# Trap covers normal exit, errors (set -e), and the common cancellation
|
||||
# signals Gitea / GitHub send when a job is cancelled or times out.
|
||||
# `shred -uz` overwrites then unlinks; on tmpfs the overwrite is mostly
|
||||
# symbolic, but it's free defence-in-depth in case /dev/shm wasn't
|
||||
# available and we fell back to a disk-backed /tmp.
|
||||
cleanup() {
|
||||
find "$SECDIR" -type f -exec shred -uz {} + 2>/dev/null || true
|
||||
rm -rf "$SECDIR"
|
||||
}
|
||||
trap cleanup EXIT INT TERM HUP
|
||||
|
||||
# ---- Build the netrc -------------------------------------------------
|
||||
# Why netrc and not `curl -u user:pass`:
|
||||
# - `-u` puts the password in argv; any local user can read it from
|
||||
# /proc/<pid>/cmdline while the curl is in flight.
|
||||
# - netrc is a 0600 file curl reads itself; the password never
|
||||
# appears on a command line.
|
||||
# Why `printf` (a bash builtin): builtins don't fork an external
|
||||
# process, so the password is never an argv to any executable.
|
||||
# The host string in netrc must match the URL host exactly, so we
|
||||
# derive it from $NEXUS_URL rather than hardcoding it — this lets
|
||||
# forks reuse the workflow without editing it.
|
||||
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"
|
||||
# Drop the in-memory copies now that the file is the source of truth.
|
||||
unset NEXUS_USER NEXUS_PASS
|
||||
|
||||
# ---- Replace any prior version of this package -----------------------
|
||||
# Nexus's apt-hosted format keeps every uploaded .deb forever unless we
|
||||
# explicitly delete the old component. Without this, the repo grows
|
||||
# unboundedly and `apt` may pick a stale version. Best-effort: a
|
||||
# missing prior component is not an error.
|
||||
# Replace the prior version of this same package in this same repo,
|
||||
# if any. Best-effort: missing prior is not an error. (apt-hosted
|
||||
# repos in Nexus retain every upload otherwise.)
|
||||
OLD_ID="$(curl -fsS --netrc-file "$SECDIR/netrc" \
|
||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
|
||||
| PKG_NAME="$PKG_NAME" python3 -c '
|
||||
@@ -265,25 +219,11 @@ jobs:
|
||||
"$NEXUS_URL/service/rest/v1/components/$OLD_ID" -o /dev/null
|
||||
fi
|
||||
|
||||
# ---- Upload the new .deb --------------------------------------------
|
||||
# Body goes to a file inside SECDIR so the trap shreds it too — Nexus
|
||||
# error responses sometimes echo request metadata we'd rather not
|
||||
# leave on disk.
|
||||
HTTP="$(curl -sS --netrc-file "$SECDIR/netrc" \
|
||||
-o "$SECDIR/upload.body" -w '%{http_code}' \
|
||||
-X POST -F "apt.asset=@$DEB_FILE" \
|
||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO")"
|
||||
case "$HTTP" in
|
||||
201|204) echo "Uploaded $(basename "$DEB_FILE") to $NEXUS_URL/repository/$NEXUS_REPO/" ;;
|
||||
*) echo "Upload failed (HTTP $HTTP)"; head -c 400 "$SECDIR/upload.body"; exit 1 ;;
|
||||
201|204) echo "[$TARGET] uploaded $(basename "$DEB_FILE") to $NEXUS_URL/repository/$NEXUS_REPO/" ;;
|
||||
*) echo "[$TARGET] upload failed (HTTP $HTTP)"; head -c 400 "$SECDIR/upload.body"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# ---- Why we don't sign each .deb ourselves ---------------------------
|
||||
# apt's trust chain on the client is:
|
||||
# Release.gpg → Packages (verified by SHA256 in Release)
|
||||
# → the .deb (verified by SHA256 in Packages)
|
||||
# Signing the Release file is enough; per-.deb signatures are not
|
||||
# consulted by apt during install. Nexus signs Release on every
|
||||
# upload using a key bound at repo-creation time, and that private
|
||||
# key never leaves the Nexus host — so we deliberately keep all
|
||||
# signing material off the CI runner.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||

|
||||
|
||||
- [x] Debian 13 (trixie) supported
|
||||
- [x] Debian 13 (trixie) and Ubuntu 26.04 LTS (raccoon) supported
|
||||
- [x] nginx 1.30.0
|
||||
- [x] HTTP/3 (QUIC) via AWS-LC
|
||||
- [x] ModSecurity v3 (libmodsecurity)
|
||||
@@ -12,37 +12,54 @@
|
||||
- [x] [Versions List](https://git.julio.al/theraw/The-World-Is-Yours/src/branch/master/version)
|
||||
|
||||
## Easy install
|
||||
|
||||
### Debian 13 (trixie)
|
||||
```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 main" \
|
||||
| sudo tee /etc/apt/sources.list.d/raweb.list
|
||||
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)
|
||||
```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-raccoon raccoon main" | sudo tee /etc/apt/sources.list.d/raweb.list
|
||||
sudo apt update && sudo apt install twiy
|
||||
```
|
||||
|
||||
## Compile from source
|
||||
```bash
|
||||
apt-get -y install git && cd /root/ && git clone https://github.com/theraw/The-World-Is-Yours.git && cd The-World-Is-Yours/
|
||||
|
||||
bash build/run.sh new
|
||||
bash build/run.sh build
|
||||
bash build/run.sh postfix
|
||||
Pick the script that matches your OS — they're separate so apt package
|
||||
divergences (e.g. the t64 ABI transition on Ubuntu 24.04+) stay isolated.
|
||||
|
||||
```bash
|
||||
apt-get -y install git && cd /root/ && git clone https://git.julio.al/theraw/The-World-Is-Yours.git && cd The-World-Is-Yours/
|
||||
|
||||
# Debian 13
|
||||
bash build/trixie.sh new
|
||||
bash build/trixie.sh build
|
||||
bash build/trixie.sh postfix
|
||||
|
||||
# Ubuntu 26.04 LTS
|
||||
bash build/raccoon.sh new
|
||||
bash build/raccoon.sh build
|
||||
bash build/raccoon.sh postfix
|
||||
```
|
||||
|
||||
If you want to try with a custom nginx version then, open `version` file and change versions then run
|
||||
```bash
|
||||
bash build/run.sh new
|
||||
bash build/run.sh build
|
||||
```
|
||||
To try a different upstream version, edit `version` and re-run `new` then `build`.
|
||||
|
||||
## CLI Info
|
||||
```
|
||||
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.
|
||||
@@ -69,16 +86,11 @@ nginx -s reload
|
||||
|
||||
## Performance
|
||||
|
||||
|
||||
### vs. vanilla nginx (same version, default config)
|
||||
|
||||
| Area | Twiy | Vanilla nginx | Why |
|
||||
|---|---|---|---|
|
||||
| TLS handshake throughput | **+5–15%** | baseline | AWS-LC's tuned AES/ChaCha asm vs OpenSSL |
|
||||
| Static file throughput | **2–5×** | baseline | `open_file_cache` (off by default in vanilla) |
|
||||
| TLS resumed handshakes | **~10× CPU saving** | baseline | 200 MB shared session cache vs none |
|
||||
| Per-handshake latency (cold) | **−50–200 ms p95** | baseline | OCSP stapling on by default |
|
||||
| Compressed-text bandwidth | **−60 to −80%** | unchanged | brotli + gzip enabled in `http {}` |
|
||||
| WAF, Lua, HTTP/3 | included | not included | needs custom build |
|
||||
|
||||
# Support options.
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
. ./version
|
||||
set -e
|
||||
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-dev mercurial libpcre2-dev libc-ares-dev libre2-dev libzstd-dev libjemalloc2 -y
|
||||
mkdir -p $LUA_SCRIPTS
|
||||
}
|
||||
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
|
||||
|
||||
# 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
|
||||
if [ ! -d /opt/mod/zlib ]; then
|
||||
cd /opt/mod && wget http://zlib.net/current/zlib.tar.gz
|
||||
cd /opt/mod && tar xf zlib.tar.gz; rm -Rf zlib.tar.gz; mv zlib-* zlib
|
||||
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
|
||||
|
||||
# NGX_MOD_ZSTD — Zstandard compression module from tokers. Pinned via
|
||||
# NGX_MOD_ZSTD; tarball pattern (dir name embeds version → cache invalidates
|
||||
# automatically when the pin moves).
|
||||
if [ ! -d /opt/mod/zstd-nginx-module-${NGX_MOD_ZSTD} ]; then
|
||||
cd /opt/mod/; wget https://github.com/tokers/zstd-nginx-module/archive/refs/tags/${NGX_MOD_ZSTD}.tar.gz
|
||||
cd /opt/mod/; tar xf ${NGX_MOD_ZSTD}.tar.gz; rm -Rf ${NGX_MOD_ZSTD}.tar.gz
|
||||
fi
|
||||
|
||||
# END OF NGINX MODULES
|
||||
# ============================================================================================================
|
||||
}
|
||||
|
||||
test_nginx() {
|
||||
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=/var/run/nginx.pid \
|
||||
--lock-path=/var/run/nginx.lock \
|
||||
--error-log-path=/var/log/nginx/error.log \
|
||||
--http-log-path=/var/log/nginx/access.log \
|
||||
--with-pcre \
|
||||
--with-pcre-jit \
|
||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
||||
--with-zlib=/opt/mod/zlib \
|
||||
--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" \
|
||||
--with-ld-opt="-Wl,-rpath,/usr/local/LuaJIT/lib -Wl,-rpath,/usr/local/lib -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/mod/pcre2-${SYSTEM_PCRE}/.libs -lpcre2-8 -L/usr/local/aws-lc/lib -lssl -lcrypto -Wl,-rpath,/usr/local/aws-lc/lib"
|
||||
make clean
|
||||
}
|
||||
function build() {
|
||||
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=/var/run/nginx.pid \
|
||||
--lock-path=/var/run/nginx.lock \
|
||||
--error-log-path=/var/log/nginx/error.log \
|
||||
--http-log-path=/var/log/nginx/access.log \
|
||||
--with-pcre \
|
||||
--with-pcre-jit \
|
||||
--with-pcre=/opt/mod/pcre2-${SYSTEM_PCRE} \
|
||||
--with-zlib=/opt/mod/zlib \
|
||||
--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" \
|
||||
--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"
|
||||
# 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
|
||||
if [ -f "/run/.containerenv" ] || [ -f "/.dockerenv" ] || [ -f "/home/runner/.dockerenv" ]; then
|
||||
echo "Skipping systemctl commands on GitHub runner"
|
||||
mkdir -p /etc/systemd/system/
|
||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Raccoon/nginx.service > /etc/systemd/system/nginx.service
|
||||
else
|
||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Raccoon/nginx.service > /etc/systemd/system/nginx.service
|
||||
systemctl daemon-reload
|
||||
systemctl start 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
|
||||
@@ -358,9 +358,9 @@ function post_build() {
|
||||
if [ -f "/run/.containerenv" ] || [ -f "/.dockerenv" ] || [ -f "/home/runner/.dockerenv" ]; then
|
||||
echo "Skipping systemctl commands on GitHub runner"
|
||||
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
|
||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Trixie/nginx.service > /etc/systemd/system/nginx.service
|
||||
else
|
||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Jammy/nginx.service > /etc/systemd/system/nginx.service
|
||||
curl -s https://raw.githubusercontent.com/theraw/The-World-Is-Yours/master/static/Trixie/nginx.service > /etc/systemd/system/nginx.service
|
||||
systemctl daemon-reload
|
||||
systemctl start nginx.service
|
||||
systemctl enable nginx.service
|
||||
@@ -1,16 +0,0 @@
|
||||
[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
|
||||
@@ -1,21 +0,0 @@
|
||||
[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=/run/nginx.pid
|
||||
# jemalloc replaces glibc malloc — better fragmentation/perf under nginx's
|
||||
# alloc/free churn at scale. Package depends on libjemalloc2 so the .so is
|
||||
# guaranteed present. Removing this line falls back to glibc malloc cleanly.
|
||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /usr/local/nginx /usr/local/nginx/client_body_temp /usr/local/nginx/proxy_temp /usr/local/nginx/fastcgi_temp /usr/local/nginx/uwsgi_temp /usr/local/nginx/scgi_temp /var/log/nginx
|
||||
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,57 @@
|
||||
[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
|
||||
|
||||
# jemalloc replaces glibc malloc — better fragmentation/perf under nginx's
|
||||
# alloc/free churn at scale. Package depends on libjemalloc2 so the .so is
|
||||
# guaranteed present. Removing this line falls back to glibc malloc cleanly.
|
||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
||||
|
||||
# Self-heal: nginx was compiled without --http-*-temp-path so it expects
|
||||
# these dirs under /usr/local/nginx; install -d is idempotent and fixes any
|
||||
# missing/wrong ownership on every restart.
|
||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /usr/local/nginx /usr/local/nginx/client_body_temp /usr/local/nginx/proxy_temp /usr/local/nginx/fastcgi_temp /usr/local/nginx/uwsgi_temp /usr/local/nginx/scgi_temp /var/log/nginx
|
||||
ExecStartPre=/usr/sbin/nginx -t
|
||||
ExecStart=/usr/sbin/nginx
|
||||
ExecReload=/usr/sbin/nginx -s reload
|
||||
ExecStop=/bin/kill -s QUIT $MAINPID
|
||||
|
||||
# ---- systemd hardening (systemd 257+ on Debian 13 / Ubuntu 26.04) ----
|
||||
# Each line shrinks the worker's blast radius without affecting throughput.
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=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
|
||||
LockPersonality=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged @resources @mount @debug @cpu-emulation @obsolete @raw-io @reboot @swap
|
||||
|
||||
# Paths nginx legitimately writes to. ProtectSystem=strict makes everything
|
||||
# else read-only; these carve out the exceptions.
|
||||
ReadWritePaths=/var/log/nginx /usr/local/nginx /run /nginx /hostdata
|
||||
|
||||
# NOTE on MemoryDenyWriteExecute: LuaJIT does runtime JIT compilation and
|
||||
# therefore needs writable+executable pages — enabling MDWE breaks Lua. Left
|
||||
# off intentionally.
|
||||
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,57 @@
|
||||
[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
|
||||
|
||||
# jemalloc replaces glibc malloc — better fragmentation/perf under nginx's
|
||||
# alloc/free churn at scale. Package depends on libjemalloc2 so the .so is
|
||||
# guaranteed present. Removing this line falls back to glibc malloc cleanly.
|
||||
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
||||
|
||||
# Self-heal: nginx was compiled without --http-*-temp-path so it expects
|
||||
# these dirs under /usr/local/nginx; install -d is idempotent and fixes any
|
||||
# missing/wrong ownership on every restart.
|
||||
ExecStartPre=/usr/bin/install -d -o nginx -g nginx -m 0755 /usr/local/nginx /usr/local/nginx/client_body_temp /usr/local/nginx/proxy_temp /usr/local/nginx/fastcgi_temp /usr/local/nginx/uwsgi_temp /usr/local/nginx/scgi_temp /var/log/nginx
|
||||
ExecStartPre=/usr/sbin/nginx -t
|
||||
ExecStart=/usr/sbin/nginx
|
||||
ExecReload=/usr/sbin/nginx -s reload
|
||||
ExecStop=/bin/kill -s QUIT $MAINPID
|
||||
|
||||
# ---- systemd hardening (systemd 257+ on Debian 13 / Ubuntu 26.04) ----
|
||||
# Each line shrinks the worker's blast radius without affecting throughput.
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=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
|
||||
LockPersonality=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged @resources @mount @debug @cpu-emulation @obsolete @raw-io @reboot @swap
|
||||
|
||||
# Paths nginx legitimately writes to. ProtectSystem=strict makes everything
|
||||
# else read-only; these carve out the exceptions.
|
||||
ReadWritePaths=/var/log/nginx /usr/local/nginx /run /nginx /hostdata
|
||||
|
||||
# NOTE on MemoryDenyWriteExecute: LuaJIT does runtime JIT compilation and
|
||||
# therefore needs writable+executable pages — enabling MDWE breaks Lua. Left
|
||||
# off intentionally.
|
||||
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -43,7 +43,7 @@ export SYSTEM_PCRE="10.47"
|
||||
export SYSTEM_AWSLC="1.72.0"
|
||||
|
||||
# https://github.com/SpiderLabs/ModSecurity/releases 3.0.12
|
||||
export SYSTEM_MODSECURITY="3.0.12"
|
||||
export SYSTEM_MODSECURITY="3.0.14"
|
||||
|
||||
# https://github.com/openresty/lua-resty-mysql/tags
|
||||
export NGX_MOD_LUA_MYSQL="0.29"
|
||||
|
||||
Reference in New Issue
Block a user