66# Nginx to load the module, and sets up the OWASP Core Rule Set for basic protection against
77# common web vulnerabilities.
88#
9- # Version: v1.0.0-beta.4
9+ # Version: v1.0.0
1010# License: MIT License
1111# Copyright (c) 2026 Hunter T. (StrangeRanger)
1212#
13- # TODO: Delete existing nginx source directory if it exists? Maybe a cleanup?
14- # TODO: Go through and verify 'sudo' is only used where necessary.
15- # TODO: Go through and ensure proper ownership and permissions of create, copied, and
16- # modified files.
17- #
1813# ###########################################################################################
1914set -Eeuo pipefail
2015# ###[ Global Variables ]####################################################################
@@ -53,10 +48,6 @@ readonly C_REQUIRED_PKGS=(
5348 zlib1g-dev
5449)
5550
56- C_NGINX_VERSION=" "
57- C_NGINX_CONFIG_ARGS=" "
58- C_MODULES_PATH=" "
59-
6051coreruleset_clone_exists=false
6152required_pkgs=(" ${C_REQUIRED_PKGS[@]} " )
6253missing_pkgs=()
@@ -79,9 +70,12 @@ on_error() {
7970# ###
8071# Check if a variable is empty. If it is empty, print an error message and return with
8172# code 1.
73+ #
74+ # PARAMETERS:
75+ # $1 - var_name (Required)
8276is_not_empty () {
8377 local var_name=" $1 "
84- local -n var_ref=" $1 "
78+ local -n var_ref=" $1 " # Use nameref to reference the variable by name.
8579
8680 if [[ -z " $var_ref " ]]; then
8781 echo " ${C_ERROR} Required value '${var_name} ' is empty" >&2
@@ -92,6 +86,12 @@ is_not_empty() {
9286# ###
9387# Add additional packages to the list of required packages if certain Nginx modules are
9488# enabled.
89+ #
90+ # MODIFIED GLOBALS:
91+ # - required_pkgs: Appends the package name when it is not already present.
92+ #
93+ # PARAMETERS:
94+ # $1 - required_pkg (Required)
9595require_pkg () {
9696 local required_pkg=" $1 "
9797
@@ -102,14 +102,51 @@ require_pkg() {
102102 required_pkgs+=(" $required_pkg " )
103103}
104104
105+ # ###
106+ # Confirm with the user before performing a 'git pull' in a repository that has local
107+ # changes.
108+ #
109+ # PARAMETERS:
110+ # $1 - repo_path (Optional, default: current directory)
111+ # $2 - use_sudo (Optional, default: false)
112+ confirm_git_pull () {
113+ local repo_path=" ${1:- .} "
114+ local use_sudo=" ${2:- false} "
115+ local sudo_cmd=()
116+
117+ if [[ $use_sudo == " true" ]]; then
118+ sudo_cmd=(sudo)
119+ fi
105120
106- # ###[ Trapping & Initial Checks ]###########################################################
121+ pushd " $repo_path " > /dev/null
107122
123+ if [[ -n $( " ${sudo_cmd[@]} " git status --porcelain) ]]; then
124+ echo " ${C_NOTE} Local changes detected in '$repo_path '"
125+ " ${sudo_cmd[@]} " git status --short
108126
109- trap on_error ERR
127+ printf " %sPull anyway? This may fail or require conflict resolution. " " $C_NOTE "
128+ read -rp " [y/N] " reply
110129
130+ case " $reply " in
131+ [Yy]* ) ;;
132+ * )
133+ echo " ${C_NOTE} Skipping pull for '$repo_path '"
134+ popd > /dev/null
135+ return 0
136+ ;;
137+ esac
138+ fi
111139
112- # ###[ Initial Checks ]######################################################################
140+ echo " ${C_INFO} Pulling latest changes in '$repo_path '..."
141+ " ${sudo_cmd[@]} " git pull
142+ popd > /dev/null
143+ }
144+
145+
146+ # ###[ Trapping & Initial Checks ]###########################################################
147+
148+
149+ trap on_error ERR
113150
114151
115152if command -v nginx & > /dev/null; then
159196if [[ ! -d " ModSecurity/.git" ]]; then
160197 echo " ${C_INFO} Cloning ModSecurity repository..."
161198 git clone --depth 1 -b v3/master --single-branch https://github.com/owasp-modsecurity/ModSecurity
162- pushd ModSecurity > /dev/null
163199else
164200 echo " ${C_NOTE} ModSecurity repository already exists"
165- pushd ModSecurity > /dev/null
166- echo " ${C_INFO} Updating existing ModSecurity repository..."
167- # TODO: Consider adding a check to ensure the local repository is on the correct branch
168- # and there are no local changes before pulling.
169- git pull
201+ confirm_git_pull " ModSecurity"
170202fi
171203
204+ pushd ModSecurity > /dev/null
172205echo " ${C_INFO} Initializing and updating git submodules..."
173206git submodule update --init --recursive
174207
@@ -195,17 +228,15 @@ if [[ ! -d "ModSecurity-nginx/.git" ]]; then
195228 git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-nginx
196229else
197230 echo " ${C_NOTE} ModSecurity-nginx repository already exists"
198- echo " ${C_INFO} Updating existing ModSecurity-nginx repository..."
199- pushd ModSecurity-nginx > /dev/null
200- git pull
201- popd > /dev/null
231+ confirm_git_pull " ModSecurity-nginx"
202232fi
203233
204234echo " ${C_INFO} Downloading Nginx source code for version '${C_NGINX_VERSION} '..."
205- [[ -f " nginx- ${C_NGINX_VERSION} .tar.gz " ]] && rm -f " nginx-${C_NGINX_VERSION} .tar.gz"
235+ rm -f " nginx-${C_NGINX_VERSION} .tar.gz"
206236wget " https://nginx.org/download/nginx-${C_NGINX_VERSION} .tar.gz"
207237
208238echo " ${C_INFO} Extracting Nginx source code..."
239+ rm -rf " nginx-${C_NGINX_VERSION} "
209240tar -xzf " nginx-${C_NGINX_VERSION} .tar.gz"
210241
211242pushd " nginx-${C_NGINX_VERSION} " > /dev/null
263294cd coreruleset
264295
265296if [[ $coreruleset_clone_exists == true ]]; then
266- echo " ${C_INFO} Updating existing OWASP Core Rule Set repository..."
267- # TODO: Consider adding a check to ensure the local repository is on the correct branch
268- # and there are no local changes before pulling.
269- sudo git pull
297+ confirm_git_pull " " " true"
270298fi
271299
272300echo " ${C_INFO} Configuring OWASP Core Rule Set..."
0 commit comments