Saturday, May 09, 2026 AM03:21:24 HKT
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "naxsi_src/libinjection"]
|
||||
path = naxsi_src/libinjection
|
||||
url = https://github.com/libinjection/libinjection
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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[:])
|
||||
@@ -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()
|
||||
@@ -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");
|
||||
@@ -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>.
|
||||
@@ -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>.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,86 @@
|
||||

|
||||
|
||||
## 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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
"
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
"
|
||||
@@ -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
|
||||
"
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
"
|
||||
@@ -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
|
||||
"
|
||||
@@ -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
|
||||
"
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
@@ -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."
|
||||
@@ -0,0 +1 @@
|
||||
load_module modules/ngx_http_naxsi_module.so;
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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).
|
||||
@@ -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).
|
||||
@@ -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";
|
||||
}
|
||||
```
|
||||
@@ -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).
|
||||
@@ -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).
|
||||
@@ -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"
|
||||
}
|
||||
```
|
||||
@@ -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).
|
||||
@@ -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 !
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 679 B |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
@@ -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.
|
||||
|
||||

|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
@@ -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 / {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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**)
|
||||
@@ -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!
|
||||
@@ -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 :)
|
||||
@@ -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.
|
||||
@@ -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";
|
||||
```
|
||||
|
||||
@@ -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)
|
||||
@@ -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]]
|
||||