package changes
This commit is contained in:
@@ -15,11 +15,13 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- target: trixie
|
- target: trixie
|
||||||
image: debian:13
|
image: debian:13
|
||||||
|
distro_dir: Trixie
|
||||||
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
||||||
nexus_user_secret: NEXUS_USER_TRIXIE
|
nexus_user_secret: NEXUS_USER_TRIXIE
|
||||||
nexus_pass_secret: NEXUS_PASS_TRIXIE
|
nexus_pass_secret: NEXUS_PASS_TRIXIE
|
||||||
- target: raccoon
|
- target: raccoon
|
||||||
image: ubuntu:26.04
|
image: ubuntu:26.04
|
||||||
|
distro_dir: Raccoon
|
||||||
nexus_repo_secret: NEXUS_REPO_RACCOON
|
nexus_repo_secret: NEXUS_REPO_RACCOON
|
||||||
nexus_user_secret: NEXUS_USER_RACCOON
|
nexus_user_secret: NEXUS_USER_RACCOON
|
||||||
nexus_pass_secret: NEXUS_PASS_RACCOON
|
nexus_pass_secret: NEXUS_PASS_RACCOON
|
||||||
@@ -41,82 +43,90 @@ jobs:
|
|||||||
id: pkg
|
id: pkg
|
||||||
env:
|
env:
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
|
DISTRO_DIR: ${{ matrix.distro_dir }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
REPO_ROOT="$PWD" # captured before any cd in the build script
|
||||||
touch /.dockerenv
|
touch /.dockerenv
|
||||||
bash build/${TARGET}.sh new
|
bash build/${TARGET}.sh new
|
||||||
bash build/${TARGET}.sh build
|
bash build/${TARGET}.sh build
|
||||||
bash build/${TARGET}.sh postfix
|
bash build/${TARGET}.sh postfix
|
||||||
|
|
||||||
PKG_NAME="twiy"
|
|
||||||
NGINX_VER="$(nginx -v 2>&1 | awk -F/ '{print $2}')"
|
NGINX_VER="$(nginx -v 2>&1 | awk -F/ '{print $2}')"
|
||||||
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
||||||
ARCH="amd64"
|
ARCH="amd64"
|
||||||
PKG_DIR="/opt/${PKG_NAME}_${VERSION}_${ARCH}"
|
|
||||||
DEB_DIR="${PKG_DIR}/DEBIAN"
|
|
||||||
|
|
||||||
mkdir -p "${PKG_DIR}/usr/sbin" "${PKG_DIR}/nginx" \
|
assemble_deb() {
|
||||||
"${PKG_DIR}/etc/systemd/system" "${PKG_DIR}/var/log/nginx" \
|
local pkg_name="$1" unit_src="$2" conflicts="$3"
|
||||||
"${PKG_DIR}/usr/lib" \
|
local pkg_dir="/opt/${pkg_name}_${VERSION}_${ARCH}"
|
||||||
"${PKG_DIR}/hostdata/default/public_html" \
|
local deb_dir="${pkg_dir}/DEBIAN"
|
||||||
"${PKG_DIR}/usr/nginx_lua"
|
|
||||||
|
|
||||||
cp /usr/sbin/nginx "${PKG_DIR}/usr/sbin/"
|
mkdir -p "${pkg_dir}/usr/sbin" "${pkg_dir}/nginx" \
|
||||||
cp -R /nginx/* "${PKG_DIR}/nginx/" || true
|
"${pkg_dir}/etc/systemd/system" "${pkg_dir}/var/log/nginx" \
|
||||||
cp /etc/systemd/system/nginx.service "${PKG_DIR}/etc/systemd/system/"
|
"${pkg_dir}/usr/lib" \
|
||||||
cp -R /hostdata/default "${PKG_DIR}/hostdata/" || true
|
"${pkg_dir}/hostdata/default/public_html" \
|
||||||
cp -R /usr/nginx_lua "${PKG_DIR}/usr/" || true
|
"${pkg_dir}/usr/nginx_lua"
|
||||||
|
|
||||||
for d in /usr/local/aws-lc /usr/local/LuaJIT /usr/local/modsecurity /usr/local/zlib-ng; do
|
cp /usr/sbin/nginx "${pkg_dir}/usr/sbin/"
|
||||||
[ -d "$d" ] && cp -R "$d" "${PKG_DIR}/usr/local/" || true
|
cp -R /nginx/* "${pkg_dir}/nginx/" || true
|
||||||
done
|
cp "${unit_src}" "${pkg_dir}/etc/systemd/system/nginx.service"
|
||||||
mkdir -p "${PKG_DIR}/usr/local/lib"
|
cp -R /hostdata/default "${pkg_dir}/hostdata/" || true
|
||||||
cp -R /usr/local/lib/. "${PKG_DIR}/usr/local/lib/" 2>/dev/null || true
|
cp -R /usr/nginx_lua "${pkg_dir}/usr/" || true
|
||||||
|
|
||||||
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
|
for d in /usr/local/aws-lc /usr/local/LuaJIT /usr/local/modsecurity /usr/local/zlib-ng; do
|
||||||
case "$lib" in
|
[ -d "$d" ] && cp -R "$d" "${pkg_dir}/usr/local/" || true
|
||||||
/usr/local/*) continue ;;
|
done
|
||||||
esac
|
mkdir -p "${pkg_dir}/usr/local/lib"
|
||||||
cp "$lib" "${PKG_DIR}/usr/lib/" || true
|
cp -R /usr/local/lib/. "${pkg_dir}/usr/local/lib/" 2>/dev/null || true
|
||||||
done
|
|
||||||
|
|
||||||
mkdir -p "${DEB_DIR}"
|
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
|
||||||
cat > "${DEB_DIR}/control" <<EOF
|
case "$lib" in /usr/local/*) continue ;; esac
|
||||||
Package: ${PKG_NAME}
|
cp "$lib" "${pkg_dir}/usr/lib/" || true
|
||||||
Version: ${VERSION}
|
done
|
||||||
Section: base
|
|
||||||
Priority: optional
|
|
||||||
Architecture: ${ARCH}
|
|
||||||
Depends: libjemalloc2, libsystemd0
|
|
||||||
Maintainer: Julio <me@julio.al>
|
|
||||||
Description: Nginx L7 DDoS Protection (The-World-Is-Yours), built by RAWeb CI for ${TARGET}.
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > "${DEB_DIR}/postinst" <<'EOFPOSTINST'
|
mkdir -p "${deb_dir}"
|
||||||
#!/bin/bash
|
cat > "${deb_dir}/control" <<EOF
|
||||||
useradd -r -s /bin/false nginx 2>/dev/null || true
|
Package: ${pkg_name}
|
||||||
install -d -o nginx -g nginx -m 0755 /var/log/nginx
|
Version: ${VERSION}
|
||||||
# /run/nginx/temp/* is recreated on every systemd start (ExecStartPre)
|
Section: base
|
||||||
# since /run is tmpfs and cleared on reboot.
|
Priority: optional
|
||||||
chown -R nginx:nginx /var/log/nginx /nginx 2>/dev/null || true
|
Architecture: ${ARCH}
|
||||||
systemctl daemon-reload 2>/dev/null || true
|
Depends: libjemalloc2, libsystemd0
|
||||||
systemctl enable nginx.service 2>/dev/null || true
|
Conflicts: ${conflicts}
|
||||||
systemctl restart nginx.service 2>/dev/null || true
|
Replaces: ${conflicts}
|
||||||
exit 0
|
Maintainer: Julio <me@julio.al>
|
||||||
EOFPOSTINST
|
Description: Nginx L7 DDoS Protection (${pkg_name}), built by RAWeb CI for ${TARGET}.
|
||||||
chmod 755 "${DEB_DIR}/postinst"
|
EOF
|
||||||
|
|
||||||
dpkg-deb --build "${PKG_DIR}"
|
cat > "${deb_dir}/postinst" <<'EOFPOSTINST'
|
||||||
DEB_FILE="${PKG_DIR}.deb"
|
#!/bin/bash
|
||||||
|
useradd -r -s /bin/false nginx 2>/dev/null || true
|
||||||
|
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
|
||||||
|
EOFPOSTINST
|
||||||
|
chmod 755 "${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_file=${DEB_FILE}"
|
echo "deb_twiy=${DEB_TWIY}"
|
||||||
echo "version=${VERSION}"
|
echo "deb_raweb=${DEB_RAWEB}"
|
||||||
echo "pkg_name=${PKG_NAME}"
|
echo "version=${VERSION}"
|
||||||
} >> "$GITHUB_OUTPUT"
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
ls -la "${DEB_FILE}"
|
ls -la /opt/twiy*.deb
|
||||||
sha256sum "${DEB_FILE}"
|
sha256sum /opt/twiy*.deb
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
env:
|
env:
|
||||||
@@ -124,8 +134,8 @@ jobs:
|
|||||||
NEXUS_PASS: ${{ secrets[matrix.nexus_pass_secret] }}
|
NEXUS_PASS: ${{ secrets[matrix.nexus_pass_secret] }}
|
||||||
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
||||||
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
||||||
DEB_FILE: ${{ steps.pkg.outputs.deb_file }}
|
DEB_TWIY: ${{ steps.pkg.outputs.deb_twiy }}
|
||||||
PKG_NAME: ${{ steps.pkg.outputs.pkg_name }}
|
DEB_RAWEB: ${{ steps.pkg.outputs.deb_raweb }}
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -137,8 +147,8 @@ jobs:
|
|||||||
|| mktemp -d -t twiy-XXXXXXXX)"
|
|| mktemp -d -t twiy-XXXXXXXX)"
|
||||||
chmod 700 "$SECDIR"
|
chmod 700 "$SECDIR"
|
||||||
cleanup() {
|
cleanup() {
|
||||||
find "$SECDIR" -type f -exec shred -uz {} + 2>/dev/null || true
|
find "$SECDIR" -type f -exec shred -uz {} + 2>/dev/null || true
|
||||||
rm -rf "$SECDIR"
|
rm -rf "$SECDIR"
|
||||||
}
|
}
|
||||||
trap cleanup EXIT INT TERM HUP
|
trap cleanup EXIT INT TERM HUP
|
||||||
|
|
||||||
@@ -147,24 +157,33 @@ jobs:
|
|||||||
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
|
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
|
||||||
unset NEXUS_USER NEXUS_PASS
|
unset NEXUS_USER NEXUS_PASS
|
||||||
|
|
||||||
OLD_ID="$(curl -fsS --netrc-file "$SECDIR/netrc" \
|
publish_one() {
|
||||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
|
local deb="$1" pkg_name="$2"
|
||||||
| PKG_NAME="$PKG_NAME" python3 -c '
|
|
||||||
|
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
|
import sys, json, os
|
||||||
for c in json.load(sys.stdin).get("items", []):
|
for c in json.load(sys.stdin).get("items", []):
|
||||||
if c.get("name") == os.environ["PKG_NAME"]:
|
if c.get("name") == os.environ["PKG_NAME"]:
|
||||||
print(c["id"]); break
|
print(c["id"]); break
|
||||||
' || true)"
|
' || true)"
|
||||||
if [ -n "$OLD_ID" ]; then
|
if [ -n "$old_id" ]; then
|
||||||
curl -fsS -X DELETE --netrc-file "$SECDIR/netrc" \
|
curl -fsS -X DELETE --netrc-file "$SECDIR/netrc" \
|
||||||
"$NEXUS_URL/service/rest/v1/components/$OLD_ID" -o /dev/null
|
"$NEXUS_URL/service/rest/v1/components/$old_id" -o /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
HTTP="$(curl -sS --netrc-file "$SECDIR/netrc" \
|
local http
|
||||||
-o "$SECDIR/upload.body" -w '%{http_code}' \
|
http="$(curl -sS --netrc-file "$SECDIR/netrc" \
|
||||||
-X POST -F "apt.asset=@$DEB_FILE" \
|
-o "$SECDIR/upload.body" -w '%{http_code}' \
|
||||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO")"
|
-X POST -F "apt.asset=@$deb" \
|
||||||
case "$HTTP" in
|
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO")"
|
||||||
201|204) echo "[$TARGET] uploaded $(basename "$DEB_FILE")" ;;
|
case "$http" in
|
||||||
*) echo "[$TARGET] upload failed (HTTP $HTTP)"; cat "$SECDIR/upload.body"; exit 1 ;;
|
201|204) echo "[$TARGET] uploaded $(basename "$deb")" ;;
|
||||||
esac
|
*) 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"
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,4 @@
|
|||||||
.claude/
|
.claude
|
||||||
.codex
|
.codex
|
||||||
.env
|
.env
|
||||||
.creds
|
.creds
|
||||||
@@ -9,3 +9,4 @@ Dockerfile
|
|||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
PENDING_*.md
|
PENDING_*.md
|
||||||
|
PATCH_*.md
|
||||||
|
|||||||
@@ -11,12 +11,6 @@
|
|||||||
- [x] Cookie-based challenge
|
- [x] Cookie-based challenge
|
||||||
- [x] [Versions List](https://git.julio.al/theraw/The-World-Is-Yours/src/branch/master/version)
|
- [x] [Versions List](https://git.julio.al/theraw/The-World-Is-Yours/src/branch/master/version)
|
||||||
|
|
||||||
## Easy install
|
|
||||||
|
|
||||||
## CAREFUL
|
|
||||||
|
|
||||||
Raweb-nginx uses custom .service that limits system visibility for security reasons, basically you need to store your data on /hostdata, or /srv, if you use custom folders then you have to edit the service, for more details check : https://github.com/theraw/The-World-Is-Yours/blob/master/static/Trixie/nginx.service
|
|
||||||
|
|
||||||
### Debian 13 (trixie)
|
### Debian 13 (trixie)
|
||||||
```bash
|
```bash
|
||||||
sudo install -d /etc/apt/keyrings
|
sudo install -d /etc/apt/keyrings
|
||||||
@@ -33,10 +27,7 @@ echo "deb [signed-by=/etc/apt/keyrings/raweb.asc] https://apt.julio.al/repositor
|
|||||||
sudo apt update && sudo apt install twiy
|
sudo apt update && sudo apt install twiy
|
||||||
```
|
```
|
||||||
|
|
||||||
## Compile from source
|
## Compile from source by yourself.
|
||||||
|
|
||||||
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
|
```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/
|
apt-get -y install git && cd /root/ && git clone https://git.julio.al/theraw/The-World-Is-Yours.git && cd The-World-Is-Yours/
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
[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
|
||||||
|
BindPaths=/var/cache/nginx
|
||||||
|
BindPaths=/srv
|
||||||
|
BindPaths=/hostdata
|
||||||
|
BindPaths=/raweb
|
||||||
|
|
||||||
|
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
|
||||||
|
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()
|
||||||
|
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -15,56 +15,5 @@ ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|||||||
TimeoutStartSec=10
|
TimeoutStartSec=10
|
||||||
LimitNOFILE=65535
|
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
|
|
||||||
BindPaths=/var/cache/nginx
|
|
||||||
BindPaths=/srv
|
|
||||||
BindPaths=/hostdata
|
|
||||||
BindPaths=/raweb
|
|
||||||
|
|
||||||
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
|
|
||||||
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()
|
|
||||||
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
[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
|
||||||
|
BindPaths=/var/cache/nginx
|
||||||
|
BindPaths=/srv
|
||||||
|
BindPaths=/hostdata
|
||||||
|
BindPaths=/raweb
|
||||||
|
|
||||||
|
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
|
||||||
|
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()
|
||||||
|
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -15,56 +15,5 @@ ExecStop=/bin/sh -c "/bin/kill -s QUIT $(/bin/cat /run/nginx.pid)"
|
|||||||
TimeoutStartSec=10
|
TimeoutStartSec=10
|
||||||
LimitNOFILE=65535
|
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
|
|
||||||
BindPaths=/var/cache/nginx
|
|
||||||
BindPaths=/srv
|
|
||||||
BindPaths=/hostdata
|
|
||||||
BindPaths=/raweb
|
|
||||||
|
|
||||||
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
|
|
||||||
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()
|
|
||||||
# ProtectSystem and ProtectHome are redundant under TemporaryFileSystem=/.
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
Reference in New Issue
Block a user