Saturday, May 09, 2026 AM03:21:24 HKT

This commit is contained in:
2026-05-09 03:21:32 +08:00
commit 41f17b127c
884 changed files with 263824 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
# ENDGAME V3.5
This is the third and a half edition of Endgame. The most popular anti-ddos solution on the darknet.
EndGame is
- a front system designed to protect the core application servers on an onion service in a safe and private way.
- locally complied and locally run (no trusted or middle party).
- a combination of multiple different technologies working together in harmony (listed below).
- FREE FOR ALL TO USE!
- *arguably* magic ㄟ( ▔, ▔ )ㄏ
## Main Features
- Fully scripted and easily deploy-able (for mass scaling!) on blank Debian 12 systems.
- Full featured NGINX LUA script to filter packets and provide a captcha directly using the NGINX layer.
- Rate limiting via Tor's V3 onion service circuit ID system with secondary rate limiting based on a testcookie like system.
- Easy Configuration for both local and remote (over Tor) front systems.
- Easily configurable and change-able to meet an onion service's needs.
- Hardening and compromise check processes (fail2ban, rkhunter, debsecan)
- Captcha processes and a captcha built in rust with zero runtime dependencies!
- Various updates and security improvements in the lua script (it now sends you back to the queue if you fail 3 captchas)
- Caching of nginx modules for faster deployment!
- LOTS of kernel tweaks for both hardening and more efficient memory allocation for Tor
- Fresh html and css that makes it very clear you are using the latest endgame!
- Includes an onionbalance process completely written in go built for high traffic sites (see it in the sourcecode folder)
- Includes a tor patch to require some minimum POW work for all introduction requests (stopping the introduction cell DDOS attacks bites)
It can also:
- Cause you to grow a bigger dick than the asshole DDOSER (true *figurally*, lies *probably*)
- Save you millions of dollars do to DDOSER's downing your site for ransom or for their extorting fees.
- Make it look like you know what the fuck you are doing.
## How it works
EndGame is a FRONT system. That is to say it filters the requests that a service will receive, blocks bad requests, and only passes good ones to the application server.
At a request level it works like this:
`USER -> Tor -> Endgame Front -> Tor(optional) -> Backend (origin) Application Server`
*Endgame should be on a separate isolated server to your backend server.* It only proxies content from your backend to the user. You will still need to configure your backend to handle requests from the Endgame Front.
This is the same system that anti-DDOS services like Cloudflare, Indusface, and Imperva use to protect websites from attacks. The difference is this is self-hosted and fully controlled by you for your own needs and made for darknet networks.
**On Tor, GoBalance (onionbalance) is central to really scale up protection and should be used with EndGame in production environments.**
What GoBalance does is take the various Endgame Front addresses and combine the descriptors together to create a distributed DNS round-robin like system on Tor. This allows for load balancing and prevents a single front from being overloaded. With GoBalance you can scale to hundreds of EndGame fronts that users can access from a single master onion (which we call in the configuration MASTERONION). The master onion is the address that GoBalance uses to sign and publish to the Tor network.
If you want to learn more about how GoBalance works go and read the [onionbalance documentation](https://onionbalance.readthedocs.io/en/latest/index.html). GoBalance is an improved fork of it written in go. To learn more about what makes Gobalance different go into the sourcecode directory and open the GoBalance folder.
You can use Endgame without Gobalance (or onionbalance) but the protection would be limited by the single EndGame front. **YOU CAN NOT USE POW (or THE POW PATCH) WITH GOBALANCE!**
## Setup Process
If you want to use Gobalance, so you can load balance the requests coming in and get the real scalable protection, follow the parts below. If you don't skip to step 3 after setup 1.
1. [Download the Latest EndGame Source from Dread](http://dreadytofatroptsdj6io7l3xptbet6onoyno2yv7jicoxknyazubrad.onion/d/endgame). Verify the archive signature and that it matches what is signed by /u/Paris. Extract the archive to your local machine. DO NOT BLINDLY USE ENDGAME FROM A RANDOM GITHUB REPO YOU FOUND. DON'T BE STUPID.
2. Go to sourcecode/gobalance and build gobalance with [go](https://go.dev). Read the README.md about how to compile and generate the gobalance configuration. With that configuration you will be able to see your MASTERONION url. The starting before .key is your master onion address. You will use that as your MASTERONION in the EndGame.config ending it with '.onion'.
3. Open up and edit the endgame.config, you will need to change your TORAUTHPASSWORD. Change it to a random alphanumeric password of your choice. This is just used for authentication on nginx's layer to send circuit kill commands.
4. You have two options for how EndGame sends the traffic to your backend. You can have it direct it to an onion address, or you can have it locally proxy to a server on the same network.
1. Tor Proxy: You will need to set both of the BACKENDONION variables to your main onion service you want protected. This means your origin application server needs to have tor running with its own onion service address. You put that onion address on the BACKENDONION(1/2). If you have multiple backends (highly recommended) you can put different backend addresses to have load balancing and fallover. It's easy to add in even more by customizing endgame for your needs.
2. Local Proxy: Change LOCALPROXY to true and edit the PROXYPASSURL to the specific IP or hostname of your backend location. It will default to connect on port 80 via http but you can edit line 320 of the site.conf to change that to your specific needs.
5. Enable TORSETUP by setting them to true. You can also enable TORINTRODEFENSE and TORPOWDEFENSE to provide more protection against introduction attacks on the Tor network. If you enable TOR POW you can not use endgame with any onionbalance.
6. Edit KEY and SALT to a secure cookie value. PROTECT THESE VALUES. If they get leaked, an attacker could generate EndGame cookies and kill your EndGame protection.
1. KEY: is your encryption key used for encryption. It should be to be between 68 and 128 random alphanumeric characters.
2. SALT: is your salt for the encryption key. It must be exactly 8 alphanumeric characters.
7. Branding is important. EndGame makes it easy to use your own branding on it. By default, it will use dread's branding, but you should change it.
1. HEXCOLOR and HEXCOLORDARK are for the specific colors used on the pages. Set HEXCOLOR to your main site color and HEXCOLORDARK to just a slightly darker version of it.
2. SITENAME, SITETAGLINE, SITESINCE is all information about your site. Self-explanatory.
3. FAVICON is used as your site's favicon in base64. This limits the amount of requests a browser may do when first loading the queue page. Make sure this value is set to something. Otherwise people's connections will get cut off from the queue when their browser makes a request to the favicon.ico.
4. SQUARELOGO is used as the icon for the queue running man and the main splash logo on the captcha page. In base64 format.
5. NETWORKLOGO is used as a bottom network icon for on the captcha page which allows different sites a part of the same organization to be shown. In base64 format.
8. After you are done EndGame's configuration, you should archive everything except the sourcecode folder. Transfer the archive to a blank debian 12 system. As root, extract the archive and run setup.sh like './setup.sh'. At the end of the setup, it will export an onion address which you can provide to users or add to your gobalance configuration.
9. Go out into the world knowing your service is protected by the best and most tested anti-DDOS solution for the darknet.
### Tech Overview
EndGame uses a number of open-source projects (and libraries) to work properly.
Projects:
* [NGINX](https://NGINX.org/) - NGINX! A web server *obviously* to provide the packet handling, threading, and proxying.
* [Tor](https://www.torproject.org/) - Tor is free and open-source software for enabling anonymous communication. It's awesome and makes all this possible.
* [STEM](https://stem.torproject.org/) - A python controller for Tor.
* [NYX](https://nyx.torproject.org/) - A command-line monitor for Tor (to easily check the EndGame front's Tor process.
* [GoBalance](http://yylovpz7taca7jfrub3wltxabzzjp34fngj5lpwl6eo47ekt5cxs6mid.onion/n0tr1v/gobalance) - A distributed DNS round-robin like system on Tor to allow load-balancing and eliminate single points of failure.
* [OpenSSL](https://www.openssl.org/) - A dependency for a lot of this projects and libraries.
* [Socat](http://www.dest-unreach.org/socat/) - Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. (used for backend tor proxying)
Hardening Projects:
* [Fail2ban](https://www.fail2ban.org/) - A set of server and client programs to limit brute force authentication attempts. (automatically configured)
* [Rkhunter](http://rkhunter.sourceforge.net/) - rkhunter is a shell script which carries out various checks on the local system to try and detect known rootkits and malware.
* [Chkrootkit](https://www.chkrootkit.org/) - chkrootkit is a tool to locally check for signs of a rootkit.
NGINX Modules:
* [NAXSI](https://github.com/nbs-system/naxsi) - A high performance web application firewall for NGINX.
* [Headers More](https://github.com/openresty/headers-more-NGINX-module) - A module for better control of headers in NGINX.
* [Echo NGINX](https://github.com/openresty/echo-nginx-module) - A NGINX module which allows shell style commands in the NGINX configuration file.
* [LUA NGINX](https://github.com/openresty/lua-nginx-module) - The power of LUA into NGINX via a module. This allows all the scripting, packet filtering, and captcha functionality EndGame does.
* [NGINX Development Kit](https://github.com/vision5/ngx_devel_kit) - Development Kit for NGINX (dependency)
Libraries:
* [LUAJIT2 NGINX](https://github.com/openresty/luajit2) - Just in time compiler for LUA.
* [LUA Resty String](https://github.com/openresty/lua-resty-string) - String functions for ngx_lua and LUAJIT2
* [LUA Resty Cookie](https://github.com/cloudflare/lua-resty-cookie) - Provides cookie manipulation
* [LUA Resty Session](https://github.com/bungle/lua-resty-session) - Provides session manipulation
* [LUA Resty AES](https://github.com/c64bob/lua-resty-aes/raw/master/lib/resty/aes_functions.lua) - AES Functions file for LUA. Used for shared session cookies.
+11
View File
@@ -0,0 +1,11 @@
Package: *
Pin: release a=bookworm
Pin-Priority: 500
Package: linux-image-amd64
Pin: release a=unstable
Pin-Priority: 1000
Package: *
Pin: release a=unstable
Pin-Priority: 100
+1
Submodule dependencies/echo-nginx-module added at 4eeda3c449
Submodule dependencies/headers-more-nginx-module added at 84a65d6868
+1
Submodule dependencies/lua-nginx-module added at 4e40c1314f
+1
Submodule dependencies/lua-resty-cookie added at f418d77082
+1
Submodule dependencies/lua-resty-session added at f4b773244f
+1
Submodule dependencies/lua-resty-string added at c6b4348f53
Vendored Submodule
+1
Submodule dependencies/luajit2 added at afc74313c6
Binary file not shown.
+135
View File
@@ -0,0 +1,135 @@
---
Language: Cpp
# BasedOnStyle: Mozilla
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Mozilla
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
+7
View File
@@ -0,0 +1,7 @@
*.txt linguist-detectable=false
*.conf linguist-detectable=false
*.script linguist-detectable=false
*.install linguist-detectable=false
*.sh linguist-detectable=false
*.py linguist-detectable=false
*.t linguist-detectable=false
+27
View File
@@ -0,0 +1,27 @@
---
name: Bug report
about: Describe the issue
title: 'Change me'
labels: bug
assignees: wargio
---
**Details**
- NGINX version: `X.Y.Z`
- NAXSI version: `X.Y`
- Did you install NAXSI from a package manager? **YES/NO**
- Operating System: `XXX Linux`
**Nginx Logs**
```
Copy and paste here the logs
```
**Additional details**
Add any other detail about the problem here.
+87
View File
@@ -0,0 +1,87 @@
name: "CI Unit Tests & Efficacy"
on:
push:
branches:
- main
pull_request:
paths:
- 'naxsi_src/**'
- 'unit-tests/**'
- 'distros/**'
# Automatically cancel any previous workflow on new push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
build-sys:
strategy:
fail-fast: false
matrix:
container:
- fedora:37
- fedora:38
- fedora:39
name: libinjection-system ${{ matrix.container }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: Checkout repository without submodule
uses: actions/checkout@v4
- name: Install system libinjection
run: |
sudo dnf -y install libinjection \
libinjection-devel \
pcre2-devel pcre2 \
zlib-devel zlib \
make automake gcc \
wget openssl
- name: Build
run: /bin/bash .scripts/ci-build.sh "1.25.1"
build-test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
nginx:
- 1.27.0
- 1.26.1
- 1.25.1
- 1.24.0
- 1.23.4
- 1.22.0
- 1.21.5
- 1.20.2
- 1.18.0
- 1.16.1
- 1.14.2
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Build
run: /bin/bash .scripts/ci-build.sh "${{ matrix.nginx }}"
- name: Unit Tests
run: /bin/bash .scripts/ci-test.sh
build-efficacy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Build
run: /bin/bash .scripts/ci-build.sh "1.25.1"
- name: Run WAF efficacy tests (core only)
run: /bin/bash .scripts/ci-wafefficacy.sh core
- name: Run WAF efficacy tests (complete)
run: /bin/bash .scripts/ci-wafefficacy.sh complete
@@ -0,0 +1,69 @@
name: "CodeQL"
on:
push:
branches:
- main
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
paths:
- 'naxsi_src/**'
schedule:
- cron: '42 17 * * 2'
# Automatically cancel any previous workflow on new push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: 'cpp'
- name: Autobuild
run: .scripts/ci-build.sh "1.23.0"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
output: "reports"
upload: false
- name: Move file to merged.sarif (CodeQL)
run: mv reports/*.sarif merged.sarif
- name: Exclude NGINX source
run: |
jq 'del(.runs[].results[].locations[] | select(.physicalLocation.artifactLocation.uri | contains("nginx-source/")))' merged.sarif > tmp0.sarif
jq 'del(.runs[].results[] | select(.locations | length == 0))' tmp0.sarif > filtered.sarif
- name: Treat warnings as errors
run: |
jq '.runs[].tool.driver.rules[] |= . + {"defaultConfiguration": {"level": "error"}}' filtered.sarif > final.sarif
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: final.sarif
+282
View File
@@ -0,0 +1,282 @@
name: "CI for distros"
on:
push:
branches:
- main
- "dist-*"
tags:
- v*
pull_request:
branches:
- "dist-*"
paths:
- 'naxsi_src/**'
- 'unit-tests/**'
- 'distros/**'
# Automatically cancel any previous workflow on new push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
tarball:
runs-on: ubuntu-latest
name: "Release Tarball"
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Prepare Release
shell: bash
run: |
if [[ "${{ startsWith(github.event.ref, 'refs/tags')}}" = "true" ]]
then
RELEASE_ID="${{ github.event.ref }}"
else
RELEASE_ID="git-`date "+%Y-%m-%d"`-`git rev-parse --short HEAD`"
fi
RELEASE_ID=${RELEASE_ID##refs/tags/}
echo RELEASE_NAME="naxsi-${RELEASE_ID}-src-with-deps-tgz" >> $GITHUB_ENV
export TARNAME="naxsi-${RELEASE_ID}-src-with-deps.tar.gz"
touch "$TARNAME"
rm -rf .git
tar --exclude="$TARNAME" -czvf "$TARNAME" .
- name: Upload tarball
uses: actions/upload-artifact@v3
with:
name: ${{ env.RELEASE_NAME }}
path: ./*.tar.gz
zip:
runs-on: ubuntu-latest
name: "Release Zip"
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Prepare Release
shell: bash
run: |
if [[ "${{ startsWith(github.event.ref, 'refs/tags')}}" = "true" ]]
then
RELEASE_ID="${{ github.event.ref }}"
else
RELEASE_ID="git-`date "+%Y-%m-%d"`-`git rev-parse --short HEAD`"
fi
RELEASE_ID=${RELEASE_ID##refs/tags/}
echo RELEASE_NAME="naxsi-${RELEASE_ID}-src-with-deps-zip" >> $GITHUB_ENV
rm -rf .git
- name: Upload zip
uses: actions/upload-artifact@v3
with:
name: ${{ env.RELEASE_NAME }}
path: ./*
packages:
runs-on: ubuntu-latest
name: ${{ matrix.name }}
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
name:
[
"arch-linux",
"debian-buster",
"debian-bullseye",
"debian-bookworm",
"ubuntu-focal",
"ubuntu-jammy",
"alpine-3.17.4",
"alpine-3.18.2",
]
include:
- name: arch-linux
container: archlinux:latest
package: arch
- name: debian-buster
container: debian:buster
package: deb
pcredep: libpcre3-dev
nginxdep: nginx-common
- name: debian-bullseye
container: debian:bullseye
package: deb
pcredep: libpcre3-dev
nginxdep: nginx-common
- name: debian-bookworm
container: debian:bookworm-slim
package: deb
pcredep: libpcre2-dev
nginxdep: nginx
- name: ubuntu-focal
container: ubuntu:focal
package: deb
pcredep: libpcre3-dev
nginxdep: nginx-common
- name: ubuntu-jammy
container: ubuntu:jammy
package: deb
pcredep: libpcre3-dev
nginxdep: nginx-common
- name: alpine-3.17.4
container: alpine:3.17.4
package: apk
- name: alpine-3.18.2
container: alpine:3.18.2
package: apk
steps:
- name: Checkout repository
uses: actions/checkout@v4
# APK package
- name: Install required dependencies
if: matrix.package == 'apk'
run: apk add alpine-sdk doas
- name: Checkout needed repos
if: matrix.package == 'apk'
run: |
rm -rf naxsi_src/libinjection
git clone https://github.com/libinjection/libinjection.git naxsi_src/libinjection
git -C naxsi_src/libinjection checkout b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9
chmod 777 .
- name: ${{ matrix.name }} package
if: matrix.package == 'apk'
run: sh ./distros/alpine/build-ci.sh
- name: Test apk package
if: matrix.package == 'apk'
run: |
apk add --no-cache nginx
apk add --allow-untrusted build/*.apk
- name: Upload apk package
if: matrix.package == 'apk'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}
path: build/*.apk
# DEB package
- name: Update OS & Install deps
if: matrix.package == 'deb'
run: |
if [ -f "/etc/apt/sources.list" ]; then
cat /etc/apt/sources.list > /tmp/sources.list.orig
cat /tmp/sources.list.orig | grep -v "#" | sed 's/^deb /deb-src /g' >> /etc/apt/sources.list
fi
apt-get -qqy update
DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install \
build-essential \
ca-certificates \
dpkg-dev \
gzip \
git \
libgd-dev \
libgeoip-dev \
${{ matrix.pcredep }} \
libperl-dev \
libssl-dev \
libxslt1-dev \
nginx \
tar \
wget \
zlib1g-dev
if [ -f "/etc/apt/sources.list.d/debian.sources" ]; then
# bookworm only.
echo "deb https://ftp.debian.org/debian/ bookworm contrib main non-free non-free-firmware" >> /etc/apt/sources.list.d/nginx.list
echo "deb-src https://ftp.debian.org/debian/ bookworm contrib main non-free non-free-firmware" >> /etc/apt/sources.list.d/nginx.list
apt-get -qqy update
DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install \
libperl-dev
fi
- name: Checkout needed repos
if: matrix.package == 'deb'
run: |
rm -rf naxsi_src/libinjection
git clone https://github.com/libinjection/libinjection.git naxsi_src/libinjection
git -C naxsi_src/libinjection checkout b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9
git clone --depth=1 https://github.com/wargio/deb-creator.git
chmod 777 .
apt-get source nginx
- name: ${{ matrix.name }} package
if: matrix.package == 'deb'
run: |
mkdir -p deb_pkg/
DEB_PKG=$(realpath deb_pkg)
NGINX_PACKAGE="${{ matrix.nginxdep }}"
NAXSI_VERSION=$(grep "NAXSI_VERSION" naxsi_src/naxsi_const.h | cut -d ' ' -f3 | sed 's/"//g')
LIBPCRE_PACKAGE="${{ matrix.pcredep }}"
LIBPCRE_VERSION=$(dpkg -s ${{ matrix.pcredep }} | grep '^Version:' | cut -d ' ' -f2 | cut -d '-' -f1)
NGINX_VERSION=$(dpkg -s nginx | grep '^Version:' | cut -d ' ' -f2 | cut -d '-' -f1)
NGINX_BUILD_OPTS=$(nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g')
echo "NGINX_VERSION: $NGINX_VERSION"
echo "NGINX_BUILD_OPTS: $NGINX_BUILD_OPTS"
# build module
cd nginx-$NGINX_VERSION
CMDLINE=$(echo ./configure $NGINX_BUILD_OPTS --add-dynamic-module=../naxsi_src/)
eval $CMDLINE
make modules
cd ..
# install files
mkdir -p "$DEB_PKG/data/usr/lib/nginx/modules/"
mkdir -p "$DEB_PKG/data/usr/share/nginx/modules-available/"
mkdir -p "$DEB_PKG/data/usr/share/naxsi/whitelists"
mkdir -p "$DEB_PKG/data/usr/share/naxsi/blocking"
install -Dm755 distros/deb/postinstall.script "$DEB_PKG/postinstall.script"
install -Dm755 distros/deb/postremove.script "$DEB_PKG/postremove.script"
install -Dm755 distros/deb/preremove.script "$DEB_PKG/preremove.script"
install -Dm644 distros/deb/control.install "$DEB_PKG/control.install"
install -Dm755 "nginx-$NGINX_VERSION/objs/ngx_http_naxsi_module.so" "$DEB_PKG/data/usr/lib/nginx/modules/ngx_http_naxsi_module.so"
install -Dm644 distros/deb/mod-http-naxsi.conf "$DEB_PKG/data/usr/share/nginx/modules-available/mod-http-naxsi.conf"
install -Dm644 distros/nginx/naxsi_block_mode.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_block_mode.conf"
install -Dm644 distros/nginx/naxsi_denied_url.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_denied_url.conf"
install -Dm644 distros/nginx/naxsi_learning_mode.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_learning_mode.conf"
install -Dm644 naxsi_rules/naxsi_core.rules "$DEB_PKG/data/usr/share/naxsi/naxsi_core.rules"
install -Dm644 naxsi_rules/whitelists/*.rules "$DEB_PKG/data/usr/share/naxsi/whitelists"
install -Dm644 naxsi_rules/blocking/*.rules "$DEB_PKG/data/usr/share/naxsi/blocking"
# add deb details.
sed -i "s/@NGINX_PACKAGE@/$NGINX_PACKAGE/" "$DEB_PKG/control.install"
sed -i "s/@NGINX_VERSION@/$NGINX_VERSION/" "$DEB_PKG/control.install"
sed -i "s/@LIBPCRE_PACKAGE@/$LIBPCRE_PACKAGE/" "$DEB_PKG/control.install"
sed -i "s/@LIBPCRE_VERSION@/$LIBPCRE_VERSION/" "$DEB_PKG/control.install"
sed -i "s/@NAXSI_VERSION@/$NAXSI_VERSION/" "$DEB_PKG/control.install"
# build deb file
./deb-creator/deb-creator "$DEB_PKG"
- name: Test deb package
if: matrix.package == 'deb'
run: dpkg -i deb_pkg/*.deb
- name: Upload deb package
if: matrix.package == 'deb'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}
path: deb_pkg/*.deb
# Arch Linux package
- name: ${{ matrix.name }} package
if: matrix.package == 'arch'
run: |
pacman -Syy --needed --noconfirm sudo base-devel git perl-rename
chmod 777 distros/arch
useradd build-user -m
passwd -d build-user
printf 'build-user ALL=(ALL) ALL\n' | tee -a /etc/sudoers
cd distros/arch
sudo -u build-user makepkg -s --noconfirm
# Fix package name due github name restrictions
perl-rename -v 's/:/-/g' *.pkg.tar.zst
- name: Test arch package
if: matrix.package == 'arch'
run: pacman -U --noconfirm distros/arch/*.pkg.tar.zst
- name: Upload arch package
if: matrix.package == 'arch'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}
path: distros/arch/*.pkg.tar.zst
+69
View File
@@ -0,0 +1,69 @@
name: "Linters"
on:
push:
branches:
- main
pull_request:
# Automatically cancel any previous workflow on new push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
no-debug:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check debug logs are disabled
run: /bin/bash .scripts/ci-debug-check.sh
distro-ci-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Check if the distro info are updated
run: /bin/bash .scripts/ci-distro-check.sh
licenses:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Reuse Compliance Check
uses: fsfe/reuse-action@v5
with:
args: --suppress-deprecation lint
formatting:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install wget, software-properties-common, lsb-release (dependencies of LLVM install script)
run: sudo apt --assume-yes install wget software-properties-common lsb-release
- name: Install automatic LLVM 16
run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 16
- name: Install clang-format-16
run: sudo apt --assume-yes install clang-format-16
- name: Format check
run: find naxsi_src/ -type f -name "*.c" -o -name "*.h" | grep -v "libinjection" | xargs -I % clang-format --verbose --Werror --dry-run %
rules:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install python3
run: sudo apt --assume-yes install python3
- name: Format check rules
run: |
bash .scripts/ci-rules-linter.sh naxsi_rules/blocking
bash .scripts/ci-rules-linter.sh naxsi_rules/whitelists
+41
View File
@@ -0,0 +1,41 @@
name: "Windows CI Unit Tests"
on:
push:
branches:
- main
pull_request:
paths:
- 'naxsi_src/**'
- 'unit-tests/**'
- 'distros/**'
# Automatically cancel any previous workflow on new push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
build-test:
strategy:
fail-fast: false
matrix:
os: [windows-latest]
nginx:
- 1.24.0
- 1.23.2
- 1.22.1
runs-on: ${{ matrix.os }}
defaults:
run:
shell: cmd
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: Windows build
run: .scripts\ci-windows-build.bat ${{ matrix.nginx }}
- name: Unit Tests
run: .scripts\ci-windows-test.bat
+10
View File
@@ -0,0 +1,10 @@
*.tar.gz
*.asc
nginx-source
nginx-tmp
*.log
.scripts/.tmp/
/naxsi_src/libinjection_ngxbuild/
/unit-tests/python/__pycache__
/unit-tests/python/test_*
*.orig
+3
View File
@@ -0,0 +1,3 @@
[submodule "naxsi_src/libinjection"]
path = naxsi_src/libinjection
url = https://github.com/libinjection/libinjection
+63
View File
@@ -0,0 +1,63 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2022 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
set -e
NGINX_VERSION="$1"
N_CPUS=$(nproc)
if [ -z "$NGINX_VERSION" ]; then
echo "usage: $0 <nginx version>"
echo "example: $0 1.12.2"
exit 1
fi
echo "############################"
echo " NGINX VERSION: $NGINX_VERSION"
echo "############################"
NEW_BUILD=true
if [ -d "nginx-tmp" ] && [ "$NGINX_VERSION" == $(cat nginx-tmp/nginx.version) ]; then
NEW_BUILD=false
fi
if $NEW_BUILD ; then
rm -rf nginx-source nginx-tmp nginx.tar.gz 2>&1 > /dev/null
wget --no-clobber -O nginx.tar.gz "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz"
mkdir -p nginx-source nginx-tmp/naxsi_ut/root
echo "$NGINX_VERSION" > nginx-tmp/nginx.version
tar -C nginx-source -xzf nginx.tar.gz --strip-components=1
rm nginx.tar.gz
fi
export NAXSI_SRC_PATH=$(realpath naxsi_src/)
export NAXSI_TMP_PATH=$(realpath nginx-tmp/)
export NGINX_TMP_PATH=$(realpath nginx-source/)
if $NEW_BUILD ; then
cd "$NGINX_TMP_PATH"
./configure --with-cc-opt='-g -O2 -Wextra -Wall -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' \
--with-select_module \
--conf-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" \
--http-client-body-temp-path="$NAXSI_TMP_PATH/naxsi_ut/body/" \
--http-fastcgi-temp-path="$NAXSI_TMP_PATH/naxsi_ut/fastcgi/" \
--http-proxy-temp-path="$NAXSI_TMP_PATH/naxsi_ut/proxy/" \
--lock-path="$NAXSI_TMP_PATH/nginx.lock" \
--pid-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.pid" \
--modules-path="$NAXSI_TMP_PATH/naxsi_ut/modules/" \
--without-mail_pop3_module \
--without-mail_smtp_module \
--without-mail_imap_module \
--with-http_realip_module \
--with-http_v2_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--prefix="$NAXSI_TMP_PATH/" \
--add-dynamic-module="$NAXSI_SRC_PATH" \
--error-log-path="$NAXSI_TMP_PATH/naxsi_ut/error.log" \
--conf-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
cd ..
fi
make -C "$NGINX_TMP_PATH" -j$N_CPUS install
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2022 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
set -e
N_DEBUGS=$(cat naxsi_src/naxsi.h | grep "#define _debug" | grep 1 | wc -l)
if [ $N_DEBUGS -gt 0 ]; then
cat naxsi_src/naxsi.h | grep "#define _debug" | grep 1
exit 1
fi
+53
View File
@@ -0,0 +1,53 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
set -e
check_file_for() {
local FILENAME="$1"
local SEARCH_FOR="$2"
local EXPECTED="$3"
local FOUND=$(cat "$FILENAME" | grep "$SEARCH_FOR")
if [ -z "$FOUND" ]; then
echo "'$FILENAME' does not contain '$SEARCH_FOR'."
exit 1
fi
local HAS_EXPECTED=$(echo "$FOUND" | grep "$EXPECTED")
if [ -z "$HAS_EXPECTED" ]; then
echo "'$FILENAME' differs with what is expected to have."
echo "Expected: $EXPECTED"
echo "Got: $FOUND"
exit 1
fi
}
# check distro release version.
NAXSI_VERSION=$(grep -R "NAXSI_VERSION" naxsi_src/ | cut -d '"' -f2)
if [ -z "$NAXSI_VERSION" ]; then
echo "Cannot find NAXSI_VERSION in naxsi_src/"
exit 1
fi
check_file_for "distros/arch/PKGBUILD" "pkgver=" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.18.0-r13/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.20.1-r3/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.20.2-r1/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.22.1-r0/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.18.0-r15/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.20.2-r0/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.22.0-r1/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
check_file_for "distros/alpine/1.24.0-r3/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION"
# check libinjection hash
SUBMODULE_HASH=$(git -C naxsi_src/libinjection rev-parse HEAD)
for DISTRO_YAML_HASH in $(grep "git -C naxsi_src/libinjection checkout" .github/workflows/distros.yaml | xargs -L1 echo | cut -d ' ' -f5); do
if [ "$DISTRO_YAML_HASH" != "$SUBMODULE_HASH" ]; then
echo "The libinjection hash in .github/workflows/distros.yaml does not match the submodule one."
echo "Expected: $SUBMODULE_HASH"
echo "Got: $DISTRO_YAML_HASH"
echo ".github/workflows/distros.yaml:"
grep -n "$DISTRO_YAML_HASH" .github/workflows/distros.yaml
exit 1
fi
done
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2022 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
RULE_FOLDER="$1"
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
TMP_DIR="$SCRIPT_DIR/.tmp"
RET_VAL=0
if [ -z "$RULE_FOLDER" ]; then
echo "usage: $0 <rule folder>"
echo "example: $0 naxsi_rules/blocking"
exit 1
fi
if [[ -d "$TMP_DIR" ]]; then
rm -rf "$TMP_DIR"
fi
mkdir "$TMP_DIR" || exit 1
for FILE in $(ls "$RULE_FOLDER/"*.rules); do
FILENAME=$(basename $FILE)
echo "Linter: $FILE"
python "$SCRIPT_DIR/naxsi-lint.py" -r "$FILE" -o "$TMP_DIR/$FILENAME" || exit 1
DIFF=$(diff -u "$FILE" "$TMP_DIR/$FILENAME")
if [[ ! -z "$DIFF" ]]; then
diff -u --color=auto "$FILE" "$TMP_DIR/$FILENAME"
RET_VAL=1
fi
done
rm -rf "$TMP_DIR"
exit $RET_VAL
+37
View File
@@ -0,0 +1,37 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2022 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
RUN_TEST="$1"
export NAXSI_CFG_PATH=$(realpath naxsi_rules/)
export NAXSI_TMP_PATH=$(realpath nginx-tmp/)
export NAXSI_TST_PATH=$(realpath unit-tests/)
if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_TST_PATH" ] ; then
echo "did you run first ci-build.sh ?"
exit 1
fi
echo "############################"
echo " running tests"
echo "############################"
cp -v "$NAXSI_TST_PATH/nginx-ci.conf" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
openssl req -batch -x509 -nodes -days 365 -newkey rsa:2048 -keyout "$NAXSI_TMP_PATH/nginx.key" -out "$NAXSI_TMP_PATH/nginx.crt"
export PATH="$NGINX_TMP_PATH/objs/:$PATH"
export TEST_NGINX_SERVROOT="$NAXSI_TMP_PATH/naxsi_ut/root"
export TEST_NGINX_BINARY="$NAXSI_TMP_PATH/sbin/nginx"
export TEST_NGINX_NAXSI_MODULE_SO="$NAXSI_TMP_PATH/naxsi_ut/modules/ngx_http_naxsi_module.so"
export TEST_NGINX_NAXSI_RULES="$NAXSI_CFG_PATH/naxsi_core.rules"
export TEST_NGINX_NAXSI_BLOCKING_RULES="$NAXSI_CFG_PATH/blocking"
export TEST_NGINX_NAXSI_WHITELISTS_RULES="$NAXSI_CFG_PATH/whitelists"
cd "$NAXSI_TMP_PATH"
if [ -z "$RUN_TEST" ]; then
prove -r "$NAXSI_TST_PATH/tests/"*.t
else
prove --verbose -r "$NAXSI_TST_PATH/tests/$RUN_TEST"
fi
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2022 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
RUN_TEST="$1"
if command -v python3 &> /dev/null ; then
PYTHON=python3
elif command -v python &> /dev/null ; then
PYTHON=python
else
echo "Cannot find python.."
exit 1
fi
export NAXSI_CFG_PATH=$(realpath naxsi_rules/)
export NAXSI_TMP_PATH=$(realpath nginx-tmp/)
export NAXSI_TST_PATH=$(realpath unit-tests/)
if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_TST_PATH" ] ; then
echo "did you run first ci-build.sh ?"
exit 1
fi
echo "############################"
echo " running tests"
echo "############################"
cp -v "$NAXSI_TST_PATH/nginx-ci.conf" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
openssl req -batch -x509 -nodes -days 365 -newkey rsa:2048 -keyout "$NAXSI_TMP_PATH/nginx.key" -out "$NAXSI_TMP_PATH/nginx.crt"
$PYTHON .scripts/naxsi-gen-tests.py
$PYTHON -m unittest discover ./unit-tests/python/ $RUN_TEST -v
+116
View File
@@ -0,0 +1,116 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 wargio <deroad@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
set -e
WAFEFFICACY_VERSION="v1.0"
NUCLEI_VERSION="2.9.6"
case "$1" in
"core" | "complete")
;;
*)
if [ -z "$1" ]; then
echo "usage: $0 [mode]"
else
echo "error: invalid mode option '$1'."
fi
echo "supported modes:"
echo " - core test efficacy only against naxsi_core.rules"
echo " - complete test efficacy against all rules"
exit 1
;;
esac
export NAXSI_CFG_PATH=$(realpath naxsi_rules)
export NAXSI_TMP_PATH=$(realpath nginx-tmp)
export NAXSI_DST_PATH=$(realpath distros/nginx)
export NAXSI_TST_PATH=$(realpath unit-tests/)
export NAXSI_VERSION=$(grep -R "NAXSI_VERSION" naxsi_src/ | cut -d '"' -f2)
export NAXSI_MODE="$1"
check_for() {
if [ "$1" == "f" ] && [ ! -f "$2" ]; then
echo "file '$1' does not exist!"
exit 1
elif [ "$1" == "d" ] && [ ! -d "$2" ]; then
echo "directory '$1' does not exist!"
exit 1
fi
}
if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_DST_PATH" ] ; then
echo "did you run first ci-build.sh ?"
exit 1
fi
if [ ! -d "$NAXSI_TMP_PATH/wafefficacy" ]; then
mkdir -p "$NAXSI_TMP_PATH/wafefficacy-tmp"
OLDPATH="$PWD"
cd "$NAXSI_TMP_PATH/wafefficacy-tmp"
# install wafefficacy
wget -O wafefficacy.zip "https://github.com/wargio/wafefficacy/releases/download/$WAFEFFICACY_VERSION/wafefficacy-linux-amd64.zip"
unzip wafefficacy.zip
mv -v wafefficacy-release "$NAXSI_TMP_PATH/wafefficacy"
cd "$OLDPATH"
rm -rf "$NAXSI_TMP_PATH/wafefficacy-tmp"
fi
if [ ! -f "$NAXSI_TMP_PATH/sbin/nuclei" ]; then
mkdir -p "$NAXSI_TMP_PATH/nuclei-tmp"
OLDPATH="$PWD"
cd "$NAXSI_TMP_PATH/nuclei-tmp"
# install nuclei
wget -O nuclei.zip "https://github.com/projectdiscovery/nuclei/releases/download/v$NUCLEI_VERSION/nuclei_""$NUCLEI_VERSION""_linux_amd64.zip"
unzip nuclei.zip || sleep 0
mv -v nuclei "$NAXSI_TMP_PATH/sbin/"
cd "$OLDPATH"
rm -rf "$NAXSI_TMP_PATH/nuclei-tmp"
fi
echo "############################"
echo " running wafefficacy"
echo "############################"
if [ ! -d "$NAXSI_TMP_PATH/naxsi_ut/logs" ]; then
mkdir -p "$NAXSI_TMP_PATH/naxsi_ut/logs"
fi
WAFEFFICACY_NGINX_CONF=$(realpath "$NAXSI_TST_PATH/nginx-ci-wafefficacy.conf")
RULES_NGINX_NAXSI_BLOCKING=$(realpath "$NAXSI_CFG_PATH/blocking")
RULES_NGINX_NAXSI_CORE=$(realpath "$NAXSI_CFG_PATH/naxsi_core.rules")
RULES_NGINX_NAXSI_WHITELISTS=$(realpath "$NAXSI_CFG_PATH/whitelists")
TEST_NGINX_NAXSI_MODULE_SO=$(realpath "$NAXSI_TMP_PATH/naxsi_ut/modules/ngx_http_naxsi_module.so")
check_for "f" "$WAFEFFICACY_NGINX_CONF"
check_for "f" "$TEST_NGINX_NAXSI_MODULE_SO"
check_for "f" "$RULES_NGINX_NAXSI_CORE"
check_for "d" "$RULES_NGINX_NAXSI_WHITELISTS"
check_for "d" "$RULES_NGINX_NAXSI_BLOCKING"
cp -v "$WAFEFFICACY_NGINX_CONF" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
sed -i "s#@RULES_NGINX_NAXSI_CORE@#include $RULES_NGINX_NAXSI_CORE;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
sed -i "s#@TEST_NGINX_NAXSI_MODULE_SO@#$TEST_NGINX_NAXSI_MODULE_SO#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
case "$1" in
"core")
sed -i "s#@RULES_NGINX_NAXSI_BLOCKING@##g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
sed -i "s#@RULES_NGINX_NAXSI_WHITELISTS@##g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
;;
"complete")
sed -i "s#@RULES_NGINX_NAXSI_BLOCKING@#include $RULES_NGINX_NAXSI_BLOCKING/*;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
sed -i "s#@RULES_NGINX_NAXSI_WHITELISTS@#include $RULES_NGINX_NAXSI_WHITELISTS/*;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf"
;;
*)
echo "error: invalid mode option '$1'."
exit 1
;;
esac
cd "$NAXSI_TMP_PATH/wafefficacy"
"$NAXSI_TMP_PATH/sbin/nginx" -p "$NAXSI_TMP_PATH/naxsi_ut/" &
PATH="$PATH:$NAXSI_TMP_PATH/sbin" ./run.sh -w "naxsi-$NAXSI_VERSION" -t localhost:4242
jobs -p | xargs kill
+30
View File
@@ -0,0 +1,30 @@
@echo off
rem SPDX-FileCopyrightText: 2022 Alex <alex@staticlibs.net>
rem SPDX-License-Identifier: LGPL-3.0-only
@echo on
set BAD_SLASH_SCRIPT_DIR=%~dp0
set SCRIPT_DIR=%BAD_SLASH_SCRIPT_DIR:\=/%
set NAXSI_DIR=%SCRIPT_DIR%..
set NW_DIR=%NAXSI_DIR%/../nginx-windows
set NGINX_VERSION=%1
pushd .. || exit /b 1
git clone --branch 1.22.1-1 https://github.com/noproxy-http/nginx-windows.git || exit /b 1
popd || exit /b 1
pushd "%NW_DIR%" || exit /b 1
git submodule update --init || exit /b 1
popd || exit /b 1
pushd "%NW_DIR%/sources/nginx" || exit /b 1
git checkout release-%NGINX_VERSION% || exit /b 1
popd || exit /b 1
robocopy %NAXSI_DIR%/naxsi_src %NW_DIR%/modules/naxsi_src /e /nfl /ndl /njh /njs /nc /ns /np
pushd "%NW_DIR%" || exit /b 1
scripts\build.bat "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat" nossl
popd || exit /b 1
+15
View File
@@ -0,0 +1,15 @@
@echo off
rem SPDX-FileCopyrightText: 2022 Alex <alex@staticlibs.net>
rem SPDX-License-Identifier: LGPL-3.0-only
@echo on
set BAD_SLASH_SCRIPT_DIR=%~dp0
set SCRIPT_DIR=%BAD_SLASH_SCRIPT_DIR:\=/%
set NAXSI_DIR=%SCRIPT_DIR%..
pushd "%NAXSI_DIR%" || exit /b 1
python .scripts/naxsi-windows-test-dist.py %NAXSI_DIR%/../nginx-windows/build/dist || exit /b 1
python .scripts/naxsi-gen-tests.py || exit /b 1
python -m unittest discover unit-tests/python/ -v || exit /b 1
popd || exit /b 1
+434
View File
@@ -0,0 +1,434 @@
# -* coding: utf-8
# SPDX-FileCopyrightText: 2022 Alex <alex@staticlibs.net>
# SPDX-License-Identifier: LGPL-3.0-only
import os, sys
from collections import namedtuple
from os import path, replace
import re
NginxTest = namedtuple("NginxTest", "filename name user_files main_config http_config config more_headers request raw_request curl curl_protocol curl_options error_code, error_log no_error_log response_body")
unique_fun_names = set()
def is_test_file(dirpath, filename):
if not filename.endswith(".t"):
return False
filepath = path.join(dirpath, filename)
return path.isfile(filepath)
def read_list_of_test_files(test_file_or_dir):
if path.isfile(test_file_or_dir):
return [test_file_or_dir]
elif path.isdir(test_file_or_dir):
lst = os.listdir(test_file_or_dir)
filtered = list(filter(lambda f: is_test_file(test_file_or_dir, f), lst))
filtered.sort()
return list(map(lambda f: path.join(test_file_or_dir, f), filtered))
else:
print("ERROR: tests not found in directory: [{}]".format(test_file_or_dir))
sys.exit(1)
def collect_section(lines, idx, dest):
i = idx + 1
while not lines[i].startswith("--- "):
dest.append(lines[i])
i += 1
return i
def trim_test_lines(lines):
last_nonempty_idx = len(lines)
for i in reversed(range(len(lines))):
if len(lines[i]) == 0:
last_nonempty_idx = i
else:
break
return lines[:last_nonempty_idx]
def parse_test(lines, test_file, line_num):
lines = trim_test_lines(lines)
if len(lines) == 0:
return None
filename = path.basename(test_file)
name = lines[0][4:].strip()
user_files = []
main_config = []
http_config = []
config = []
more_headers = []
request = []
raw_request = []
curl = False
curl_protocol = "http"
curl_options = ""
error_code = 0
error_log = []
no_error_log = []
response_body = []
idx = 1
if lines[idx].lstrip().startswith("--- user_files"):
idx = collect_section(lines, idx, user_files)
if lines[idx].lstrip().startswith("--- main_config"):
idx = collect_section(lines, idx, main_config)
if lines[idx].lstrip().startswith("--- main_config"):
idx = collect_section(lines, idx, main_config)
if lines[idx].lstrip().startswith("--- http_config"):
idx = collect_section(lines, idx, http_config)
if lines[idx].lstrip().startswith("--- user_files"):
idx = collect_section(lines, idx, user_files)
if lines[idx].lstrip().startswith("--- config"):
idx = collect_section(lines, idx, config)
if lines[idx].lstrip().startswith("--- more_headers"):
idx = collect_section(lines, idx, more_headers)
if lines[idx].lstrip().startswith("--- request"):
idx = collect_section(lines, idx, request)
if lines[idx].lstrip().startswith("--- raw_request"):
idx = collect_section(lines, idx, raw_request)
if lines[idx].lstrip().startswith("--- curl"):
curl = True
idx = idx + 1
if lines[idx].lstrip().startswith("--- curl_protocol:"):
curl_protocol = lines[idx].strip()[len("--- curl_protocol:"):]
idx = idx + 1
if lines[idx].lstrip().startswith("--- curl_options:"):
curl_options = lines[idx].strip()[len("--- curl_options:"):]
idx = idx + 1
if not lines[idx].lstrip().startswith("--- error_code: "):
print("ERROR: Cannot parse test defintion, file: [{}], line: [{}]".format(test_file, line_num + idx - 2))
sys.exit(1)
prefix_len = len("--- error_code:")
error_code = int(lines[idx].lstrip()[prefix_len:])
if idx < len(lines) - 2 and lines[idx + 1].lstrip().startswith("--- error_log"):
idx += 2
while idx < len(lines) and (not lines[idx].startswith("--- ") or lines[idx].startswith("=== ")):
error_log.append(lines[idx])
idx += 1
idx -= 1
if idx < len(lines) - 2 and lines[idx + 1].lstrip().startswith("--- no_error_log"):
idx += 2
while idx < len(lines) and (not lines[idx].startswith("--- ") or lines[idx].startswith("=== ")):
no_error_log.append(lines[idx])
idx += 1
idx -= 1
if idx < len(lines) - 1 and lines[idx + 1].lstrip().startswith("--- response_body"):
idx+=1
response_body.append(lines[idx][18:].strip())
return NginxTest(filename, name, user_files, main_config, http_config, config, more_headers, request, raw_request, curl, curl_protocol, curl_options, error_code, error_log, no_error_log, response_body)
def read_list_of_tests(test_file):
tests = []
with open(test_file, encoding="utf-8") as file:
data_reached = False
test_lines = []
line_num = 0
for line in file:
line_num += 1
stripped = line.rstrip()
if stripped.startswith("#"):
continue
if not data_reached:
if "__DATA__" == stripped:
data_reached = True
continue
if stripped.startswith("==="):
if len(test_lines) > 0:
test = parse_test(test_lines, test_file, line_num - len(test_lines))
if test is not None:
tests.append(test)
test_lines = []
test_lines.append(stripped)
if len(test_lines) > 0:
test = parse_test(test_lines, test_file, line_num - len(test_lines))
if test is not None:
tests.append(test)
return tests
def format_array_eval_line(line):
line = line[2:-2].strip()
elems = line.split(",")
for i in range(len(elems)):
elems[i] = elems[i].strip()
xidx = elems[i].find("\"x")
if xidx > 0:
base = elems[i][1:xidx]
count = int(elems[i][xidx+2:])
elems[i] = ""
for j in range(count):
elems[i] += base
else:
elems[i] = elems[i][1:-1]
return "".join(elems)
def format_test_lines(test):
for i in range(len(test.http_config)):
test.http_config[i] = test.http_config[i].replace("\\", "\\\\")
test.http_config[i] = " {}".format(test.http_config[i])
for i in range(len(test.config)):
test.config[i] = " {}".format(test.config[i])
request_lines_to_pop = []
for i in range(len(test.request)):
line = test.request[i]
if line.lstrip().startswith("use "):
request_lines_to_pop.append(i)
if line.startswith("[[") and line.endswith("]]"):
test.request[i] = format_array_eval_line(line)
for idx in request_lines_to_pop:
test.request.pop(idx)
if len(test.request) > 0 and test.request[0].startswith("\""):
test.request[0] = test.request[0][1:]
test.request[-1] = test.request[-1][:-1]
for i in range(len(test.request)):
line = test.request[i]
test.request[i] = line.replace("\\\"", "\"").replace("\x00", "\\x00")
if len(test.raw_request) > 0 and test.raw_request[0].startswith("\""):
test.raw_request[0] = test.raw_request[0][1:]
test.raw_request[-1] = test.raw_request[-1][:-1]
for i in range(len(test.raw_request)):
line = test.raw_request[i]
test.raw_request[i] = line.replace("\\\"", "\"")
if len(test.error_log) > 0:
el = test.error_log
for i in range(len(el)):
if el[i].startswith("["):
el[i] = el[i][1:].lstrip()
if el[i].startswith("qr@"):
el[i] = el[i][3:].lstrip()
if el[i].endswith("]"):
el[i] = el[i][:-1].rstrip()
if el[i].endswith(","):
el[i] = el[i][:-1].rstrip()
if el[i].endswith("@"):
el[i] = el[i][:-1].rstrip()
el[i] = el[i].replace("server=localhost", "server=127.0.0.1")
if len(el[-1]) == 0:
el.pop()
if len(test.response_body) > 0:
for i in range(len(test.response_body)):
test.response_body[i] = test.response_body[i].replace("localhost", "127.0.0.1")
def hotpatch_test(test):
if "TEST 24: Testing MULTIPART POSTs" == test.name:
test.more_headers[1] = test.more_headers[1].replace(
"Content-Length: 355",
"Content-Length: 353",
)
def parse_req_method(req):
space_idx = req[0].find(" ")
return req[0][:space_idx]
def parse_req_data(req, method):
if method not in ["POST", "PATCH"]:
return None
rn_idx = req[0].find("\\r\\n")
inline = ""
if rn_idx > 0:
inline = req[0][rn_idx:]
res = inline
if len(req) > 1:
res += "\n".join(req[1:])
if res.startswith("\\r\\n"):
res = res[4:]
if res.endswith("\\r\\n\\r\\n"):
res = res[:-8]
return res
def parse_req_url(req):
space_idx = req[0].find(" ")
rn_idx = req[0].find("\\r\\n")
if rn_idx > 0:
return req[0][space_idx + 1:rn_idx]
else:
return req[0][space_idx + 1:]
def parse_headers(more_headers):
headers = {}
for line in more_headers:
idx = line.find(": ")
name = line[:idx]
value = line[idx + 2:]
headers[name] = value
return headers
def parse_user_files(user_files):
res = {}
name = None
for line in user_files:
stripped = line.strip()
if stripped.startswith(">>> "):
name = stripped[4:]
res[name] = ""
else:
res[name] += line
return res
def gen_file_header(test_file_name_noext):
cls_name = test_file_name_noext[2:].replace("-", "_")
return """# -* coding: utf-8
# SPDX-FileCopyrightText: NAXSI project
# SPDX-License-Identifier: LGPL-3.0-only
import unittest
from _test_utils import nginx_runner
class {}(unittest.TestCase):""".format(cls_name)
def gen_function_header(test):
fun_name = test.name.strip()
fun_name = re.sub(r'[^a-zA-Z\d_]', '_', fun_name)
if not fun_name.startswith("test_"):
fun_name = "test_{}".format(fun_name)
while fun_name in unique_fun_names:
fun_name += "_"
unique_fun_names.add(fun_name)
docstring = test.name.replace("\\x", "\\\\x")
return '''
def {}(self):
"""
{}
"""'''.format(fun_name, docstring)
def gen_runner_init(test):
res = ''' with nginx_runner('''
if len(test.http_config) > 0:
http_config = "\n".join(test.http_config)
res += '''
http_config="""
{}
""",'''.format(http_config)
if len(test.config) > 0:
config = "\n".join(test.config)
res += '''
config="""
{}
""",'''.format(config)
if len(test.user_files) > 0:
res += '''
user_files={'''
files = parse_user_files(test.user_files)
for name, value in files.items():
res += '''
"{}": "{}",'''.format(name, value)
res += '''
},'''
res += '''
) as nr:'''
return res;
def gen_request(test):
if len(test.response_body) > 0:
res = ''' ec, resp_body = nr.request('''
else:
res = ''' ec = nr.request('''
url = parse_req_url(test.request).replace("\"", "\\\"")
res += '''
url="{}",'''.format(url)
method = parse_req_method(test.request)
if "GET" != method:
res += '''
method="{}",'''.format(method)
if len(test.more_headers) > 0:
res += '''
headers={'''
headers = parse_headers(test.more_headers)
for name, value in headers.items():
res += '''
"{}": "{}",'''.format(name, value)
res += '''
},'''
data = parse_req_data(test.request, method)
if data is not None:
res += '''
data="""{}""",'''.format(data)
if test.curl:
res += '''
curl=True,'''
if len(test.curl_protocol) > 0:
res += '''
curl_protocol="{}",'''.format(test.curl_protocol)
if len(test.curl_options) > 0:
res += '''
curl_options="{}",'''.format(test.curl_options)
if len(test.response_body) > 0:
res += '''
resp_body_required=True'''
res += '''
)'''. format(test.error_code)
return res
def gen_raw_request(test):
raw_req = "\n".join(test.raw_request)
return ''' ec = nr.raw_request("""
{}""")'''.format(raw_req)
def gen_checks(test):
res = " self.assertEqual(ec, {})".format(test.error_code)
if len(test.error_log) > 0:
res += '''
elm = nr.error_log_matches(['''
for line in test.error_log:
line = line.replace("\"", "\\\"")
res += '''
r"{}",'''.format(line)
res += '''
])
self.assertTrue(elm)'''
if len(test.no_error_log) > 0:
res += '''
nelm = nr.error_log_matches(['''
for line in test.no_error_log:
line = line.replace("\"", "\\\"")
res += '''
r"{}",'''.format(line)
res += '''
])
self.assertFalse(nelm)'''
if len(test.response_body) > 0:
response_body = "\n".join(test.response_body)
res += '''
self.assertEqual(resp_body, """{}""".encode("utf-8"))'''.format(response_body)
return res
def gen_test_function(test):
header = gen_function_header(test)
runner = gen_runner_init(test)
if len(test.request) > 0:
send_req = gen_request(test)
else:
send_req = gen_raw_request(test)
checks = gen_checks(test)
return '''
{}
{}
{}
{}'''.format(header, runner, send_req, checks)
def write_python_test_file(test_file_name, test_list):
scripts_dir = path.dirname(__file__)
naxsi_dir = path.dirname(scripts_dir)
dest_dir = path.join(naxsi_dir, "unit-tests", "python")
test_file_name_noext = path.splitext(test_file_name)[0]
test_file_name_nodash = test_file_name_noext.replace("-", "_")
dest_file_name = "test_{}.py".format(test_file_name_nodash)
dest_file_path = path.join(dest_dir, dest_file_name)
if path.exists(dest_file_path):
os.remove(dest_file_path)
with open(dest_file_path, "w", encoding="utf-8") as file:
file.write(gen_file_header(test_file_name_noext))
for test in test_list:
hotpatch_test(test)
format_test_lines(test)
file.write(gen_test_function(test))
file.write("\n")
if __name__ == "__main__":
scripts_dir = path.dirname(__file__)
naxsi_dir = path.dirname(scripts_dir)
tests_dir = path.join(naxsi_dir, "unit-tests", "tests")
test_files_list = read_list_of_test_files(tests_dir)
for test_file_path in test_files_list[:]:
unique_fun_names.clear()
test_list = read_list_of_tests(test_file_path)
test_file_name = path.basename(test_file_path)
write_python_test_file(test_file_name, test_list[:])
+249
View File
@@ -0,0 +1,249 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2022 deroad <wargio@libero.it>
# SPDX-License-Identifier: LGPL-3.0-only
import argparse
import sys
import re
import shlex
DESCRIPTION='Naxsi Rule Linter'
EPILOG='''
This tool lints naxsi rules
Example:
$ python naxsi-lint.py --rule /path/to/file.rules --output output.rules --begin-id 4200000
'''
def clean_token(token):
if not token.startswith('"'):
return token
return token[1:-1]
def find_keyword(keyword, tokens):
for token in tokens:
token = clean_token(token)
if token.startswith(keyword):
return token
return None
class Rule(object):
def __init__(self, tokens, line_num, comments):
super(Rule, self).__init__()
self.line_num = line_num
self.comments = comments
self.main_rule = find_keyword("MainRule", tokens)
self.basic_rule = find_keyword("BasicRule", tokens)
self.id = find_keyword("id:", tokens)
self.msg = find_keyword("msg:", tokens)
self.str = find_keyword("str:", tokens)
self.rx = find_keyword("rx:", tokens)
self.mz = find_keyword("mz:", tokens)
self.s = find_keyword("s:", tokens)
self.wl = find_keyword("wl:", tokens)
self.d = find_keyword("d:libinj_", tokens)
self.negative = find_keyword("negative", tokens)
# validate first
self.validate()
if self.wl != None:
ids = list(set(self.wl[3:].split(',')))
ids.sort()
self.wl = 'wl:' + ','.join(ids)
else:
self.id = int(self.id[3:])
if self.msg != None:
self.msg = re.sub(r'\s+', ' ', self.msg.strip())
self.msg = re.sub(r'"', '\'', self.msg.strip())
def validate(self):
if self.main_rule == None and self.basic_rule == None:
print("ERROR: {}: missing 'MainRule' or 'BasicRule' prefix".format(self.line_num))
sys.exit(1)
if self.main_rule != None and self.basic_rule != None:
print("ERROR: {}: 'MainRule' and 'BasicRule' are set".format(self.line_num))
sys.exit(1)
if self.id == None and self.wl == None:
print("ERROR: {}: missing 'id:' or 'wl:'".format(self.line_num))
sys.exit(1)
elif self.id != None and self.wl != None:
print("ERROR: {}: 'id:' and 'wl:' are both set".format(self.line_num))
sys.exit(1)
if self.is_whitelist():
if self.mz == None:
print("ERROR: {}: missing whitelist 'mz:'".format(self.line_num))
sys.exit(1)
elif self.str != None:
print("ERROR: {}: 'str:' is set for a whitelist".format(self.line_num))
sys.exit(1)
elif self.rx != None:
print("ERROR: {}: 'rx:' is set for a whitelist".format(self.line_num))
sys.exit(1)
elif self.d != None:
print("ERROR: {}: 'd:' is set for a whitelist".format(self.line_num))
sys.exit(1)
else:
self.match()
if self.mz == None:
print("ERROR: {}: missing rule 'mz:'".format(self.line_num))
sys.exit(1)
if self.s == None:
print("ERROR: {}: missing rule 's:'".format(self.line_num))
sys.exit(1)
def prefix(self):
return self.main_rule if self.main_rule != None else self.basic_rule
def match(self):
if self.rx != None:
return self.rx
elif self.str != None:
return self.str
elif self.d != None:
return self.d
print("ERROR: {}: missing rule 'rx:' or 'str:' or 'd:'".format(self.line_num))
sys.exit(1)
def is_whitelist(self):
return self.wl != None
def message(self):
if self.msg == None:
return "match " + self.match().replace('"', '')
return self.msg[4:]
def print(self):
if len(self.comments) > 0:
print('\n'.join(self.comments))
prefix = self.prefix()
args = []
if self.is_whitelist():
args = [
self.wl,
self.negative,
'"{}"'.format(self.mz),
'"{}"'.format(self.msg),
]
else:
args = [
'id:{}'.format(self.id),
'"{}"'.format(self.s),
self.negative,
'"{}"'.format(self.match()),
'"{}"'.format(self.mz),
'"{}"'.format(self.msg),
]
args = list(filter(lambda x: x != None and x != '"None"', args))
print("{} {};".format(self.prefix(), ' '.join(args)))
def parse_file(filename, rules, whitelists, ruleid):
lines = []
with open(filename, 'r') as fp:
lines = fp.readlines()
line_num = 0
comments = []
for line in lines:
line_num += 1
line = line.strip()
if line.startswith("#") or len(line) < 1:
comments.append(line)
continue
elif '#' in line and not '#"' in line and not line.endswith(';'):
comments.append('#' + line.split('#', 1)[-1])
line = line.split('#')[0]
if not line.endswith(';'):
print("ERROR: {}: missing ; at the end the line '{}'".format(line_num, line))
sys.exit(1)
line = re.sub(r';$', " ;", line)
tokens = shlex.split(line, posix=False)
# print("{}: {}".format(line_num, tokens))
rule = Rule(tokens, line_num, comments)
comments = []
if rule.is_whitelist():
whitelists.append(rule)
continue
if ruleid > 100:
rule.id = ruleid
ruleid += 1
elif rule.id in rules:
print("ERROR: {}: Rule {} already exists at line {}".format(line_num, rule.id, rules[rule.id].line_num))
sys.exit(1)
rules[rule.id] = rule
def print_rules(rules_ids, rules, whitelists):
header = len(rules_ids) < 1
if len(whitelists) > 0:
for whitelist in whitelists:
if not header:
header = True
print('#############')
print("# Whitelist #")
print('#############')
whitelist.print()
for idx in rules_ids:
if header:
header = False
print('#########')
print("# Rules #")
print('#########')
rules[idx].print()
def print_translate_dictionary(rules_ids, rules, whitelists):
for idx in rules_ids:
print('"{}","{}"'.format(rules[idx].id, rules[idx].message()))
output_formats = {
'rules': print_rules,
'logstash_translate_dictionary': print_translate_dictionary,
}
def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options]', description=DESCRIPTION, epilog=EPILOG, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-r', '--rule', default='', help='source rule to parse')
parser.add_argument('-o', '--output', default='', help='path to the output file')
parser.add_argument('-f', '--format', default='rules', help='format of the output file ({})'.format(','.join(list(output_formats.keys()))))
parser.add_argument('-b', '--begin-id', default=0, type=int, help='rebase all rules ids from this id number (id must be > 100)')
args = parser.parse_args()
if len(sys.argv) == 1 or \
len(args.rule) < 1 or \
len(args.output) < 1 or \
len(args.format) < 1 or \
args.format not in output_formats or \
(args.begin_id != 0 and args.begin_id <= 100):
parser.print_help(sys.stderr)
sys.exit(1)
rules = {}
whitelists = []
parse_file(args.rule, rules, whitelists, args.begin_id)
rules_ids = list(rules.keys())
rules_ids.sort()
file_format = output_formats[args.format]
fd = sys.stdout
if args.output != '-':
sys.stdout = open(args.output, 'w')
file_format(rules_ids, rules, whitelists)
if args.output != '-':
sys.stdout.close()
sys.stdout = fd
if __name__ == '__main__':
main()
+30
View File
@@ -0,0 +1,30 @@
# -* coding: utf-8
# SPDX-FileCopyrightText: 2022 Alex <alex@staticlibs.net>
# SPDX-License-Identifier: LGPL-3.0-only
import os, shutil, sys
from os import path
if __name__ == "__main__":
if 2 != len(sys.argv):
print("ERROR: The path to Nginx dist must be specified as a first and only argument")
sys.exit(1)
src = sys.argv[1]
if not path.isdir(src):
print("ERROR: Nginx dist not found on the specified path: [{}]".format(src))
sys.exit(1)
scripts_dir = path.dirname(__file__)
naxsi_dir = path.dirname(scripts_dir)
nginx_dir = path.join(naxsi_dir, "nginx-tmp")
if path.exists(nginx_dir):
shutil.rmtree(nginx_dir)
os.mkdir(nginx_dir)
shutil.copytree(path.join(src, "conf"), path.join(nginx_dir, "conf"))
os.remove(path.join(nginx_dir, "conf", "nginx.conf"))
shutil.copytree(path.join(src, "logs"), path.join(nginx_dir, "logs"))
shutil.copytree(path.join(src, "temp"), path.join(nginx_dir, "temp"))
os.mkdir(path.join(nginx_dir, "html"))
with open(path.join(nginx_dir, "html", "index.html"), "w", encoding="utf-8") as file:
file.write("<html>Hello Nginx!<html>")
shutil.copy(path.join(src, "nginx.exe"), nginx_dir)
print("Test Nginx dist prepared successfully");
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+232
View File
@@ -0,0 +1,232 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and other kinds of works.
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based on the Program.
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.
+71
View File
@@ -0,0 +1,71 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License.
"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version".
The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
+86
View File
@@ -0,0 +1,86 @@
![naxsi](logo.png)
## Documentation
Updated documentation is available [here](https://wargio.github.io/naxsi/).
## What is Naxsi?
NAXSI means [Nginx](http://nginx.org/) Anti [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29) & [SQL Injection](https://www.owasp.org/index.php/SQL_injection).
Technically, it is a third party nginx module, available as a package for
many UNIX-like platforms. This module, by default, reads a small subset of
simple (and readable) rules containing 99% of known patterns involved in
website vulnerabilities. For example, `<`, `|` or `drop` are not supposed
to be part of a URI.
Being very simple, those patterns may match legitimate queries, it is
the Naxsi's administrator duty to add specific rules that will whitelist
legitimate behaviours. The administrator can either add whitelists manually
by analyzing nginx's error log, or (recommended) start the project with an
intensive auto-learning phase that will automatically generate whitelisting
rules regarding a website's behaviour.
In short, Naxsi behaves like a DROP-by-default firewall, the only task
is to add required ACCEPT rules for the target website to work properly.
## Why is it different?
Contrary to most Web Application Firewalls, Naxsi doesn't rely on a
signature base like an antivirus, and thus cannot be circumvented by an
"unknown" attack pattern.
Naxsi is [Free software](https://www.gnu.org/licenses/gpl.html) (as in freedom)
and free (as in free beer) to use.
## What does it run on?
Naxsi should be compatible with any nginx version.
It depends on `libpcre` for its regexp support, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS.
## Why using this repository
The original project is **officially** abandoned (and has been archived the 8th Nov 2023), but you can fully ask for support here as i'm willing to keep the project working as last remaining developer.
## Build naxsi
**Be sure when you clone the repository to fetch all the submodules.**
```
$ git clone --recurse-submodules https://github.com/wargio/naxsi.git
$ wget --no-clobber -O nginx.tar.gz "https://nginx.org/download/nginx-1.22.0.tar.gz"
$ mkdir nginx-source
$ tar -C nginx-source -xzf nginx.tar.gz --strip-components=1
$ cd nginx-source
$ ./configure --prefix=/etc/nginx --add-dynamic-module=../naxsi/naxsi_src
$ make
```
# Support & Bugs
Questions & bug reports regarding NAXSI can be addressed via issues.
[Click here to open an issue](https://github.com/wargio/naxsi/issues/new)
# Vulnerability disclosure
When disclosing vulnerabilities, please send first an email to `deroad at kumo.xn--q9jyb4c` (gpg keyid: `29656E856786B9A1FBF983CFA219F52A8217B1FE`)
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEXR3FZhYJKwYBBAHaRw8BAQdAfuSDE68TEppjJfUAApXSTsHrKtGefVJXvz7f
YIO0gci0MUdpb3Zhbm5pIERhbnRlIEdyYXppb2xpIDxkZXJvYWRAa3Vtby54bi0t
cTlqeWI0Yz6IkAQTFggAOAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBCll
boVnhrmh+/mDz6IZ9SqCF7H+BQJg9+CGAAoJEKIZ9SqCF7H+X04BAPXz7R856z72
f8nsZZjj4q3YaJbXA3pSVLIJ9uDQniCsAP9PaPBcbr231M3cjjBMo7ovlrElfFor
zCWA3NhRb4Y2DLg4BF0dxWYSCisGAQQBl1UBBQEBB0AVby+EIQcIoqSDZelvkqt8
dV1kvF4f/J0jj0k3OEKNcAMBCAeIeAQYFggAIAIbDBYhBCllboVnhrmh+/mDz6IZ
9SqCF7H+BQJg9+C4AAoJEKIZ9SqCF7H+ZfQBAOFb7iZm7t8j5ymiXyJFcuM/nF9+
bx4+KJJUTR9r6zBFAQD3Ea5Ya4lny/v9WKNSpBfZFEs3pkDnfgxw3o8vc4iSAQ==
=d/IR
-----END PGP PUBLIC KEY BLOCK-----
```
## Future plans
- Bring back nxapi using python3
- Creation of a simple tool to create rules and test them
+64
View File
@@ -0,0 +1,64 @@
version = 1
SPDX-PackageName = "Naxsi WAF"
SPDX-PackageSupplier = "deroad <wargio@libero.it>"
SPDX-PackageDownloadLocation = "https://github.com/wargio/naxsi"
[[annotations]]
path = ".github/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ".clang-format"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = [".gitignore", ".gitmodules"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = "distros/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = "naxsi_rules/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ["README.md", ".gitattributes", "logo.png"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2019 nbs-system <security@nbs-system.com>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "naxsi_rules/naxsi_core.rules"
precedence = "aggregate"
SPDX-FileCopyrightText = "2019 nbs-system <security@nbs-system.com>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "unit-tests/**"
precedence = "aggregate"
SPDX-FileCopyrightText = ["2019 nbs-system <security@nbs-system.com> \\", "2022 deroad <wargio@libero.it>"]
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "docs/**.md"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 deroad <wargio@libero.it>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = "docs/old**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2019 nbs-system <security@nbs-system.com>"
SPDX-License-Identifier = "GPL-3.0-or-later"
+220
View File
@@ -0,0 +1,220 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.18.0
pkgrel=13
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
8c21eeb62ab6e32e436932500f700bd2fb99fd2d29e43c08a5bfed4714c189c29c7141db551fcd5d2437303b7439f71758f7407dfd3e801e704e45e7daa78ddb nginx-1.18.0.tar.gz
"
+222
View File
@@ -0,0 +1,222 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.18.0
pkgrel=15
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz
CVE-2021-23017.patch"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
8c21eeb62ab6e32e436932500f700bd2fb99fd2d29e43c08a5bfed4714c189c29c7141db551fcd5d2437303b7439f71758f7407dfd3e801e704e45e7daa78ddb nginx-1.18.0.tar.gz
b8ed5dedc55f4e1c60f3c0b97836096e83a9f928b13c125fe568f5d369bb35535224c7def05677f04adc9733a983ac9cc8aa2c7af94468085eb3121c1817dc45 CVE-2021-23017.patch
"
@@ -0,0 +1,25 @@
Patch-Source: http://nginx.org/download/patch.2021.resolver.txt
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -4008,15 +4008,15 @@ done:
n = *src++;
} else {
+ if (dst != name->data) {
+ *dst++ = '.';
+ }
+
ngx_strlow(dst, src, n);
dst += n;
src += n;
n = *src++;
-
- if (n != 0) {
- *dst++ = '.';
- }
}
if (n == 0) {
+221
View File
@@ -0,0 +1,221 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.20.1
pkgrel=3
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
3d9fd4bf2740eaf20fcc3c77260a3556aaf9dff2879afc2dbb5fff364dea27313ffbc51d335e9fc9c0186a2a44dac055ef60fde0d411b8cf842fdf661478c961 nginx-1.20.1.tar.gz
"
+221
View File
@@ -0,0 +1,221 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.20.2
pkgrel=0
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
8b65e881ea4ac6162cbf32e5e95cf47a6d5418819f8763ca4a781cffa38187dd7886d4bc195d000a7046111a27121ff25800f8645405174995247e6738b4279a nginx-1.20.2.tar.gz
"
+223
View File
@@ -0,0 +1,223 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.20.2
pkgrel=1
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz
CVE-2021-3618.patch"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
8b65e881ea4ac6162cbf32e5e95cf47a6d5418819f8763ca4a781cffa38187dd7886d4bc195d000a7046111a27121ff25800f8645405174995247e6738b4279a nginx-1.20.2.tar.gz
5896417268cdd4cde1cc6a4cf9ebc3aa2c82cb4b27a68c1fa4e9c1065cf4e5f0eebc13cfdb2ac3ebe29fdc5332022a61681aceefe1c72c5402ce73fab3f03f5a CVE-2021-3618.patch
"
@@ -0,0 +1,92 @@
Patch-Source: https://github.com/nginx/nginx/commit/173f16f736c10eae46cd15dd861b04b82d91a37a
commit 173f16f736c10eae46cd15dd861b04b82d91a37a
Author: Maxim Dounin <mdounin@mdounin.ru>
Date: Wed May 19 03:13:31 2021 +0300
Mail: max_errors directive.
Similarly to smtpd_hard_error_limit in Postfix and smtp_max_unknown_commands
in Exim, specifies the number of errors after which the connection is closed.
diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h
index 07104df6..21178c3e 100644
--- a/src/mail/ngx_mail.h
+++ b/src/mail/ngx_mail.h
@@ -115,6 +115,8 @@ typedef struct {
ngx_msec_t timeout;
ngx_msec_t resolver_timeout;
+ ngx_uint_t max_errors;
+
ngx_str_t server_name;
u_char *file_name;
@@ -231,6 +233,7 @@ typedef struct {
ngx_uint_t command;
ngx_array_t args;
+ ngx_uint_t errors;
ngx_uint_t login_attempt;
/* used to parse POP3/IMAP/SMTP command */
diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c
index 40831242..115671ca 100644
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -85,6 +85,13 @@ static ngx_command_t ngx_mail_core_commands[] = {
offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
NULL },
+ { ngx_string("max_errors"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_core_srv_conf_t, max_errors),
+ NULL },
+
ngx_null_command
};
@@ -163,6 +170,8 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
cscf->timeout = NGX_CONF_UNSET_MSEC;
cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
+ cscf->max_errors = NGX_CONF_UNSET_UINT;
+
cscf->resolver = NGX_CONF_UNSET_PTR;
cscf->file_name = cf->conf_file->file.name.data;
@@ -182,6 +191,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
30000);
+ ngx_conf_merge_uint_value(conf->max_errors, prev->max_errors, 5);
ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
index 57503e9a..246ba97c 100644
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -874,7 +874,20 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
- if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
+ if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
+
+ s->errors++;
+
+ if (s->errors >= cscf->max_errors) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent too many invalid commands");
+ s->quit = 1;
+ }
+
+ return rc;
+ }
+
+ if (rc == NGX_IMAP_NEXT) {
return rc;
}
+225
View File
@@ -0,0 +1,225 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.22.0
pkgrel=1
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
# --without-pcre2 - Lua module is not compatible with PCRE2 yet
# https://github.com/openresty/lua-nginx-module/issues/1984
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--without-pcre2 \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
074782dba9cd5f8f493fbb57e20bda6dc9171814d919a47ee9f825d93f12c9f9d496e25d063c983191b55ad6a236bcef252ce16ecc1d253dc8b23433557559b1 nginx-1.22.0.tar.gz
"
+225
View File
@@ -0,0 +1,225 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.22.1
pkgrel=0
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
# --without-pcre2 - Lua module is not compatible with PCRE2 yet
# https://github.com/openresty/lua-nginx-module/issues/1984
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--without-pcre2 \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
1d468dcfa9bbd348b8a5dc514ac1428a789e73a92384c039b73a51ce376785f74bf942872c5594a9fcda6bbf44758bd727ce15ac2395f1aa989c507014647dcc nginx-1.22.1.tar.gz
"
+227
View File
@@ -0,0 +1,227 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.24.0
pkgrel=3
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
hiredis-dev
jansson-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
# --without-pcre2 - Lua module is not compatible with PCRE2 yet
# https://github.com/openresty/lua-nginx-module/issues/1984
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--without-pcre2 \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
1114e37de5664a8109c99cfb2faa1f42ff8ac63c932bcf3780d645e5ed32c0b2ac446f80305b4465994c8f9430604968e176ae464fd80f632d1cb2c8f6007ff3 nginx-1.24.0.tar.gz
"
+227
View File
@@ -0,0 +1,227 @@
# Maintainer: Giovanni Dante Grazioli <wargio@libero.it>
pkgname=nginx
pkgver=1.24.0
pkgrel=6
pkgdesc="HTTP and reverse proxy server (stable version)"
url="https://www.nginx.org/"
arch="all"
license="BSD-2-Clause"
depends=""
makedepends="
brotli-dev
gd-dev
geoip-dev
hiredis-dev
jansson-dev
libmaxminddb-dev
libxml2-dev
libxslt-dev
linux-headers
luajit-dev
openssl-dev
pcre-dev
perl-dev
pkgconf
zeromq-dev
zlib-dev
"
checkdepends="
gd
perl
perl-fcgi
perl-io-socket-ssl
perl-net-ssleay
perl-protocol-websocket
tzdata
uwsgi-python3
"
pkgusers="nginx"
_grp_ngx="nginx"
_grp_www="www-data"
pkggroups="$_grp_ngx $_grp_www"
install=""
subpackages=""
source="https://nginx.org/download/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
_modules_dir="usr/lib/$pkgname/modules"
# For simplicity we assume that module is hosted on GitHub.
_add_module() {
local name="$1" ver="$2" url="$3" subdir="$4"
local dirname=${url##*/}-${ver#v}
local varprefix="_${name//-/_}"
eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'"
# Don't add new flag and source if it's already there, i.e. two or more
# modules share the same source (e.g. geoip2 that provides http-geoip2
# and stream-geoip2).
if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then
_module_path=$(realpath ../../../$subdir)
_extra_flags="$_extra_flags --add-dynamic-module=$_module_path"
fi
subpackages="$subpackages $pkgname-mod-$name:_module"
}
_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src"
_naxsi_provides="$pkgname-naxsi" # for backward compatibility
prepare() {
local file; for file in $source; do
file=${file%%::*}
case $file in
*~*.patch)
msg $file
cd "$srcdir"/${file%%~*}-*
patch -p 1 -i "$srcdir/$file"
;;
*.patch)
msg $file
cd "$builddir"
patch -p 1 -i "$srcdir/$file"
;;
esac
done
}
_build() {
# --without-pcre2 - Lua module is not compatible with PCRE2 yet
# https://github.com/openresty/lua-nginx-module/issues/1984
./configure \
--prefix=/var/lib/$pkgname \
--sbin-path=/usr/sbin/$pkgname \
--modules-path=/$_modules_dir \
--conf-path=/etc/$pkgname/$pkgname.conf \
--pid-path=/run/$pkgname/$pkgname.pid \
--lock-path=/run/$pkgname/$pkgname.lock \
--http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \
--http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \
--with-perl_modules_path=/usr/lib/perl5/vendor_perl \
\
--user=$pkgusers \
--group=$_grp_ngx \
--with-threads \
--with-file-aio \
\
--without-pcre2 \
\
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--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_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
\
$_extra_flags \
"$@"
make -j
}
build() {
cd "$builddir"
_build --with-debug
mv objs objs-debug
make clean
_build
}
check() {
msg "Ignore nginx tests..."
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install
}
debug() {
return
}
vim() {
return
}
_module() {
local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}"
local ver=$(getvar _${name}_ver)
pkgdesc="Nginx module ${name//_/-}"
[ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)"
url=$(getvar "_${name}_url" "$url")
sonames=$(getvar "_${name}_so" "ngx_${name}_module.so")
depends="$pkgname $(getvar "_${name}_depends")"
provides=$(getvar "_${name}_provides")
# Numeric prefix for the module config to ensure that modules with
# dependencies on other modules will be loaded after their dependencies.
# For simplicity, we don't actually resolve dependency tree. Instead,
# we just prefix the module name with a number that reflects number of
# the module's dependencies times ten (e.g. 10, 20, 30, ...).
local conf_prefix="$(echo "$depends" | wc -w)0_"
mkdir -p "$subpkgdir"/$_modules_dir
mkdir -p "$subpkgdir"/etc/nginx/modules
cd "$subpkgdir"
local soname; for soname in $sonames; do
mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname
echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf
done
mkdir -p ./etc/nginx/naxsi/blocking/
mkdir -p ./etc/nginx/naxsi/whitelists/
cd "$srcdir/.."
case "$name" in
http_naxsi)
install -m644 -D ../../../naxsi_rules/naxsi_core.rules \
"$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules
install -m644 -D ../../../naxsi_rules/blocking/*.rules \
"$subpkgdir/etc/nginx/naxsi/blocking/"
install -m644 -D ../../../naxsi_rules/whitelists/*.rules \
"$subpkgdir/etc/nginx/naxsi/whitelists/"
;;
esac
}
# Print value of the specified variable, or the default if empty or not defined.
getvar() {
eval "printf '%s\n' \"\${$1:-$2}\""
}
sha512sums="
1114e37de5664a8109c99cfb2faa1f42ff8ac63c932bcf3780d645e5ed32c0b2ac446f80305b4465994c8f9430604968e176ae464fd80f632d1cb2c8f6007ff3 nginx-1.24.0.tar.gz
"
@@ -0,0 +1,65 @@
v3.13.0/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.1/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.2/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.3/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.4/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.5/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5
v3.13.6/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.7/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.8/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.9/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.10/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.11/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.13.12/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97
v3.14.0/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403
v3.14.1/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403
v3.14.2/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403
v3.14.3/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403
v3.14.4/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530
v3.14.5/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530
v3.14.6/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530
v3.14.7/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf
v3.14.8/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf
v3.14.9/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf
v3.14.10/APKBUILD 82c4a602c17a8b9dfce1fc833c968d37ce797cfe
v3.15.0/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45
v3.15.1/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45
v3.15.2/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45
v3.15.3/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45
v3.15.4/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45
v3.15.5/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293
v3.15.6/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293
v3.15.7/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293
v3.15.8/APKBUILD 934f7d64c39b23cfd0be976bda5c3c3fc8e2fb9f
v3.15.9/APKBUILD 934f7d64c39b23cfd0be976bda5c3c3fc8e2fb9f
v3.16.0/APKBUILD 9d141041a3dd31d8f63d2fb9e491b36066847ab5
v3.16.1/APKBUILD ae51a127df402f10a3510bbb3a0db986ed3f362f
v3.16.2/APKBUILD ae51a127df402f10a3510bbb3a0db986ed3f362f
v3.16.3/APKBUILD cf21abf069b99df0466109da431e257be35e5fd2
v3.16.4/APKBUILD cf21abf069b99df0466109da431e257be35e5fd2
v3.16.5/APKBUILD 741f460e98d96286e3178f0892e43e4b24c105ba
v3.16.6/APKBUILD 741f460e98d96286e3178f0892e43e4b24c105ba
v3.17.0/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77
v3.17.1/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77
v3.17.2/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77
v3.17.3/APKBUILD 755ae65dbf1112735fbe16c987ce0a1ee9962223
v3.17.4/APKBUILD 755ae65dbf1112735fbe16c987ce0a1ee9962223
v3.18.0/APKBUILD 5ac489bf563ac1f9fd8389f5f227a6fcd260e6e4
v3.18.1/APKBUILD 3047d360052cbd089f7c960b7c72727b9fe1a390
v3.18.2/APKBUILD 3047d360052cbd089f7c960b7c72727b9fe1a390
+58
View File
@@ -0,0 +1,58 @@
#!/bin/sh
set -e
NAXSI_ROOT="$PWD"
BUILD_DIR="$NAXSI_ROOT/build"
ALPINE_VERSION=$(cat /etc/alpine-release)
VERSION="unknown"
case "v$ALPINE_VERSION" in
"v3.13.0" | "v3.13.1" | "v3.13.2" | "v3.13.3" | "v3.13.4" | "v3.13.5")
VERSION="1.18.0-r13"
;;
"v3.13.6" | "v3.13.7" | "v3.13.8" | "v3.13.9" | "v3.13.10" | "v3.13.11" | "v3.13.12")
VERSION="1.18.0-r15"
;;
"v3.14.0" | "v3.14.1" | "v3.14.2" | "v3.14.3")
VERSION="1.20.1-r3"
;;
"v3.14.4" | "v3.14.5" | "v3.14.6" | "v3.15.0" | "v3.15.1" | "v3.15.2" | "v3.15.3" | "v3.15.4")
VERSION="1.20.2-r0"
;;
"v3.14.7" | "v3.14.8" | "v3.14.9" | "v3.14.10" | "v3.15.5" | "v3.15.6" | "v3.15.7" | "v3.15.8" | "v3.15.9" | "v3.16.0")
VERSION="1.20.2-r1"
;;
"v3.16.1" | "v3.16.2")
VERSION="1.22.0-r1"
;;
"v3.16.3" | "v3.16.4" | "v3.16.5" | "v3.16.6" | "v3.17.0" | "v3.17.1" | "v3.17.2" | "v3.17.3" | "v3.17.4")
VERSION="1.22.1-r0"
;;
"v3.18.0")
VERSION="1.24.0-r3"
;;
"v3.18.1" | "v3.18.2")
VERSION="1.24.0-r6"
;;
*)
echo "error: unsupported version, please open an issue on github."
exit 1
;;
esac
echo "Alpine $ALPINE_VERSION, using $VERSION APKBUILD..."
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
mkdir "$BUILD_DIR"
echo "$BUILD_DIR/naxsi.key" | abuild-keygen -a
cp -v "$BUILD_DIR/naxsi.key.pub" /etc/apk/keys
cd "$NAXSI_ROOT/distros/alpine/$VERSION"
SRCDEST="$BUILD_DIR" abuild -F fetch
SRCDEST="$BUILD_DIR" abuild -F -c -r -P "$BUILD_DIR"
find "$BUILD_DIR" -name "*.apk" | grep naxsi | xargs -I % mv -v % "$BUILD_DIR"
+69
View File
@@ -0,0 +1,69 @@
# Maintainer: Giovanni Dante (deroad) Grazioli <deroad@libero.it>
pkgname=nginx-mod-naxsi-git
pkgver=1.7
pkgrel=1
epoch=1
_modname=naxsi
pkgdesc='Nginx Anti XSS & SQL Injection'
arch=('x86_64')
depends=('nginx')
makedepends=('nginx-src')
url="https://github.com/wargio/naxsi"
license=('GPL3')
backup=('etc/nginx/naxsi_core.rules')
conflicts=('nginx-mod-naxsi')
source=(
"$pkgname::git+https://github.com/wargio/$_modname.git"
)
sha256sums=('SKIP')
pkgver () {
cd ${srcdir}/${pkgname}
printf $(grep "NAXSI_VERSION" naxsi_src/naxsi_const.h | cut -d ' ' -f3 | sed 's/"//g')
}
prepare() {
cd ${pkgname}
git submodule init
git config submodule.libinjection.url "${srcdir}/${pkgname}/naxsi_src/libinjection"
git submodule update
mkdir -p ${srcdir}/build
cd ${srcdir}/build
ln -sf /usr/src/nginx/auto
ln -sf /usr/src/nginx/src
}
build() {
cd ${srcdir}/build
local GCC_PATH=$(which gcc)
/usr/src/nginx/configure --with-cc="$GCC_PATH" --with-compat --add-dynamic-module="${srcdir}/${pkgname}/naxsi_src"
make modules
}
package() {
cd $srcdir/build/objs
for mod in *.so; do
install -Dm755 $mod "$pkgdir"/usr/lib/nginx/modules/$mod
done
mkdir -p "$pkgdir"/etc/nginx/naxsi/whitelists
mkdir -p "$pkgdir"/etc/nginx/naxsi/blocking
install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_block_mode.conf "$pkgdir"/etc/nginx/naxsi/naxsi_block_mode.conf
install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_denied_url.conf "$pkgdir"/etc/nginx/naxsi/naxsi_denied_url.conf
install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_learning_mode.conf "$pkgdir"/etc/nginx/naxsi/naxsi_learning_mode.conf
install -Dm644 "$srcdir/${pkgname}"/naxsi_rules/naxsi_core.rules "$pkgdir"/etc/nginx/naxsi/naxsi_core.rules
cd "$srcdir/${pkgname}"/naxsi_rules/whitelists/
for rule in *.rules; do
install -Dm644 $rule "$pkgdir"/etc/nginx/naxsi/whitelists/$rule
done
cd "$srcdir/${pkgname}"/naxsi_rules/blocking/
for rule in *.rules; do
install -Dm644 $rule "$pkgdir"/etc/nginx/naxsi/blocking/$rule
done
}
+9
View File
@@ -0,0 +1,9 @@
PACKAGE="libnginx-mod-http-naxsi"
VERSION="@NAXSI_VERSION@"
SECTION="httpd"
ARCHITECTURE="amd64"
DEPENDENCIES="@NGINX_PACKAGE@ (>= @NGINX_VERSION@), @LIBPCRE_PACKAGE@ (>= @LIBPCRE_VERSION@)"
MAINTAINER_NAME="Giovanni Dante Grazioli"
MAINTAINER_EMAIL="deroad@libero.it"
HOMEPAGE="https://github.com/wargio/naxsi"
DESCRIPTION="NAXSI, a web application firewall for Nginx."
+1
View File
@@ -0,0 +1 @@
load_module modules/ngx_http_naxsi_module.so;
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
set -e
# Automatically added by dh_nginx/UNDECLARED
for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do
from=$(echo $confpair | cut -d: -f1)
to=$(echo $confpair | cut -d: -f2)
if [ -L /etc/nginx/modules-enabled/$to.removed ]; then
rm /etc/nginx/modules-enabled/$to.removed
removed_link=true
else
removed_link=false
fi
# Symlink on
# 1) Fresh installations
# 2) Reinstalls after automatic removes (preserve admin actions)
if [ -z "$2" -o "$removed_link" = "true" ]; then
ln -sf /usr/share/nginx/modules-available/$from \
/etc/nginx/modules-enabled/$to
fi
done
if [ "$1" = "configure" ] ; then
if which dpkg-trigger >/dev/null 2>&1 ; then
dpkg-trigger --no-await nginx-reload
fi
fi
# End automatically added section
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
set -e
# Automatically added by dh_nginx/UNDECLARED
if [ "$1" = "purge" ] ; then
for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do
from=$(echo $confpair | cut -d: -f1)
to=$(echo $confpair | cut -d: -f2)
if [ -L /etc/nginx/modules-enabled/$to ]; then
rm /etc/nginx/modules-enabled/$to
fi
if [ -L /etc/nginx/modules-enabled/$to.removed ]; then
rm /etc/nginx/modules-enabled/$to.removed
fi
done
fi
if [ "$1" = "remove" ] ; then
for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do
from=$(echo $confpair | cut -d: -f1)
to=$(echo $confpair | cut -d: -f2)
if [ -L /etc/nginx/modules-enabled/$to ]; then
mv /etc/nginx/modules-enabled/$to /etc/nginx/modules-enabled/$to.removed
fi
done
if which dpkg-trigger >/dev/null 2>&1 ; then
dpkg-trigger --no-await nginx-reload
fi
fi
# End automatically added section
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
set -e
# Automatically added by dh_nginx/UNDECLARED
if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ] ; then
for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do
from=$(echo $confpair | cut -d: -f1)
to=$(echo $confpair | cut -d: -f2)
if [ -L /etc/nginx/modules-enabled/$to ]; then
mv /etc/nginx/modules-enabled/$to /etc/nginx/modules-enabled/$to.removed
fi
done
fi
# End automatically added section
+15
View File
@@ -0,0 +1,15 @@
SecRulesEnabled; #enable naxsi
LibInjectionSql; #enable libinjection support for SQLI
LibInjectionXss; #enable libinjection support for XSS
#the location where naxsi will redirect the request when it is blocked
DeniedUrl "/NaxsiRequestDenied";
#the action to take when the $SQL score is superior or equal to 8
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
CheckRule "$UWA >= 8" BLOCK;
CheckRule "$EVADE >= 8" BLOCK;
@@ -0,0 +1,4 @@
location /NaxsiRequestDenied {
internal;
return 418; #I'm a teapot \o/
}
@@ -0,0 +1,16 @@
SecRulesEnabled; #enable naxsi
LearningMode; #enable learning mode
LibInjectionSql; #enable libinjection support for SQLI
LibInjectionXss; #enable libinjection support for XSS
#the location where naxsi will redirect the request when it is blocked
DeniedUrl "/NaxsiRequestDenied";
#the action to take when the $SQL score is superior or equal to 8
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
CheckRule "$UWA >= 8" BLOCK;
CheckRule "$EVADE >= 8" BLOCK;
+139
View File
@@ -0,0 +1,139 @@
# **Naxsi Basic Configuration**
To get started with Naxsi, you can explore the following basic configuration.
## **Configuring Naxsi**
Naxsi must be configured based on what it is going to protect.
The first step, once compiled dynamically compiled, you will have a shared library which will need to be loaded by nginx by adding an entry to the `/etc/nginx/nginx.conf` file.
```nginx
load_module /usr/lib/nginx/modules/ngx_http_naxsi_module.so;
```
Once the module is added to the NGINX configuration, the next step is to **include global rules**; in the Naxsi repository you can find the [**`naxsi_core.rules`**](https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules) which gives to the user the ability to add the most basic ruleset to Naxsi itself.
> 💡 Tip
>
> It is possible to include these rules directly in `/etc/nginx/nginx.conf`.
```nginx
include /etc/nginx/naxsi/naxsi_core.rules
```
The next step is configuring each website which will need to be protected by Naxsi; this happens by adding the directives `SecRulesEnabled`, `DeniedUrl` and `CheckRule` to a `location` block.
* `SecRulesEnabled`: is used to enable Naxsi in the `location` block.
* `DeniedUrl`: specifies where blocked requests will be redirected (**this is an internal redirect for NGINX** and requires a different `location` block as destination).
* `CheckRule`: takes an action (`LOG`, `BLOCK`, `DROP`, `ALLOW`) based on a specific score associated with the request.
For more details, check the [Directive chapter](directives.md)
```nginx
location / {
SecRulesEnabled;
DeniedUrl "/RequestDenied";
CheckRule "$FOO >= 8" BLOCK;
}
# The location where all the blocked request will be internally redirected.
location /RequestDenied {
internal;
return 403;
}
```
The last steps are create whitelists and configure the logging.
```nginx
# example of whitelist (global and location-defined)
MainRule wl:1000,1009,1315 "mz:$BODY_VAR:_wp_http_referer";
BasicRule wl:1000,1009,1315 "mz:$BODY_VAR:_wp_http_referer";
# Enable JSON logs for Naxsi
set $naxsi_json_log 1;
```
## **Example Configuration**
This NGINX configuration for `/etc/nginx/nginx.conf` where we define a reverse proxy towards a webservice hosted on `internal-ip-address` on port `80`.
```nginx
# load module
load_module /etc/nginx/modules/ngx_http_naxsi_module.so;
server {
listen 80;
server_name example.com;
set $naxsi_json_log 1; # Enable JSON logs for Naxsi
include /etc/nginx/naxsi/naxsi_core.rules; # Include core rules (see below)
location / {
proxy_pass http://internal-ip-address:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
SecRulesEnabled; #enable naxsi for this `location`
# LearningMode; #When enable, BLOCK CheckRule are considered as LOG.
LibInjectionSql; #enable libinjection support for SQL injection detection
LibInjectionXss; #enable libinjection support for XSS detection
# Internal denied request.
DeniedUrl "/RequestDenied";
# Include additional rules
include /etc/nginx/naxsi/blocking/*.rules;
# The following CheckRules are mandatory when using the rules found in the naxsi repository.
# For more info, please check:
# - https://github.com/wargio/naxsi/tree/main/naxsi_rules/blocking
# - https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules
CheckRule "$SQL >= 8" BLOCK; # SQL injection action (unrelated to libinjection)
CheckRule "$XSS >= 8" BLOCK; # XSS action (unrelated to libinjection)
CheckRule "$RFI >= 8" BLOCK; # Remote File Inclusion action
CheckRule "$UWA >= 8" BLOCK; # Unwanted Access action
CheckRule "$EVADE >= 8" BLOCK; # Evade action (some tools may try to avoid detection).
CheckRule "$UPLOAD >= 5" BLOCK; # Malicious upload action
CheckRule "$TRAVERSAL >= 5" BLOCK; # Traversal access action
CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; # libinjection XSS action
CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; # libinjection SQLi action
}
# The location where all the blocked request will be internally redirected.
location /RequestDenied {
internal;
return 403;
}
}
```
This configuration enables NAXSI and sets up basic rules for blocking requests based on various threat levels.
> 📣 Important
>
> The `SecRulesEnabled` directive is mandatory to enable NAXSI in a location.
Some key directives used in this example include:
* `LearningMode`: if enabled, `BLOCK` CheckRule will be considered as `LOG`, thus not blocking the requests.
* `LibInjectionXss` and `LibInjectionSql`: When defined, enables libinjection support for SQLi & XSS and requires to define `$LIBINJECTION_XSS` & `$LIBINJECTION_SQL` **`**CheckRules**.
* `include`: This directive allows to include other configuration files within the current scope, this can be useful if the system owner wants to have the same configuration for multiple websites without copy-pasting the same lines.
Additionally, this configuration includes directives for enabling libinjection's XSS and SQLi detection features.
> ⚠️ Warning
>
> **Be aware that Nginx will fail to load the configuration, if `ngx_http_naxsi_module.so` is not loaded**.
> 💡 Tip
>
> It is possible to test the NGINX configuration by using `nginx -t` from the command line.
# Go Back
[Table of Contents](index.md).
+171
View File
@@ -0,0 +1,171 @@
# **Installing Naxsi**
In this section you can find how to install and build naxsi on various distributions.
## **Ubuntu/Debian**
Ubuntu & Debian do not provide a package for this, but you can easily compile naxsi using `apt-get source` to fetch the correct version of nginx as follows.
1. **Download the required software**
> ️ Info
>
> Some Debian and Ubuntu distributions uses **`libpcre2-dev`** instad of `libpcre3-dev`.
> ️ Info
>
> Debian bookworm requires also **`libperl-dev`**
```bash
# Install required software
apt-get install build-essential ca-certificates \
dpkg-dev zlib1g-dev libgd-dev libgeoip-dev \
libpcre3-dev libperl-dev libssl-dev libxslt1-dev \
gzip git nginx tar wget
```
We also need to download **Naxsi**
```bash
NAXSI_VERSION=X.Y
wget "https://github.com/wargio/naxsi/releases/download/$NAXSI_VERSION/naxsi-$NAXSI_VERSION-src-with-deps.tar.gz"
mkdir -p naxsi
tar -C naxsi -xzf naxsi-$NAXSI_VERSION-src-with-deps.tar.gz
```
And fetch the NGINX source via `apt-get source`.
```bash
apt-get source nginx
```
2. **Retrieve the distro compile flags**
To correctly build Naxsi for Debian/Ubuntu, you will need to retrieve the configure arguments (also called `compile flags`) using `nginx -V`, as shown below.
```bash
nginx -V
```
Example of output:
```
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f 31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-lUTckl/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_gzip_static_module --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_conn_module --without-http_memcached_module --without-http_referer_module --without-http_split_clients_module --without-http_userid_module --add-dynamic-module=/build/nginx-lUTckl/nginx-1.18.0/debian/modules/http-echo
```
To simplify this process, you can use the following command, which takes the output of `nginx -V` and modifies it; this can be used as a quick way to get "ready-to-use" configure arguments for building NGINX.
```bash
nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g'
```
Example of output:
```
--with-cc-opt='-g -O2 -fdebug-prefix-map=./nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_gzip_static_module --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_conn_module --without-http_memcached_module --without-http_referer_module --without-http_split_clients_module --without-http_userid_module
```
3. **Build NGINX with Naxsi as module**
Now we will build Naxsi using NGINX sources:
```bash
# Build NGINX with Naxsi
cd nginx-*
NGINX_BUILD_FLAGS=$(nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g')
./configure $NGINX_BUILD_FLAGS --add-dynamic-module=../naxsi/naxsi_src/
make modules
```
You will find the built module at the following path:
```
nginx-<version>/objs/ngx_http_naxsi_module.so
```
The other files you will need, are **the rules**, which can be found at the following path:
```
naxsi/naxsi_rules
```
> ⚠️ Warning
>
> **Be aware that you may encounter the following error related to `libinjection`, which can be safely ignored.**
```
[truncated output ...]
configuring additional dynamic modules
adding module in ../naxsi/naxsi_src
Package libinjection was not found in the pkg-config search path.
Perhaps you should add the directory containing `libinjection.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libinjection' found
Package libinjection was not found in the pkg-config search path.
Perhaps you should add the directory containing `libinjection.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libinjection' found
Using submodule libinjection
+ naxsi was configured
```
# **Compiling Naxsi from Sources**
> ️ Info
>
> You will need to have a working C dev environment installed on your system, for tools like `gcc` or `clang` and `make`, in order to compile Naxsi.
> ⚠️ Warning
>
> You will need to have `libpcre` or `libpcre2` or `libpcre3` installed to correctly build Naxsi.
To compile Naxsi from source code, follow these steps:
1. **Get Naxsi sources**
```bash
NAXSI_VERSION=X.Y
wget "https://github.com/wargio/naxsi/releases/download/$NAXSI_VERSION/naxsi-$NAXSI_VERSION-src-with-deps.tar.gz"
mkdir -p naxsi
tar -C naxsi -xzf naxsi-$NAXSI_VERSION-src-with-deps.tar.gz
```
2. **Get NGINX sources**
```bash
NGINX_VERSION=X.Y.Z
wget https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz
mkdir -p nginx
tar -C nginx -xzf nginx-$NGINX_VERSION.tar.gz
```
3. **Build NGINX and Naxsi**
```
cd nginx
./configure --add-dynamic-module=../naxsi/naxsi_src/
make modules
```
4. **Install Nginx and Naxsi**
You can automatically install the files using `make install` or alternatively you can manually install the built module using:
You will find the built module at the following path:
```
nginx/objs/ngx_http_naxsi_module.so
```
The other files you will need, are **the rules**, which can be found at the following path:
```
naxsi/naxsi_rules
```
# Next
[Basic Configuration](basic-configuration.md).
+252
View File
@@ -0,0 +1,252 @@
# **Naxsi Directives**
This section explains all the directives, with examples, that are available when the Naxsi module (`ngx_http_naxsi_module.so`) is enabled.
## **SecRulesEnabled**
> ️ Info
>
> NGINX block: `location`
This directive is mandatory to `enable` naxsi in a NGINX `location`.
### Example:
```nginx
location / {
SecRulesEnabled;
}
```
## **CheckRule**
> ️ Info
>
> NGINX block: `location`
This directive is required to instruct Naxsi on which action to take when there is a rule match.
The directive requires you to specify a **score** with a variable name and its min/max value (for example `$FOO_BAR >= 4`); the score is then followed by an action to take (`LOG`, `BLOCK`, `DROP`, or `ALLOW`) when is met.
> 📣 Important
>
> Score variable names must starts with a "dollar sign" `$` and can contains "underscores" `_`.
> ⚠️ Warning
>
> The action `BLOCK` will behave like `DROP` only when `LearningMode` is not enabled.
### Example:
```nginx
location / {
CheckRule "$FOO_UU >= 8" LOG;
CheckRule "$BARRRR < 99" DROP;
CheckRule "$SOMETHING <= 33" BLOCK;
}
```
## **LibInjectionXss**
> ️ Info
>
> NGINX block: `location`
When defined, this directive enables [libinjection's](https://github.com/libinjection/libinjection) xss detection on *all* requests.
> 📣 Important
>
> The detected XSS will increase the score `$LIBINJECTION_XSS` by `1` for each match; this means that is required to define `$LIBINJECTION_XSS` as a `CheckRule`.
### Example:
```nginx
location / {
# enable libinjection xss
LibInjectionXss;
# define LIBINJECTION_XSS for libinjection
CheckRule "$LIBINJECTION_XSS >= 8" BLOCK;
}
```
## **LibInjectionSql**
> ️ Info
>
> NGINX block: `location`
When defined, this directive enables [libinjection's](https://github.com/libinjection/libinjection) sqli detection on *all* requests.
> 📣 Important
>
> The detected SQLi will increase the score `$LIBINJECTION_SQL` by `1` for each match; this means that is required to define `$LIBINJECTION_SQL` as a `CheckRule`.
### Example:
```nginx
location / {
# enable libinjection sqli
LibInjectionSql;
# define LIBINJECTION_SQL for libinjection
CheckRule "$LIBINJECTION_SQL >= 8" BLOCK;
}
```
## **LearningMode**
> ️ Info
>
> NGINX block: `location`
This directive instructs Naxsi that to not honor `CheckRules` which defines actions as `BLOCK` in a NGINX `location`.
All the `BLOCK` actions will be interpreted as `LOG`; this is a useful mode when deploying a new web application and detect all false positives that might be generated by the WAF.
> 📣 Important
>
> Keep in mind that internal rules (those with an `id` inferior to 1000) will drop the request even in learning mode, because it means something fishy is going on and Naxsi can't correctly process the request. You can of course apply whitelists if those are false positives.
### Example:
```nginx
location / {
# enable Naxsi learning mode
LearningMode;
}
```
## **DeniedUrl**
> ️ Info
>
> NGINX block: `location`
This directive is used to define where Naxsi has to redirect (it's an NGINX's internal redirect) when blocking, dropping or logging requests.
The following headers that are added are when blocking, dropping or logging requests:
- `x-orig_url`
- `x-orig_args`
- `x-naxsi_sig`
> 💡 Tip
>
> It is **strongly** suggested to mark the `DeniedUrl` location as `internal` to prevent possible pre-detection of the WAF as per example.
### Example:
```nginx
location / {
DeniedUrl "/RequestDenied";
}
location /RequestDenied {
# Mark this location as internal only to prevent possible pre-detection of the WAF
internal;
# return code of the location.
return 403;
}
```
## **MainRule**
> ️ Info
>
> NGINX block: `http`
This directive is required to declare a **global** [rule](rules.md) or a [whitelist](whitelist.md).
> 💡 Tip
>
> You can define these within a config file and use the `include` directive to include them within the NGINX configuration.
You can find within the [Naxsi source code a list of global rules](https://github.com/wargio/naxsi/blob/main/naxsi_rules/) which provides a basic ruleset to protect any web application; these rules requires to include the following `CheckRules`:
```nginx
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
CheckRule "$UWA >= 8" BLOCK;
CheckRule "$EVADE >= 8" BLOCK;
```
### Example:
```nginx
http {
# global whitelist
MainRule wl:12345 "mz:$URL:/robots.txt|URL";
# global rule
MainRule id:45678 "s:$UWA:8" "str:nmap" "mz:$HEADERS_VAR:User-Agent" "msg:nmap in user-agent";
}
```
## **BasicRule**
> ️ Info
>
> NGINX block: `location`
This directive is required to declare a **location-specific** (i.e. not global) [rule](rules.md) or a [whitelist](whitelist.md).
> 💡 Tip
>
> You can define these within a config file and use the `include` directive to include them within the NGINX configuration.
> 💡 Tip
>
> You can find within the [Naxsi source code a list of location-specific whitelist](https://github.com/wargio/naxsi/tree/main/naxsi_rules/whitelists) which can be used for known web applications like Wordpress, Etherpad, Drupal, and more...
### Example:
```nginx
location / {
# location-specific whitelist
BasicRule wl:12345 "mz:$URL:/robots.txt|URL";
# location-specific rule
BasicRule id:45678 "s:$UWA:8" "str:nmap" "mz:$HEADERS_VAR:User-Agent" "msg:nmap in user-agent";
}
```
## **IgnoreIP**
> ️ Info
>
> NGINX block: `location`
This directive can be used to whitelist requests from certain IPs.
> 💡 Tip
>
> You can define these within a config file and use the `include` directive to include them within the NGINX configuration.
### Example:
```nginx
location / {
IgnoreIP "1.2.3.4";
IgnoreIP "2001:4860:4860::8844";
}
```
## **IgnoreCIDR**
> ️ Info
>
> NGINX block: `location`
This directive can be used to whitelist requests from certain IP ranges.
> 💡 Tip
>
> You can define these within a config file and use the `include` directive to include them within the NGINX configuration.
### Example:
```nginx
location / {
IgnoreCIDR "192.168.0.0/24";
IgnoreCIDR "2001:4860:4860::/112";
}
```
+79
View File
@@ -0,0 +1,79 @@
# **Naxsi Web Application Firewall Documentation**
Naxsi is a Free Open Source Web Application Firewall which runs under NGINX.
## What is a Web Application Firewall (WAF)?
A Web Application Firewall (WAF) is a security system that sits in front of a web application to inspect, filter, and block malicious traffic. It acts as an intermediary between the internet and your website or web application, examining HTTP requests and responses for potential threats.
One of the key features of WAFs is virtual patching, which allows them to protect against known vulnerabilities without requiring actual patches to be applied to the underlying code. Here's how it works on Naxsi:
1. **Rule-based detection**: The WAF has a list of known patterns, i.e. malicious request, which are used to block requests.
2. **Request analysis**: When an incoming HTTP request is received, the WAF analyzes its contents against the list of patterns.
3. **Threat identification**: If the request matches a known pattern, the WAF first checks if there is a whitelist rule and if not, then it assigns a score to the request; if this score exceeds the score limits then the request is blocked.
Naxsi is also capable to employ a whitelisting strategy, where all incoming traffic is initially blocked by default. In this case, only the requests that match specific rules are then allowed to pass through and reach the web application behind the WAF. This approach provides an added layer of security by assuming all unknown traffic poses a potential threat until proven otherwise.
## Virtual patching
Sometimes it happens that the web application behind the WAF might have a security vulnerability that cannot be patched immediately by the system owner; Naxsi can apply "virtual patches" to block the vulnerability without requiring changes to the underlying web application code.
By using virtual patching, the system owner can:
* Protect against zero-day attacks and unknown vulnerabilities
* Prevent exploitation of unpatched or outdated software versions
* Reduce the attack surface by blocking suspicious requests before they reach your website
These virtual patches are expressed in form of Naxsi rules and can be applied to RAW requests or specific fields within the request.
## What does it run on?
Naxsi should be compatible with any NGINX version, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS based systems.
## Why is it different?
Contrary to most Web Application Firewalls, Naxsi doesn't rely on a signature base like an antivirus, and thus cannot be circumvented by an "unknown" attack pattern.
# Getting Started
* **Installing Naxsi**: [Learn how to compile and install Naxsi from source code.](build-naxsi.md)
* **Basic Configuration**: [A basic configuration for Naxsi](basic-configuration.md).
# Configuration Options
* **Directives**: [Explains all the directives that are available when the Naxsi module is enabled.](directives.md)
* **Rules**: [Understand the different types of rules you can create in Naxsi.](rules.md)
* **Internal Rules**: [The full list of internal rules that are hardcoded in Naxsi](internal_rules.md)
* **Whitelists**: [Whitelisting to resolve false positives in Naxsi.](whitelist.md)
* **Matchzones**: [How zones can be used to filter rules or whitelists.](matchzones.md)
* **Logs**: [Log format and their content.](logs.md)
* **Packaging Naxsi**: [Build your own distro packages from sources.](packaging-naxsi.md)
# Support & Bugs
Questions & bug reports regarding NAXSI can be addressed via issues.
[Click here to open an issue](https://github.com/wargio/naxsi/issues/new)
# Vulnerability disclosure
When disclosing vulnerabilities, please send first an email to `deroad at kumo.xn--q9jyb4c` (gpg keyid: `29656E856786B9A1FBF983CFA219F52A8217B1FE`)
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEXR3FZhYJKwYBBAHaRw8BAQdAfuSDE68TEppjJfUAApXSTsHrKtGefVJXvz7f
YIO0gci0MUdpb3Zhbm5pIERhbnRlIEdyYXppb2xpIDxkZXJvYWRAa3Vtby54bi0t
cTlqeWI0Yz6IkAQTFggAOAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBCll
boVnhrmh+/mDz6IZ9SqCF7H+BQJg9+CGAAoJEKIZ9SqCF7H+X04BAPXz7R856z72
f8nsZZjj4q3YaJbXA3pSVLIJ9uDQniCsAP9PaPBcbr231M3cjjBMo7ovlrElfFor
zCWA3NhRb4Y2DLg4BF0dxWYSCisGAQQBl1UBBQEBB0AVby+EIQcIoqSDZelvkqt8
dV1kvF4f/J0jj0k3OEKNcAMBCAeIeAQYFggAIAIbDBYhBCllboVnhrmh+/mDz6IZ
9SqCF7H+BQJg9+C4AAoJEKIZ9SqCF7H+ZfQBAOFb7iZm7t8j5ymiXyJFcuM/nF9+
bx4+KJJUTR9r6zBFAQD3Ea5Ya4lny/v9WKNSpBfZFEs3pkDnfgxw3o8vc4iSAQ==
=d/IR
-----END PGP PUBLIC KEY BLOCK-----
```
# **Deprecated Documentation**
The deprecated/old documentation is accessible [here](old/index.md).
+178
View File
@@ -0,0 +1,178 @@
# **Internal Rules**
Naxsi has some internal rules that are hardcoded within the WAF; these rules are defined by **ids** lower than **1000**.
> 📣 Important
>
> The internal blocking rules can be whitelisted.
> ⚠️ Warning
>
> No rules shall be defined with **ids** lower than 1000.
## Internal Rule 1 - Weird Request
> ❌ **Deprecated**
>
> Number: **1**
> Name: **Weird Request**
> Action: **BLOCK**
The internal rule `1` refers to any request that contains weird request which failed to be parsed by Naxsi.
## Internal Rule 2 - Big Request
> ️ Info
>
> Number: **2**
> Name: **Big Request**
> Action: **BLOCK**
The internal rule `2` refers to any request that is too big to be parsed; this only happens when NGINX has to create a temporary file on the filesystem or when the content-size mismatch with the actual body size.
## Internal Rule 10 - Hex Encoded Null-Bytes
> ️ Info
>
> Number: **10**
> Name: **Null-Byte Hex Encoding**
> Action: **BLOCK**
The internal rule `10` refers to any request that contains one or many hex encoded null-bytes (i.e. `0x00` or `\x00`).
## Internal Rule 11 - Uncommon Content Type
> ️ Info
>
> Number: **11**
> Name: **Uncommon Content Type**
> Action: **BLOCK**
The internal rule `11` refers to any request that contains uncommon content type; this happens when `Content-Type` header is missing or during a POST request, the `Content-Type` is not one of the followings:
- `"application/x-www-form-urlencoded"`
- `"multipart/form-data"`
- `"application/json"`
- `"application/vnd.api+json"`
- `"application/csp-report"`
## Internal Rule 12 - Invalid formatted URL
> ️ Info
>
> Number: **12**
> Name: **Invalid formatted URL**
> Action: **BLOCK**
The internal rule `12` refers to any request that contains a badly formatted URL; this happens when the HTTP request has an invalid URL (this may be caught before-hand by NGINX which may return 400).
## Internal Rule 13 - Malformed POST Format
> ️ Info
>
> Number: **13**
> Name: **Malformed POST Format**
> Action: **BLOCK**
The internal rule `13` refers to any request that contains a malformed POST, for example missing `content-disposition`, malformed boundary line, missing name, missing `Content-Type`, etc...
## Internal Rule 14 - Malformed POST Boundary
> ️ Info
>
> Number: **14**
> Name: **Malformed POST Boundary**
> Action: **BLOCK**
The internal rule `14` refers to any request that contains a malformed POST boundary.
## Internal Rule 15 - Malformed JSON
> ️ Info
>
> Number: **15**
> Name: **Malformed JSON**
> Action: **BLOCK**
The internal rule `15` refers to any request that contains malformed JSON.
## Internal Rule 16 - Empty POST Body
> ️ Info
>
> Number: **16**
> Name: **Empty POST Body**
> Action: **BLOCK**
The internal rule `16` refers to any request that contains empty POST body.
## Internal Rule 17 - libinjection SQLi
> ️ Info
>
> Number: **17**
> Name: **libinjection SQLi**
> Score: **$LIBINJECTION_SQL**
> ⚠️ Warning
>
> This rule does not block a request, but increases the score `$LIBINJECTION_SQL` by **1**.
The internal rule `17` refers to any request that contains sql injections detected by libinjection.
See also [Directive `LibInjectionSql`](directives.md#libinjectionsql) for more details.
## Internal Rule 18 - libinjection XSS
> ️ Info
>
> Number: **18**
> Name: **libinjection Xss**
> Score: **$LIBINJECTION_XSS**
> ⚠️ Warning
>
> This rule does not block a request, but increases the score `$LIBINJECTION_XSS` by **1**.
The internal rule `18` refers to any request that contains XSS injections detected by libinjection.
See also [Directive `LibInjectionXss`](directives.md#libinjectionxss) for more details.
## Internal Rule 19 - No Rules Loaded
> ️ Info
>
> Number: **19**
> Name: **No Rules**
> Action: **DROP**
The internal rule `19` is triggered only when the WAF is enabled but no global and no location-specific rules has been loaded at the current location.
## Internal Rule 20 - Malformed UTF-8
> ️ Info
>
> Number: **20**
> Name: **Malformed UTF-8**
> Action: **DROP**
The internal rule `20` refers to any request that contains malformed UTF-8.
## Internal Rule 21 - Illegal Host in Header
> ️ Info
>
> Number: **21**
> Name: **Illegal Host in Header**
> Action: **DROP**
The internal rule `21` refers to any request that contains a host header with an illegal ip:
- `0.0.0.0/8`
- `255.255.255.255/32`
- `0000:0000:0000:0000:0000:0000:0000:0000/128`
- `ff00:0000:0000:0000:0000:0000:0000:0000/8`
# Go Back
[Rules](rules.md).
+116
View File
@@ -0,0 +1,116 @@
# **Naxsi Logs**
Naxsi utilizes NGINX's `error_log` feature to produce logs; specifically, it offers two types of error logs that can be generated: one in **URL-encoded format** (which is the default option) and another in **JSON format**.
These logs are `action log` and `extended log`. They include detailed information about the triggered rules, content identified, paths and request IDs for comprehensive security monitoring and analysis.
> ⚠️ Warning
>
> Due to hardcoded limitations of NGINX (see `NGX_MAX_ERROR_STR` defined by `ngx_log.h` in the NGINX source code), these logs may be truncated if too long.
>
> It is strongly recommanded to increase the line limit to `8192` or higher by patching NGINX itself.
>
> Example of patch: `sed -i 's#NGX_MAX_ERROR_STR 2048#NGX_MAX_ERROR_STR 8192#g' src/core/ngx_log.h`
## Action Logs
Action logs contains the following information:
- `ip`: Client IP
- `server`: Nginx server name
- `uri`: Request URI
- `config`: Configuration of naxsi for the applied rule, this can be one of the following values:
- `learning` [Learning Mode active](directives.md#learningmode), i.e. The [action taken is `LOG`](directives.md#checkrule) and the **request was NOT dropped**.
- `learning-drop` [Learning Mode active](directives.md#learningmode) but request was dropped, i.e. [The action taken is `DROP`](directives.md#checkrule).
- `drop` The request was dropped, i.e. [The action taken is `DROP`](directives.md#checkrule).
- `block` The request was dropped, i.e. [The action taken is `BLOCK`](directives.md#checkrule).
- `ignore` The request was supposed to be dropped/blocked, but it was ignored due to matching [`IgnoreIP`](directives.md#ignoreip) or [`IgnoreCIDR`](directives.md#ignorecidr), i.e. [The action taken is `LOG`](directives.md#checkrule).
- `rid`: Request Identifier (matches the `request_id` NGINX value).
- `id<N>`: Matched rule identifier
- `cscore<N>`: Request score name (see [Check Rules](directives.md#checkrule)), for example `$SQL`.
- `score<N>`: Request score value (see [Check Rules](directives.md#checkrule)), for example `8`.
- `zone<N>`: Request [matchzone](matchzones.md), for example `URL`.
- `var_name<N>`: Request variable name where the match has happen, for example `foo_bar[]`.
> ️ Info
>
> The `<N>` is a counter that always starts from `0` for each request and is used for listing all the matched rules and their info (`id`, `cscore`, etc..).
>
> For example, a request can have multiple matching rules and these will be logged by Naxsi as follows:
>
> The first rule (`<N>=0`) is logged as `id0=<id>`, `cscore0=<score name>`, `score0=<score count>`, `zone0=<matchzone>`, `var_name0=<var name>`; the second rule (`<N>=1`) is going to be `id1=<id>`, `cscore1=<score name>`, `score1=<score count>`, `zone1=<matchzone>`, `var_name1=<var name>`, the third (`<N>=2`), etc...
>
> If the rule score name is the same for multiple rules, the first `cscoreX` defined in the logs will contain the sum of the total score of multiple rules.
## Extended Logs
Extended logs needs to be enabled by adding `set $naxsi_extensive_log 1;` or via the runtime modifier `naxsi_extensive_log` to the NGINX configuration and logs all the matches of a request:
- `ip`: Client IP
- `server`: Nginx server name
- `rid`: Request Identifier (matches the `request_id` NGINX value).
- `uri`: Request URI
- `id`: Matched rule identifier
- `zone`: Request [matchzone](matchzones.md), for example `URL`.
- `var_name`: Request variable name where the match has happen, for example `foo_bar[]`.
- `content`: The matched content, for example `malicious` (can be truncated if too long).
*Action format logs* can be distinguished by *extended logs* the presence of `cscore` & `score` keywords; *Extended logs* are also the only ones having the `content` keyword.
## URL Encoded logs
**This is the default logging format for Naxsi**; These logs are always preceded by `NAXSI_FMT` (action logs) or `NAXSI_EXLOG` (extended logs) and the values of each logged info is `url-encoded`.
Example:
```
2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_EXLOG: ip=127.0.0.1&server=localhost&rid=70d8cd8818e7e27a11d14df63c676227&uri=%2Fx%2Cy&id=1015&zone=URL&var_name=&content=%2Fx%2Cy, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_EXLOG: ip=127.0.0.1&server=localhost&rid=70d8cd8818e7e27a11d14df63c676227&uri=%2Fx%2Cy&id=1015&zone=ARGS&var_name=uuu&content=b%2Cc, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_FMT: ip=127.0.0.1&server=localhost&uri=%2Fx%2Cy&config=learning&rid=70d8cd8818e7e27a11d14df63c676227&cscore0=$SQL&score0=8&zone0=URL&id0=1015&var_name0=&zone1=ARGS&id1=1015&var_name1=uuu, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
```
## JSON logs
This logs format needs to be enabled via `set $naxsi_json_log 1;` or via the runtime modifier `naxsi_json_log`.
*Action logs* can be distinguished by *extended logs* the presence of `cscore` & `score` keywords; *Extended logs* are also the only ones having the `content` keyword.
```
2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","uri":"/x,y","id":1015,"zone":"URL","var_name":"","content":"/x,y"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","uri":"/x,y","id":1015,"zone":"ARGS","var_name":"uuu","content":"b,c"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","uri":"/x,y","config":"block","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","cscore0":"$SQL","score0":8,"zone0":"URL","id0":1015,"var_name0":"","zone1":"ARGS","id1":1015,"var_name1":"uuu"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost"
```
Here is an example of how the previous JSON logs appears when formatted by utilities such as `jq`:
```json
// Action Log
{
"ip": "127.0.0.1",
"server": "localhost",
"uri": "/x,y",
"config": "block",
"rid": "1d27ac3c0b10bbb8783d109213f3f4cd",
"cscore0": "$SQL",
"score0": 8,
"zone0": "URL",
"id0": 1015,
"var_name0": "",
"zone1": "ARGS",
"id1": 1015,
"var_name1": "uuu"
}
// Extended Log
{
"ip": "127.0.0.1",
"server": "localhost",
"rid": "1d27ac3c0b10bbb8783d109213f3f4cd",
"uri": "/x,y",
"id": 1015,
"zone": "URL",
"var_name": "",
"content": "/x,y"
}
```
+222
View File
@@ -0,0 +1,222 @@
# **Naxsi Matchzones**
**Matchzones**, denoted by the prefix `mz:`, are crucial components of **rules** and **whitelists**. They act like filters to define specific locations where a pattern should be searched or allowed.
Here's how they function differently based on the context:
- **Rules:** In this case, matchzones work with an **OR** logic (like `BODY` OR `HEADERS`). This means that as long as one of the specified conditions is met, the rule triggers.
- **Whitelists:** Here, matchzones operate under an **AND** logic (like `url` must be `/foo` AND must occur in `ARGS`). It requires that *both conditions* within a whitelist be satisfied before the pattern is allowed.
> 📣 Important
>
> Naxsi decodes any `url-encoded` or `hexadecimal` sequence, this means the string or regex to search for must be of the decoded content (**this applies also to URLs**).
>
> Example: `1%20UnioN%20SeLEct%201` becomes `1 UnioN SeLEct 1` before applying rules.
## Any Matchzone
This special matchzone designated by `ANY` allows to define **rules and whitelists which matches in any area of a request**.
For instance, the rule `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ANY";` is equivalent of writing the following rules but in one line.
```
MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ARGS|HEADERS|BODY|URL";
MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:RAW_BODY";
MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:FILE_EXT";
```
> 📣 Important
>
> This can be used also for whitelists, but it is possible to disable a rule by just not declaring any matchzone (see the [Whitelist matchzones notes](whitelist.md#matchzone)).
## Filter by HTTP Headers
HTTP headers let the client and the server pass additional information with a message in a request or response; Naxsi allows to filter rules and whitelists by headers as follows:
### Filter by Any HTTP header value
This Matchzone designated by `HEADERS` is specifically tailored to identify **only the content found within HTTP headers**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:HEADERS";` detects the occurrence of the string `malicious` exclusively within the HTTP headers values transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:HEADERS";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP header values.
### Filter by Any HTTP header name
This Matchzone designated by `HEADERS|NAME` is specifically tailored to identify **only the name of the header found within HTTP request**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8" "str:x-forward-to" "mz:HEADERS|NAME";` detects the occurrence of the string `X-Forward-To` exclusively within the HTTP headers names transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:HEADERS|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP header name.
### Filter by HTTP header name
This Matchzone designated by `$HEADERS_VAR:foo` and `$HEADERS_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP header named `foo`**.
- `$HEADERS_VAR:<string>` can be used to filter by header name (**case-insensitive**) via a string.
- `$HEADERS_VAR_X:<regex>` can be used to filter by header name (**case-insensitive**) via a regex.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:curl" "mz:$HEADERS_VAR:user-agent|$HEADERS_VAR:cookie";` detects the occurrence of the string `curl` exclusively within the value of the HTTP headers `User-Agent` and `Cookie` (**case-insensitive**).
- A whitelist entry like `BasicRule wl:12345 "mz:$HEADERS_VAR_X:^cookie$";` negates the match of any rule with id `12345` if the match occurs within the value of the HTTP header `Cookie` via regex.
> 📣 Important
>
> This can be mixed with `|NAME` to perform the filtering at argument name instead of value.
> Example: `mz:$HEADERS_VAR_X:^foo\d+$|NAME` matches only the HTTP header named `foo<number>`.
## Filter by GET query
HTTP GET requests can carry information, referred as queries, in the form of key=value pairs; Naxsi allows to filter rules and whitelists by these arguments as follows:
### Filter by Any GET query value
This Matchzone designated by `ARGS` is specifically tailored to identify **only the value found within HTTP GET query**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ARGS";` detects the occurrence of the string `malicious` exclusively within the HTTP GET queries values transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:ARGS";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP GET queries values.
### Filter by Any GET query name
This Matchzone designated by `ARGS|NAME` is specifically tailored to identify **only the name of the GET query found within HTTP request**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8" "str:delete_action" "mz:ARGS|NAME";` detects the occurrence of the string `delete_action` exclusively within the HTTP GET queries names transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:ARGS|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP GET queries names.
### Filter by GET query value or name
This Matchzone designated by `$ARGS_VAR:foo` and `$ARGS_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP GET query named `foo`**.
- `$ARGS_VAR:<string>` can be used to filter by argument name (**case-insensitive**) via a string.
- `$ARGS_VAR_X:<regex>` can be used to filter by argument name (**case-insensitive**) via a regex.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:evil" "mz:$ARGS_VAR:foo|$ARGS_VAR:bar";` detects the occurrence of the string `evil` exclusively within the value of the GET queries `User-Agent` (**case-insensitive**).
- A whitelist entry like `BasicRule wl:12345 "mz:$ARGS_VAR_X:^cookie$";` negates the match of any rule with id `12345` if the match occurs within the value of the HTTP header `Cookie` via regex.
> 📣 Important
>
> This can be mixed with `|NAME` to perform the filtering at argument name instead of value.
> Example: `mz:$ARGS_VAR_X:^foo\d+$|NAME` matches only the GET query named `foo<number>`.
## Filter by POST Requests
HTTP POST requests carries information in the HTTP body; the request data can have multiple formats:
- `application/x-www-form-urlencoded` contains key=value pairs.
- `multipart/form-data` contains boundaries with the raw data.
Naxsi allows to filter these in rules and whitelists as follows:
### Filter by Any `application/x-www-form-urlencoded` Value
This Matchzone designated by `BODY` is specifically tailored to identify **only the value found within HTTP POST body**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:BODY";` detects the occurrence of the string `malicious` exclusively within the HTTP POST body values (key=value format) transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:BODY";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP POST body values.
### Filter by Any `application/x-www-form-urlencoded` Key
This Matchzone designated by `BODY|NAME` is specifically tailored to identify **only the name of the header found within HTTP request**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8" "str:delete_action" "mz:BODY|NAME";` detects the occurrence of the string `delete_action` exclusively within the HTTP POST arguments names transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:BODY|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP POST arguments names.
### Filter by Any `application/x-www-form-urlencoded` Key and Value
This Matchzone designated by `$BODY_VAR:foo` and `$BODY_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP POST body named `foo`**.
- `$BODY_VAR:<string>` can be used to filter by POST form name (**case-insensitive**) via a string.
- `$BODY_VAR_X:<regex>` can be used to filter by POST form name (**case-insensitive**) via a regex.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:$BODY_VAR:foo|$BODY_VAR:bar";` detects the occurrence of the string `malicious` exclusively within the value of the POST form keys `foo` and `body` (**case-insensitive**).
- A whitelist entry like `BasicRule wl:12345 "mz:$BODY_VAR_X:^foo$";` negates the match of any rule with id `12345` if the match occurs within the value of the POST form named `foo` via regex.
> 📣 Important
>
> This can be mixed with `|NAME` to perform the filtering at argument name instead of value.
> Example: `mz:$BODY_VAR_X:^foo\d+$|NAME` matches only the POST argument named `foo<number>`.
### Filter by Any `multipart/form-data` filename
This Matchzone designated by `FILE_EXT` is specifically tailored to match **only the filename found within HTTP multipart POST request**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:.php" "mz:FILE_EXT";` detects the occurrence of the string `.php` exclusively within the filename of the HTTP multipart POST request.
- A whitelist entry like `BasicRule wl:12345 "mz:FILE_EXT";` negates the match of any rule with id `12345` if the match itself occurs in the filename of the HTTP multipart POST request.
## Filter by HTTP Raw Body
This Matchzone designated by `RAW_BODY` is specifically tailored to match **any byte sequence in an unparsed HTTP body**.
For instance:
- A rule such as `BasicRule id:12345 "s:$EXECUTABLE:8" "rx:MZ\x90" "mz:RAW_BODY";` detects the occurrence of a byte sequence (Windows PE magic) within the HTTP body of the request.
- A whitelist entry like `BasicRule wl:12345 "mz:RAW_BODY";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP body of the request.
> 📣 Important
>
> This matchzone is internally converted as `BODY` zone, thus the `BasicRule wl:12345 "mz:BODY";` and `BasicRule wl:12345 "mz:RAW_BODY";` are equivalent.
## Filter by HTTP URL
Naxsi supports filtering by HTTP URL as follows:
### Filter by HTTP URL (global)
This Matchzone designated by `URL` is specifically tailored to identify **only the value found within HTTP URL**.
For instance:
- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:/admin" "mz:URL";` detects the occurrence of the string `/admin` exclusively within the HTTP URL transmitted in a request.
- A whitelist entry like `BasicRule wl:12345 "mz:URL";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP URL.
> 📣 Important
>
> This matchzone is globally applied, it is possible to restrict the matchzone to a specific URL or substring in the URL via `$URL` or `$URL_X` (see below).
### Filter by HTTP URL (restricted)
This Matchzone designated by `$URL:/foo` and `$URL_X:^/foo$` is specifically tailored to identify **only the URL containing the string `/foo`**.
- `$URL:<string>` can be used to filter by string (**case-insensitive**).
- `$URL_X:<regex>` can be used to filter by regex (**case-insensitive**).
These can be mixed with all the previous matchzones as follows:
In rules context, `$URL` or `$URL_X` *must* be satisfied if present. Any other condition is treated as *OR* (opposite to whitelists).
- The rule `BasicRule str:Y id:X "mz:ARGS|BODY";` is interpreted as _pattern 'Y' will be matched against *any* GET and POST arguements_
- The rule `BasicRule str:Y id:X "mz:ARGS|BODY|$URL:/foo";` is interpreted as _pattern 'Y' will be matched against *any* GET and POST arguements as long as URL is `/foo`_
In whitelist context, *all* conditions must be satisfied, so a whitelist like `BasicRule wl:X "mz:$ARGS_VAR:foo|$URL:/bar";` is interpreted as _id X is whitelisted in GET variable `foo` on URL `/bar`_
> ⚠️ Warning
>
> **You CANNOT mix `$URL_X:<regex>` and `$ARGS_VAR:<string>`, `$BODY_VAR:<string>` and `$HEADERS_VAR:<string>` in a rule or whitelist.**
>
> It is allowed instead to mix `$URL_X:<regex>` with `$ARGS_VAR_X:<regex>`, `$BODY_VAR_X:<regex>` and `$HEADERS_VAR_X:<regex>` and to mix `$URL:<string>` with `$ARGS_VAR:<string>`, `$BODY_VAR:<string>` and `$HEADERS_VAR:<string>`.
> ️ Info
>
> It is allowed to mix `FILE_EXT` and `RAW_BODY` with `$URL_X:<regex>` and `$URL:<string>`.
# Go Back
[Table of Contents](index.md).
+18
View File
@@ -0,0 +1,18 @@
## Contributing to naxsi
We're happily taking patches, contributions, improvements, please see below :
### Naxsi Core Requirements (runtime)
* Unit tests with a decent (>90%) coverage
* Peer review by core devs in terms of quality/security impacts
* For all runtime code, please fuzz the code (see `fuzz` Makefile's target)
* For all runtime code, merge will require that we get clean static analysis results (coverity)
### NxTool/NxAPI
* Peer review by other developers
* General interest for the feature
Thanks in advance !
+22
View File
@@ -0,0 +1,22 @@
You can list which IP or CIDR (i.e 192.168.0.1/24), should be always allowed and never blocked.
IP is taken from `X-Forwarder-for` header (when available or from the client IP).
Your load balancer, some proxy could add it already, but if not you can add it with `proxy_set_header X-Forwarded-For $remote_addr;`
Usage:
```
location / {
SecRulesEnabled;
IgnoreIP "1.2.3.4";
IgnoreCIDR "192.168.0.0/24";
DeniedUrl "/RequestDenied";
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
root /var/www/html/;
index index.html index.htm;
}
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

+31
View File
@@ -0,0 +1,31 @@
# Checkrules
CheckRules instruct naxsi to take an action (`LOG`, `BLOCK`, `DROP`, `ALLOW`) based on a specific score associated to the request. This _score_ has usually been set by one or several [rule(s)](rules-bnf.md).
`CheckRule` must be present at location level.
![CheckRule schema](Images/checkrule.png)
### Basic Usage
A typical `CheckRule` is :
```
CheckRule "$SQL >= 8" BLOCK;
```
If the `$SQL` is equal or superior to '8', apply BLOCK flag to the request. Request will only be blocked if location is _not_ in learning mode.
### Other Usages
`CheckRule(s)` can as well be used to mix white and black-lists.
Having a configuration mixing virtual-patching (see [rules](rules-bnf.md)) and `naxsi_core.rules`, it is possible to have :
```
CheckRule "$UWA >= 4" DROP;
CheckRule "$XSS >= 8" BLOCK;
```
Thus - even in learning mode - any request with `$UWA` score equal to 4 will block the requests, while requests with `$XSS` score (even superior to 8) will only be blocked on location(s) *not* in learning.
+177
View File
@@ -0,0 +1,177 @@
# Directives
## DeniedUrl
* alias: denied_url
* context: location
`DeniedUrl` is a directive that indicates where naxsi will redirect (nginx's internal redirect) blocked requests.
As the request might be modified during redirect (url & arguments), extra http headers orig_url (original url),
orig_args (original GET args) and naxsi_sig (NAXSI_FMT) are added.
The headers that are forwarded to the location denied page are :
NAXSI_HEADER_ORIG_URL "x-orig_url"
NAXSI_HEADER_ORIG_ARGS "x-orig_args"
NAXSI_HEADER_NAXSI_SIG "x-naxsi_sig"
example:
```
location / {
...
DeniedUrl "/RequestDenied";
}
location /RequestDenied {
return 418; #I'm a teapot
}
```
## LearningMode
* alias: learning_mode
* context: location
`LearningMode` if instructs naxsi to enable learning mode (don't honor `BLOCK` directive) in the location.
For example:
```nginx
location /a {
# request triggering BLOCK score won't be blocked here, but simply logued.
LearningMode;
}
```
Keep in mind that internal rules (those with an `id` inferior to 1000) will drop the request even in learning mode, because it means that something fishy is going on, since naxsi can't correctly process the request.
You can of course apply [whitelist](whitelists-bnf.md) if those are false-positives.
## SecRulesEnabled
* alias: rules_enabled
* context: location
`SecRulesEnabled` is a mandatory keyword to enable naxsi in a location.
## SecRulesDisabled
* alias: rules_disabled
* context: location
`SecRulesDisabled` can be used to explicitely disable naxsi in a location.
## CheckRule
* alias: check_rule
* context: location
See [CheckRule](checkrules-bnf.md)
## BasicRule
* alias: basic_rule
* context: location
A directive used to declare a [rule](rules-bnf.md) or a [whitelist](whitelist-bnf.md).
## MainRule
* alias: main_rule
* context: http
A directive used to declare a [rule](rule-bnf.md) or a [whitelist](whitelist-bnf.md).
## LibInjectionXss
* alias: libinjection_xss
* context: location
A directive to enable [libinjection's xss detection](libinjection-integration.md) on *all* part of the http request.
## LibInjectionSql
* alias: libinjection_sql
* context: location
A directive to enable [libinjection's sqli detection](libinjection-integration.md) on *all* part of the http request.
## naxsi_extensive_log
* context: server
A flag that can be set at [runtime](runtime-modifiers.md) to enable [naxsi extensive logs](naxsilogs.md#naxsi_exlog).
```
server {
...
if ($remote_addr = "1.2.3.4") {
set $naxsi_extensive_log 1;
}
location / {
...
}
}
```
## naxsi_json_log
* context: server
Enable JSON in logs. Examples:
```
# normal log in JSON format
2022/12/22 20:36:35 [error] 1189262#0: *1 {"ip":"127.0.0.1","server":"localhost","uri":"/a","config":"block","rid":"a0333f697ff8f12b6a200a24117ff320","cscore0":"$SQL","score0":"8","cscore1":"$XSS","score1":"8","zone0":"ARGS","id0":"1001","var_name0":"b"}, client: 127.0.0.1, server: localhost, request: "GET /a?b="\dasdasdasdadsa HTTP/1.1", host: "localhost"
# extended log in json format
2022/12/22 20:36:35 [error] 1189262#0: *1 {"ip":"127.0.0.1","server":"localhost","uri":"/a","config":"block","rid":"a0333f697ff8f12b6a200a24117ff320","cscore0":"$SQL","score0":"8","cscore1":"$XSS","score1":"8","zone0":"ARGS","id0":"1001","var_name0":"b"}, client: 127.0.0.1, server: localhost, request: "GET /a?b="\dasdasdasdadsa HTTP/1.1", host: "localhost"
```
TODO DOCUMENTATION
## naxsi_flag_enable
* context: server
A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable naxsi.
```
server {
set $naxsi_flag_enable 1;
location / {
...
}
}
```
## naxsi_flag_learning
* context: server
A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable learning.
```
server {
set $naxsi_flag_learning 1;
location / {
...
}
}
```
## naxsi_flag_libinjection_sql
* context: server
A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable [libinjection's sql detection](libinjection-integration.md)
```
server {
set $naxsi_flag_libinjection_sql 1;
location / {
...
}
}
```
## naxsi_flag_libinjection_xss
A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable [libinjection's xss detection](libinjection-integration.md)
```
server {
set $naxsi_flag_libinjection_xss 1;
location / {
...
}
}
```
+34
View File
@@ -0,0 +1,34 @@
1. Setup
- [compiling nginx+naxsi](naxsi-compile.md)
- [Basic nginx/naxsi configuration](naxsi-setup.md)
2. Naxsi Configuration Directives
- [whitelists](whitelists-bnf.md)
- [rules](rules-bnf.md)
- [checkrules](checkrules-bnf.md)
- [requestdenied](requestdenied-bnf.md)
- [naxsi directives index](directives.md)
- [zoom : matchzones](matchzones-bnf.md)
3. Naxsi Extras
- [Raw Body Parsing](rawbody.md)
- [libinjection integration](libinjection-integration.md)
- [json support](json.md)
- [runtime modifiers](runtime-modifiers.md)
4. Examples
- [whitelists examples](whitelists-examples.md)
- [rules examples](rules-examples.md)
5. Going deeper
- [Understanding naxsi logs](naxsilogs.md)
- [Runtime Modifiers](runtime-modifiers.md)
- [Naxsi internal rules](internal-rules.md)
- [Contributing to naxsi](Contributing.md)
6. Integration
- [Fail2Ban integration](integration-fail2ban.md)
- [AppArmor profile for naxsi](integration-apparmor.md)
8. Legacy/old pages
- [LEGACY WIKI](legacy/legacy.md)
- [Old FAQ](legacy/olds-faq.md)
- [Old Vulnerability management](olds-Security-Advisories.md)
- Old Naxsi rules mamagement
- [installing nxapi](https://github.com/nbs-system/naxsi/tree/master/nxapi.md) (**deprecated**)
- [nxapi/nxtool](https://github.com/nbs-system/naxsi/tree/master/nxapi.md) (**deprecated**)
- [spike](http://github.com/nbs-system/spike.md) (**deprecated**)
+118
View File
@@ -0,0 +1,118 @@
# Introduction
If you care about process access control on a [AppArmor]( http://apparmor.net ) enabled *GNU/Linux* platform, and you are using Naxsi, this article is for you.
Of course defining a AppArmor profile is not straight forward and must be customized. AppArmor developers know that and provided tools easing the creation of application profiles.
Of course, path to files may change depending on your local setup.
# Requirements
You basically need:
* A GNU/Linux platform with kernel support for AppArmor, [Ubuntu]( http://www.ubuntu.com/ ) for example
* `apt-get install apparmor-utils`
* A running Nginx/Naxsi
* A couple of minutes
# Generating the profile
As root, run the following command to generate a profile:
```
aa-genprof /usr/local/sbin/nginx
```
Then answer the few questions:
```
Connecting to repository.....
WARNING: Error fetching profiles from the repository:
RPC::XML::Client::send_request: HTTP server error: Not Found
Writing updated profile for /usr/local/sbin/nginx.
Setting /usr/local/sbin/nginx to complain mode.
Please start the application to be profiled in
another window and exercise its functionality now.
Once completed, select the "Scan" button below in
order to scan the system logs for AppArmor events.
For each AppArmor event, you will be given the
opportunity to choose whether the access should be
allowed or denied.
Profiling: /usr/local/sbin/nginx
[(S)can system log for SubDomain events] / (F)inish
```
Now stop, start, reload, restart Nginx in order to generate apparmor logs. Then press 'S'
```
Reading log entries from /var/log/messages.
Updating AppArmor profiles in /etc/apparmor.d.
Complain-mode changes:
Profile: /usr/local/sbin/nginx
Path: /etc/nginx/mime.types
Mode: owner r
Severity: unknown
[1 - /etc/nginx/mime.types]
[(A)llow] / (D)eny / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t / (F)inish / (O)pts
```
Now we are starting to profile the program and it is then really up to you to decide which file need to be accessed, with which access rights, by Nginx.
Once done with answering those questions, a apparmor profile for `/usr/local/sbin/nginx` will be created in `/etc/apparmor.d/usr.local.sbin.nginx`.
Here is mine:
```apparmor
# Last Modified: Wed Jul 25 11:33:59 2012
#include <tunables/global>
/usr/local/sbin/nginx {
#include <abstractions/apache2-common>
#include <abstractions/base>
#include <abstractions/nameservice>
capability dac_override,
capability dac_read_search,
capability setgid,
capability setuid,
owner /etc/nginx/** r,
owner /etc/ssl/openssl.cnf r,
/var/lib/certificates/* r,
owner /var/log/nginx/* a,
/var/log/nginx/* w,
owner /var/run/nginx.pid rw,
/var/www/** r,
}
```
# Updating the profile for some time
Unless you precisely know what the program is doing it is a good idea to let it live for some time and gather the logs that will improve your Apparmor profile.
So we activate the complain mode of AppArmor:
aa-complain /etc/apparmor.d/usr.local.sbin.nginx
And after some time (depending on your usage of Nginx):
aa-logprof /etc/apparmor.d/usr.local.sbin.nginx
This command will simply go through the logs and ask you about updating Nginx profile.
# Enforcing the profile and open up Naxsi to tougher guys
aa-enforce /etc/apparmor.d/usr.local.sbin.nginx
Yep that's all!
BUT! Unauthorized access caught by AppArmor in enforce mode will NOT generate you extra logs! For that you need the “audit” mode (aa-audit). Sadly the audit mode also logs authorized access so it can rapidly become unreadable (you read dmesg output all the time don't you?)
Enjoy Naxsi and Apparmor!
+40
View File
@@ -0,0 +1,40 @@
### Introduction
[Fail2ban]( http://fail2ban.org ) is a nice piece of software allowing you to act on the IP address of someone abusing you, usually banning him using [netfilter]( http://netfilter.org ). Basically you want to ban all skids bruteforcing you SSH service or your webmail login form.
We figured out that *dropping skids^Whackers is cool, banning them is even better*. So this howto will show you how to ban those who are appearing to much in your naxsi logs.
# Requirements
* An OS running Fail2ban and Naxsi
* A few minutes
# Configuration
Very simple, create `/etc/fail2ban/filter.d/nginx-naxsi.conf` with:
```ini
[INCLUDES]
before = common.conf
[Definition]
failregex = NAXSI_FMT: ip=<HOST>&server=.*&uri=.*&learning=0
NAXSI_FMT: ip=<HOST>.*&config=block
ignoreregex = NAXSI_FMT: ip=<HOST>.*&config=learning
```
And add a section within `/etc/fail2ban/jail.conf` with:
```ini
[nginx-naxsi]
enabled = true
port = http,https
filter = nginx-naxsi
logpath = /var/log/nginx/*error.log
maxretry = 6
```
So in `/var/log/fail2ban.log`, any time the same IP triggers Naxsi 6 times in 5 minutes (`fail2ban findtime=600`) you should see:
```
2012-06-29 15:34:44,016 fail2ban.actions: WARNING [nginx-naxsi] Ban 88.z.x.y`
```
BONUS: Graph this new fail2ban jail with [Munin]( http://munin-monitoring.org/ ) so you can track how many guys are trying to abuse your website :)
+109
View File
@@ -0,0 +1,109 @@
# Internal rules
Internal rules are rules that can be fired by naxsi, when request is incorrect or extremely unusual - or naxsi is not able to parse the request (ie. unknown content-type).
Please note that those rules do not set an internal score, but usually just set the `block` flag of the request to `1`.
You can whitelist those, but you should never have to do so.
When whitelisting an internal rule, you might be disabling naxsi at least partially, so think twice about it.
## weird_request
* id: 1
* action: block
* impact: pass-thru
A request that cannot be understood by naxsi.
When whitelisting this one, you are telling naxsi to blindly accept the request and not to parse it.
## big_request
* id: 2
* action: block
* impact : pass-thru
A request that is buffered on file system because it's too big.
Naxsi doesn't parse buffered requests. You can always increase [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) in nginx's config.
## uncommon_hex_encoding
* id: 10
* action: block
* impact : partial loss of decoding
Hex encoding that is not valid, and that naxsi cannot "url decode".
## uncommon_content_type
* id: 11
* action: block
* impact : pass-thru on BODY
A content-type unknown to naxsi. Meaning naxsi cannot parse the body.
However, if id:11 is whitelisted and >= 0.55rc2, [RAW_BODY](rawbody) rules can be used.
## uncommon_url
* id: 12
* action: block
* impact: partial pass-thru on GET args
An URL that is not standard (ie. `?x=foo&z=bar`). Can lead to uncorrectly parsed arguments when whitelisted.
# uncommon_post_format
* id: 13
* action: block
* impact: pass-thru on BODY
POST body is malformed, ie.
* bad content-disposition
* no variable name
* malformed attached file content-type
## uncommon_post_boundary
* id: 14
* action: block
* impact: pass-thru on BODY
POST body is malformed, ie.
* bad content-type
* bad boundary (too short, too long, not rfc compliant)
## invalid_json
* id: 15
* action: block
* impact: pass-thru on BODY (json)
JSON is malformed (ie. missing `} ]`).
## empty_body
* id: 16
* action: block
* impact: pass-thru on BODY
Raised when body is empty and/or content-length is zero.
## libinjection_sql
* id: 17
* action: ??
See [libinjection](libinjection-integration.md).
## libinjection_xss
* id: 18
* action: ??
See [libinjection](libinjection-integration.md).
## no_rules
* id: 19
* action: drop
* impact: no rules checked
Raised when naxsi isn't configured with any MainRules.
## bad_utf8
* id: 20
* action: drop
Raised when [surrogate utf8](https://tools.ietf.org/html/rfc3629) is detected.
+31
View File
@@ -0,0 +1,31 @@
# JSON
POST/PUT request with content-type `application/json` will be handled by naxsi so that it should be transparent in the whitelist / signatures writting process :
* all rules targeting `BODY` are applied to json content as well
* whitelists (or rules) for specific variable use the classic `$BODY_VAR:xx`
However for JSON, naxsi does not keep track of depth, and has [a hardcoded limit of 10 (depth)](internal-rules.md#invalid_json).
A request :
```
POST ...
{
"this" : { "will" : ["work", "does"],
"it" : "??" },
"tr<igger" : {"test_1234" : ["foobar", "will", "trigger", "it"]}
}
```
A rule that will match :
```
MainRule "str:foobar" "msg:foobar test pattern" "mz:BODY" "s:$SQL:42" id:1999;
```
The associated whitelist :
```
BasicRule wl:X "mz:$BODY_VAR:test_1234";
```
+29
View File
@@ -0,0 +1,29 @@
**NOTE**
This is the legacy wiki page.
Everything here should be considered obsolete.
If you find anything here (that is not in *current* wiki),
please notify us via issues or help us moving it to current wiki.
* [fail2ban](olds-A-fail2ban-profile-for-Naxsi.md)
* [naxsilogs](olds-naxsilogs.md)
* [naxsivsobfuscated](olds-naxsivsobfuscated.md)
* [deniedurl](olds-deniedurl.md)
* [Knownbugs](olds-Knownbugs.md)
* [rulessyntax](olds-rulessyntax.md)
* [whitelists](olds-whitelists.md)
* [basicsetup](olds-basicsetup.md)
* [Security-Advisories](olds-Security-Advisories.md)
* [libinjection](olds-libinjection.md)
* [dynamicmodifiers](olds-dynamicmodifiers.md)
* [installation](olds-installation.md)
* [Philosophy](olds-Philosophy.md)
* [faq](olds-faq.md)
* [Home](olds-Home.md)
* [naxsivsappscan](olds-naxsivsappscan.md)
* [embedded_rules](olds-embedded_rules.md)
* [testing-and-stuff](olds-testing-and-stuff.md)
+30
View File
@@ -0,0 +1,30 @@
Welcome to naxsi wiki !
* [[Understand naxsi's philosophy & design|philosophy]] (READ FIRST)
### Tutorials
* [[Installing Naxsi|installation]]
* [[Basic setup|BasicSetup]]
* [[Naxsi on steroids (lua/ngx/* scripting)|dynamicmodifiers]]
* [[FAQ|FAQ]]
### Understanding Naxsi
* [[Internal and core rules|embedded_rules]]
* [[Understand Naxsi Whitelists|Whitelists]]
* [[Understanding naxsi's rules syntax|RulesSyntax]]
* [[Understanding Naxsi exceptions|NaxsiLogs]]
* [[DeniedUrl & post_action|DeniedUrl]]
* [[Libinjection integration|Libinjection]]
### Learning tools
* [nxapi]( https://github.com/nbs-system/naxsi/tree/master/nxapi )
### Extras
* [[Naxsi behaviour against obfuscated/complex payloads|naxsivsobfuscated]]
* [[Naxsi behaviour against web app scanner|naxsivsappscan]]
* [[A fail2ban profile for Naxsi|A-fail2ban-profile-for-Naxsi]]
* [[How to create an AppArmor profile for Naxsi|How-to-create-an-Apparmor-profile-for-Naxsi]]
* [[Unit tests, code coverage…|testing-and-stuff]]
### Issues
* [[Naxsi known bugs and limitations|Knownbugs]]

Some files were not shown because too many files have changed in this diff Show More