Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ networking/
permissions/
policies/
users/
colors
colors

## Generated by hardening/Nginx WAF/nginx-waf.bash
ModSecurity/
ModSecurity-nginx/
nginx-*.tar.gz
nginx-*/
11 changes: 11 additions & 0 deletions hardening/Nginx WAF/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v1.0.0 - 2026-07-03

### Added

- Added confirmation before pulling updates in existing Git checkouts when local changes are present.
- Added ignore rules for generated ModSecurity, ModSecurity-nginx, and Nginx source build artifacts.

### Changed

- Clean up any existing downloaded Nginx tarball and extracted Nginx source directory before downloading and extracting a fresh copy.

## v1.0.0-beta.4 - 2026-05-24

### Changed
Expand Down
3 changes: 0 additions & 3 deletions hardening/Nginx WAF/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# Nginx WAF

> [!CAUTION]
> Script is currently in beta.

Installs and configures ModSecurity with the OWASP Core Rule Set for Nginx.

## Requirements
Expand Down
86 changes: 57 additions & 29 deletions hardening/Nginx WAF/nginx-waf.bash
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,10 @@
# Nginx to load the module, and sets up the OWASP Core Rule Set for basic protection against
# common web vulnerabilities.
#
# Version: v1.0.0-beta.4
# Version: v1.0.0
# License: MIT License
# Copyright (c) 2026 Hunter T. (StrangeRanger)
#
# TODO: Delete existing nginx source directory if it exists? Maybe a cleanup?
# TODO: Go through and verify 'sudo' is only used where necessary.
# TODO: Go through and ensure proper ownership and permissions of create, copied, and
# modified files.
#
############################################################################################
set -Eeuo pipefail
####[ Global Variables ]####################################################################
Expand Down Expand Up @@ -53,10 +48,6 @@ readonly C_REQUIRED_PKGS=(
zlib1g-dev
)

C_NGINX_VERSION=""
C_NGINX_CONFIG_ARGS=""
C_MODULES_PATH=""

coreruleset_clone_exists=false
required_pkgs=("${C_REQUIRED_PKGS[@]}")
missing_pkgs=()
Expand All @@ -79,9 +70,12 @@ on_error() {
####
# Check if a variable is empty. If it is empty, print an error message and return with
# code 1.
#
# PARAMETERS:
# $1 - var_name (Required)
is_not_empty() {
local var_name="$1"
local -n var_ref="$1"
local -n var_ref="$1" # Use nameref to reference the variable by name.

if [[ -z "$var_ref" ]]; then
echo "${C_ERROR}Required value '${var_name}' is empty" >&2
Expand All @@ -92,6 +86,12 @@ is_not_empty() {
####
# Add additional packages to the list of required packages if certain Nginx modules are
# enabled.
#
# MODIFIED GLOBALS:
# - required_pkgs: Appends the package name when it is not already present.
#
# PARAMETERS:
# $1 - required_pkg (Required)
require_pkg() {
local required_pkg="$1"

Expand All @@ -102,14 +102,51 @@ require_pkg() {
required_pkgs+=("$required_pkg")
}

####
# Confirm with the user before performing a 'git pull' in a repository that has local
# changes.
#
# PARAMETERS:
# $1 - repo_path (Optional, default: current directory)
# $2 - use_sudo (Optional, default: false)
confirm_git_pull() {
local repo_path="${1:-.}"
local use_sudo="${2:-false}"
local sudo_cmd=()

if [[ $use_sudo == "true" ]]; then
sudo_cmd=(sudo)
fi

####[ Trapping & Initial Checks ]###########################################################
pushd "$repo_path" >/dev/null

if [[ -n $("${sudo_cmd[@]}" git status --porcelain) ]]; then
echo "${C_NOTE}Local changes detected in '$repo_path'"
"${sudo_cmd[@]}" git status --short

trap on_error ERR
printf "%sPull anyway? This may fail or require conflict resolution. " "$C_NOTE"
read -rp "[y/N] " reply

Comment on lines +127 to 129
case "$reply" in
[Yy]*) ;;
*)
echo "${C_NOTE}Skipping pull for '$repo_path'"
popd >/dev/null
return 0
;;
esac
fi

####[ Initial Checks ]######################################################################
echo "${C_INFO}Pulling latest changes in '$repo_path'..."
"${sudo_cmd[@]}" git pull
popd >/dev/null
}


####[ Trapping & Initial Checks ]###########################################################


trap on_error ERR


if command -v nginx &>/dev/null; then
Expand Down Expand Up @@ -159,16 +196,12 @@ fi
if [[ ! -d "ModSecurity/.git" ]]; then
echo "${C_INFO}Cloning ModSecurity repository..."
git clone --depth 1 -b v3/master --single-branch https://github.com/owasp-modsecurity/ModSecurity
pushd ModSecurity >/dev/null
else
echo "${C_NOTE}ModSecurity repository already exists"
pushd ModSecurity >/dev/null
echo "${C_INFO}Updating existing ModSecurity repository..."
# TODO: Consider adding a check to ensure the local repository is on the correct branch
# and there are no local changes before pulling.
git pull
confirm_git_pull "ModSecurity"
fi

pushd ModSecurity >/dev/null
echo "${C_INFO}Initializing and updating git submodules..."
git submodule update --init --recursive

Expand All @@ -195,17 +228,15 @@ if [[ ! -d "ModSecurity-nginx/.git" ]]; then
git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-nginx
else
echo "${C_NOTE}ModSecurity-nginx repository already exists"
echo "${C_INFO}Updating existing ModSecurity-nginx repository..."
pushd ModSecurity-nginx >/dev/null
git pull
popd >/dev/null
confirm_git_pull "ModSecurity-nginx"
fi

echo "${C_INFO}Downloading Nginx source code for version '${C_NGINX_VERSION}'..."
[[ -f "nginx-${C_NGINX_VERSION}.tar.gz" ]] && rm -f "nginx-${C_NGINX_VERSION}.tar.gz"
rm -f "nginx-${C_NGINX_VERSION}.tar.gz"
wget "https://nginx.org/download/nginx-${C_NGINX_VERSION}.tar.gz"

echo "${C_INFO}Extracting Nginx source code..."
rm -rf "nginx-${C_NGINX_VERSION}"
tar -xzf "nginx-${C_NGINX_VERSION}.tar.gz"

pushd "nginx-${C_NGINX_VERSION}" >/dev/null
Expand Down Expand Up @@ -263,10 +294,7 @@ fi
cd coreruleset

if [[ $coreruleset_clone_exists == true ]]; then
echo "${C_INFO}Updating existing OWASP Core Rule Set repository..."
# TODO: Consider adding a check to ensure the local repository is on the correct branch
# and there are no local changes before pulling.
sudo git pull
confirm_git_pull "" "true"
fi

echo "${C_INFO}Configuring OWASP Core Rule Set..."
Expand Down