Introduction

ModSecurity, GeoIP, and Fail2Ban are powerful, complimentary tools used by system administrators to protect web servers from malicious traffic, brute-force attacks, and unauthorized access.

ModSecurity (often called "Modsec") is an open-source Web Application Firewall (WAF) that operates directly at the web server level (like Apache, Nginx, or IIS). It inspects incoming HTTP/HTTPS traffic and watches exactly what visitors are sending to your website. It blocks advanced web application attacks like SQL injection (SQLi), Cross-Site Scripting (XSS), and session hijacking before they reach your website's code. It typically relies on the OWASP Core Rule Set (CRS) for detection.

The ModSecurity-nginx connector is the connection point between nginx and libmodsecurity (ModSecurity v3). This connector is required to use LibModSecurity with nginx. The ModSecurity-nginx connector takes the form of an nginx module.

GeoIP (Geolocation IP) is a database and technology that maps an IP address to a physical geographic location (country, region, or city). When a user visits your website, the server looks up their IP in a database (e.g., MaxMind) to determine where they are physically connecting from. t is used for geoblocking or geographic filtering. For instance, you can configure your server to drop traffic or show a 403 Forbidden error if a request originates from a specific foreign country or if you only want traffic from local users.

Fail2Ban is a server intrusion prevention framework that actively monitors your server's log files (like SSH, FTP, or web server logs) for suspicious activity. It looks for patterns, such as multiple failed login attempts or repeated 404 errors indicating a bot is scanning the site.Once a predefined threshold is met, it automatically updates the server's firewall (like iptables, nftables or UFW) to ban the malicious IP address for a specified amount of time. Although installation of Fail2ban is not required for this article, I strongly recommend that you implement.
These tools form a strong, layered defense.

Brotli is an open-source, lossless data compression algorithm developed by Google. Primarily used on web servers and content delivery networks (CDNs), it reduces the size of website files—like HTML, CSS, and JavaScript—so they transfer faster from the server to your browser. It delivers superior compression with file sizes roughly 15% to 25% smaller than older methods like Gzip. It contains a pre-built static dictionary of common web terms and phrases, allowing it to efficiently encode standard web text and it is natively supported by over 95% of modern web browsers.

Ubuntu natively supports Brotli upgrades via apt, but only if you use the stock Nginx packages provided in Ubuntu's official repositories.The moment you switch Nginx installation sources (such as using the official nginx.org stable/mainline repository), Ubuntu's native Brotli packages will break and refuse to update

In this post, we will be compiling the ModSecurity NGINX connector, Brotli and GeoIP2 as dynamic modules. Any time you upgrade nginx, you will have to recompile the modules, so I have written a shell script you can download to automate the process when updating. The ModSecurity Web Application Firewall is required, but this process will install GeoIP2 and Brotli even if you do not have them installed.
I have tested the shell script vigorously, but as all systems are different, you may need to make modification(s). The script is designed to stop at any error and can re-run as many times as necessary after you make your modifications (if any).

Prerequisites:

Ubuntu 26.04 installed on a VPS or Bare-Metal host
Nginx 1.14.0 or later
User with sudo privileges
ModSecurity v3 installed and running

Let’s go

Proceed as root for convenience otherwise most commands would have to be preceeded with ’sudo’.
sudo -i

Back up Your Current Configuration

cp -r /etc/nginx /etc/nginx_backup

Install Dependencies & Download NGINX Source.

Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIP
apt-get update
apt-get install build-essential libpcre2 libpcre2-dev zlib1g-dev libssl-dev libbrotli-dev libmaxminddb0 libmaxminddb-dev mmdb-bin git g++ flex bison curl doxygen libyajl-dev libgeoip-dev libtool dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev libxml2-dev make -y

Create a workspace
cd /opt/
mkdir -p /opt/nginx-upgrade
cd /opt/nginx-upgrade
Get your nginx version
nginx -t
Output will be something like this:
nginx version: nginx/[nginx version number]
Note the version number for future reference

Download the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gz

Create Nginx modules directory
mkdir -p /etc/nginx/modules

Clone and Compile the ModSecurity-nginx Module

cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

Navigate to your cloned ModSecurity-nginx folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
Note: Using --with-compat ensures binary compatibility with official Nginx packages.

Compile only the ModSecurity-nginx module:
make modules

Copy the freshly compiled .so file into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Clone and Compile the Brotli Module

cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git

Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
/configure --with-compat --add-dynamic-module=../ngx_brotli

Compile only the Brotli modules:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/

Clone and Compile the Clone GeoIP2 Module

cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git

Navigate to your cloned ngx_http_geoip2_module folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module

Compile only the GeoIP2 module:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules

Test and reload Nginx

nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx

Shell script to compile Brotli, and GeoIP2 after Nginx Upgrade

This script will automate everything covered above, as well as reading the correct Nginx version and keeping a log of the process. It is designed to stop on errors and can be re-run as many times as necessary.

#!/bin/bash
# Build against a specific nginx.org NGINX version (nginx -v).
# Intended to run inside an Ubuntu container
# matching the target distribution.
# Compiling GeoIP2 as a dynamic module (.so file)
# Compiling Brotli as a dynamic module (.so file)
# Compiling ModSecurity-nginx as a dynamic module (.so file)
# Must be run in root home as root (sudo -i)

if ! id | grep -q "uid=0(root)"; then
        echo "Must be run as root" 
	exit 1
fi
# Set log file
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
logname=`basename "$0"`
logname+=".log"
logfile=$scriptdir/$logname
touch "$logfile"

# Functions
logger(){
    echo "$(date): $@" >> $logfile
    echo "## $@"
}
logger "Starting script"

# Setup
## NeedRestart config change (automatically restart required services instead of prompting/blocking script. Revert at end).
sed -i 's/#$nrconf{restart} = '\''i'\'';/$nrconf{restart} = '\''a'\'';/' /etc/needrestart/needrestart.conf
#
# Best practice settings for running bash scripts:
# Exit the script when an error is encountered
set -o errexit
# Exit the script when a pipe operation fails
set -o pipefail
# Exit the script when there are undeclared variables
set -o nounset
# Uncomment this to see a log to the screen of each command run in the script
# set -o xtrace
# Credit: nginx.org 2020-10-05 https://gist.github.com/nginx-gists/bdc7da70b124c4f3e472970c7826cccc 

# Back up Your Current Configuration
cp -r /etc/nginx /etc/nginx__backup

# Pre-reqs
apt-get -qq update
apt-get -qq install -y \
libpcre2-dev \
libssl-dev \
zlib1g-dev \
libbrotli-dev \
g++ \
flex \
bison \
curl \
doxygen \
libyajl-dev \
libgeoip-dev \
libtool \
dh-autoreconf \
libcurl4-gnutls-dev \
libxml2-dev \
make \
libmaxminddb0 \
libmaxminddb-dev \
mmdb-bin

# Install the modules
# Get installed Nginx version number
NGINX_VER=$(nginx -v |& sed 's/nginx version: nginx\///' | sed 's/\s.*$//')
logger "Nginx version: $NGINX_VER"

# Create a workspace and download the exact matching Nginx ${NGINX_VER} source code:
cd /opt/

if [ ! -d /opt/nginx-upgrade ]; then
  mkdir -p /opt/nginx-upgrade
fi

cd /opt/nginx-upgrade

if [ ! -f /opt/nginx-upgrade/nginx-${NGINX_VER}/configure ]; then
  curl -O https://nginx.org/download/nginx-${NGINX_VER}.tar.gz
  tar -zxf nginx-${NGINX_VER}.tar.gz
  logger "nginx-${NGINX_VER} source downloaded"
fi

# Clone Module Repositories
# Download the source code for the Brotli GeoIP2 ModSecurity-nginx modules into your workspace.

# delete previous clone directories
if [ -d /opt/nginx-upgrade/ngx_brotli ]; then
  rm -r /opt/nginx-upgrade/ngx_brotli
fi

if [ -d /opt/nginx-upgrade/ngx_http_geoip2_module ]; then
  rm -r /opt/nginx-upgrade/ngx_http_geoip2_module
fi

if [ -d /opt/nginx-upgrade/ModSecurity-nginx ]; then
  rm -r /opt/nginx-upgrade/ModSecurity-nginx
fi

# Clone Brotli module
cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "Brotli dynamic module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Remove previous configs
if [ -d /opt/nginx-upgrade/nginx-${NGINX_VER}/objs ]; then
  make clean
fi
logger "make clean invoked"

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_brotli
logger "Brotli dynamic module completed"

# Compile only the modules:
make modules
logger "Brotli dynamic modules compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
if [ ! -d /etc/nginx/modules/ ]; then
  mkdir -p /etc/nginx/modules
fi
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
logger "Brotli dynamic modules copied to /etc/nginx/modules/"

# Clone GeoIP2 module
cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "GeoIP2 module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
logger "GeoIP2 dynamic module completed"

# Compile only the modules:
make modules
logger "GeoIP2 module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/
logger "GeoIP2 dynamic module copied to /etc/nginx/modules/"

# Clone ModSecurity-nginx module
cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "ModSecurity-nginx cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
logger "ModSecurity dynamic module configured"

# Note: Using --with-compat ensures binary compatibility with official Nginx packages.

# Compile only the modules:
make modules
logger "ModSecurity dynamic module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
logger "ModSecurity dynamic module copied to /etc/nginx/modules/"

# Verify
# nginx -t
if [ "$(command nginx -t) | grep 'ok'" ]; then
        logger "Nginx configuration ok, reloading.."
	if [ "systemctl status nginx | grep 'Started nginx.service'" ]; then 
		systemctl reload nginx
	else
		systemctl start nginx
	fi
else
        logger "Nginx errors"
fi

ls -la /opt/nginx-upgrade/nginx-${NGINX_VER}/objs

logger "Operation complete"

Download

re-build-modules-after-nginx-upgrade.tgz    raw

Introduction

ModSecurity, GeoIP, and Fail2Ban are powerful, complimentary tools used by system administrators to protect web servers from malicious traffic, brute-force attacks, and unauthorized access.

ModSecurity (often called "Modsec") is an open-source Web Application Firewall (WAF) that operates directly at the web server level (like Apache, Nginx, or IIS). It inspects incoming HTTP/HTTPS traffic and watches exactly what visitors are sending to your website. It blocks advanced web application attacks like SQL injection (SQLi), Cross-Site Scripting (XSS), and session hijacking before they reach your website's code. It typically relies on the OWASP Core Rule Set (CRS) for detection.

The ModSecurity-nginx connector is the connection point between nginx and libmodsecurity (ModSecurity v3). This connector is required to use LibModSecurity with nginx. The ModSecurity-nginx connector takes the form of an nginx module.

GeoIP (Geolocation IP) is a database and technology that maps an IP address to a physical geographic location (country, region, or city). When a user visits your website, the server looks up their IP in a database (e.g., MaxMind) to determine where they are physically connecting from. t is used for geoblocking or geographic filtering. For instance, you can configure your server to drop traffic or show a 403 Forbidden error if a request originates from a specific foreign country or if you only want traffic from local users.

Fail2Ban is a server intrusion prevention framework that actively monitors your server's log files (like SSH, FTP, or web server logs) for suspicious activity. It looks for patterns, such as multiple failed login attempts or repeated 404 errors indicating a bot is scanning the site.Once a predefined threshold is met, it automatically updates the server's firewall (like iptables, nftables or UFW) to ban the malicious IP address for a specified amount of time. Although installation of Fail2ban is not required for this article, I strongly recommend that you implement.
These tools form a strong, layered defense.

Brotli is an open-source, lossless data compression algorithm developed by Google. Primarily used on web servers and content delivery networks (CDNs), it reduces the size of website files—like HTML, CSS, and JavaScript—so they transfer faster from the server to your browser. It delivers superior compression with file sizes roughly 15% to 25% smaller than older methods like Gzip. It contains a pre-built static dictionary of common web terms and phrases, allowing it to efficiently encode standard web text and it is natively supported by over 95% of modern web browsers.

Ubuntu natively supports Brotli upgrades via apt, but only if you use the stock Nginx packages provided in Ubuntu's official repositories.The moment you switch Nginx installation sources (such as using the official nginx.org stable/mainline repository), Ubuntu's native Brotli packages will break and refuse to update

In this post, we will be compiling the ModSecurity NGINX connector, Brotli and GeoIP2 as dynamic modules. Any time you upgrade nginx, you will have to recompile the modules, so I have written a shell script you can download to automate the process when updating. The ModSecurity Web Application Firewall is required, but this process will install GeoIP2 and Brotli even if you do not have them installed.
I have tested the shell script vigorously, but as all systems are different, you may need to make modification(s). The script is designed to stop at any error and can re-run as many times as necessary after you make your modifications (if any).

Prerequisites:

Ubuntu 26.04 installed on a VPS or Bare-Metal host
Nginx 1.14.0 or later
User with sudo privileges
ModSecurity v3 installed and running

Let’s go

Proceed as root for convenience otherwise most commands would have to be preceeded with ’sudo’.
sudo -i

Back up Your Current Configuration

cp -r /etc/nginx /etc/nginx_backup

Install Dependencies & Download NGINX Source.

Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIP
apt-get update
apt-get install build-essential libpcre2 libpcre2-dev zlib1g-dev libssl-dev libbrotli-dev libmaxminddb0 libmaxminddb-dev mmdb-bin git g++ flex bison curl doxygen libyajl-dev libgeoip-dev libtool dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev libxml2-dev make -y

Create a workspace
cd /opt/
mkdir -p /opt/nginx-upgrade
cd /opt/nginx-upgrade
Get your nginx version
nginx -t
Output will be something like this:
nginx version: nginx/[nginx version number]
Note the version number for future reference

Download the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gz

Create Nginx modules directory
mkdir -p /etc/nginx/modules

Clone and Compile the ModSecurity-nginx Module

cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

Navigate to your cloned ModSecurity-nginx folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
Note: Using --with-compat ensures binary compatibility with official Nginx packages.

Compile only the ModSecurity-nginx module:
make modules

Copy the freshly compiled .so file into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Clone and Compile the Brotli Module

cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git

Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
/configure --with-compat --add-dynamic-module=../ngx_brotli

Compile only the Brotli modules:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/

Clone and Compile the Clone GeoIP2 Module

cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git

Navigate to your cloned ngx_http_geoip2_module folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module

Compile only the GeoIP2 module:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules

Test and reload Nginx

nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx

Shell script to compile Brotli, and GeoIP2 after Nginx Upgrade

This script will automate everything covered above, as well as reading the correct Nginx version and keeping a log of the process. It is designed to stop on errors and can be re-run as many times as necessary.

#!/bin/bash
# Build against a specific nginx.org NGINX version (nginx -v).
# Intended to run inside an Ubuntu container
# matching the target distribution.
# Compiling GeoIP2 as a dynamic module (.so file)
# Compiling Brotli as a dynamic module (.so file)
# Compiling ModSecurity-nginx as a dynamic module (.so file)
# Must be run in root home as root (sudo -i)

if ! id | grep -q "uid=0(root)"; then
        echo "Must be run as root" 
	exit 1
fi
# Set log file
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
logname=`basename "$0"`
logname+=".log"
logfile=$scriptdir/$logname
touch "$logfile"

# Functions
logger(){
    echo "$(date): $@" >> $logfile
    echo "## $@"
}
logger "Starting script"

# Setup
## NeedRestart config change (automatically restart required services instead of prompting/blocking script. Revert at end).
sed -i 's/#$nrconf{restart} = '\''i'\'';/$nrconf{restart} = '\''a'\'';/' /etc/needrestart/needrestart.conf
#
# Best practice settings for running bash scripts:
# Exit the script when an error is encountered
set -o errexit
# Exit the script when a pipe operation fails
set -o pipefail
# Exit the script when there are undeclared variables
set -o nounset
# Uncomment this to see a log to the screen of each command run in the script
# set -o xtrace
# Credit: nginx.org 2020-10-05 https://gist.github.com/nginx-gists/bdc7da70b124c4f3e472970c7826cccc 

# Back up Your Current Configuration
cp -r /etc/nginx /etc/nginx__backup

# Pre-reqs
apt-get -qq update
apt-get -qq install -y \
libpcre2-dev \
libssl-dev \
zlib1g-dev \
libbrotli-dev \
g++ \
flex \
bison \
curl \
doxygen \
libyajl-dev \
libgeoip-dev \
libtool \
dh-autoreconf \
libcurl4-gnutls-dev \
libxml2-dev \
make \
libmaxminddb0 \
libmaxminddb-dev \
mmdb-bin

# Install the modules
# Get installed Nginx version number
NGINX_VER=$(nginx -v |& sed 's/nginx version: nginx\///' | sed 's/\s.*$//')
logger "Nginx version: $NGINX_VER"

# Create a workspace and download the exact matching Nginx ${NGINX_VER} source code:
cd /opt/

if [ ! -d /opt/nginx-upgrade ]; then
  mkdir -p /opt/nginx-upgrade
fi

cd /opt/nginx-upgrade

if [ ! -f /opt/nginx-upgrade/nginx-${NGINX_VER}/configure ]; then
  curl -O https://nginx.org/download/nginx-${NGINX_VER}.tar.gz
  tar -zxf nginx-${NGINX_VER}.tar.gz
  logger "nginx-${NGINX_VER} source downloaded"
fi

# Clone Module Repositories
# Download the source code for the Brotli GeoIP2 ModSecurity-nginx modules into your workspace.

# delete previous clone directories
if [ -d /opt/nginx-upgrade/ngx_brotli ]; then
  rm -r /opt/nginx-upgrade/ngx_brotli
fi

if [ -d /opt/nginx-upgrade/ngx_http_geoip2_module ]; then
  rm -r /opt/nginx-upgrade/ngx_http_geoip2_module
fi

if [ -d /opt/nginx-upgrade/ModSecurity-nginx ]; then
  rm -r /opt/nginx-upgrade/ModSecurity-nginx
fi

# Clone Brotli module
cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "Brotli dynamic module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Remove previous configs
if [ -d /opt/nginx-upgrade/nginx-${NGINX_VER}/objs ]; then
  make clean
fi
logger "make clean invoked"

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_brotli
logger "Brotli dynamic module completed"

# Compile only the modules:
make modules
logger "Brotli dynamic modules compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
if [ ! -d /etc/nginx/modules/ ]; then
  mkdir -p /etc/nginx/modules
fi
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
logger "Brotli dynamic modules copied to /etc/nginx/modules/"

# Clone GeoIP2 module
cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "GeoIP2 module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
logger "GeoIP2 dynamic module completed"

# Compile only the modules:
make modules
logger "GeoIP2 module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/
logger "GeoIP2 dynamic module copied to /etc/nginx/modules/"

# Clone ModSecurity-nginx module
cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "ModSecurity-nginx cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
logger "ModSecurity dynamic module configured"

# Note: Using --with-compat ensures binary compatibility with official Nginx packages.

# Compile only the modules:
make modules
logger "ModSecurity dynamic module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
logger "ModSecurity dynamic module copied to /etc/nginx/modules/"

# Verify
# nginx -t
if [ "$(command nginx -t) | grep 'ok'" ]; then
        logger "Nginx configuration ok, reloading.."
	if [ "systemctl status nginx | grep 'Started nginx.service'" ]; then 
		systemctl reload nginx
	else
		systemctl start nginx
	fi
else
        logger "Nginx errors"
fi

ls -la /opt/nginx-upgrade/nginx-${NGINX_VER}/objs

logger "Operation complete"

Download

re-build-modules-after-nginx-upgrade.tgz    raw
Leave A Comment

Total Views: 907Daily Views: 22

Introduction

ModSecurity, GeoIP, and Fail2Ban are powerful, complimentary tools used by system administrators to protect web servers from malicious traffic, brute-force attacks, and unauthorized access.

ModSecurity (often called "Modsec") is an open-source Web Application Firewall (WAF) that operates directly at the web server level (like Apache, Nginx, or IIS). It inspects incoming HTTP/HTTPS traffic and watches exactly what visitors are sending to your website. It blocks advanced web application attacks like SQL injection (SQLi), Cross-Site Scripting (XSS), and session hijacking before they reach your website's code. It typically relies on the OWASP Core Rule Set (CRS) for detection.

The ModSecurity-nginx connector is the connection point between nginx and libmodsecurity (ModSecurity v3). This connector is required to use LibModSecurity with nginx. The ModSecurity-nginx connector takes the form of an nginx module.

GeoIP (Geolocation IP) is a database and technology that maps an IP address to a physical geographic location (country, region, or city). When a user visits your website, the server looks up their IP in a database (e.g., MaxMind) to determine where they are physically connecting from. t is used for geoblocking or geographic filtering. For instance, you can configure your server to drop traffic or show a 403 Forbidden error if a request originates from a specific foreign country or if you only want traffic from local users.

Fail2Ban is a server intrusion prevention framework that actively monitors your server's log files (like SSH, FTP, or web server logs) for suspicious activity. It looks for patterns, such as multiple failed login attempts or repeated 404 errors indicating a bot is scanning the site.Once a predefined threshold is met, it automatically updates the server's firewall (like iptables, nftables or UFW) to ban the malicious IP address for a specified amount of time. Although installation of Fail2ban is not required for this article, I strongly recommend that you implement.
These tools form a strong, layered defense.

Brotli is an open-source, lossless data compression algorithm developed by Google. Primarily used on web servers and content delivery networks (CDNs), it reduces the size of website files—like HTML, CSS, and JavaScript—so they transfer faster from the server to your browser. It delivers superior compression with file sizes roughly 15% to 25% smaller than older methods like Gzip. It contains a pre-built static dictionary of common web terms and phrases, allowing it to efficiently encode standard web text and it is natively supported by over 95% of modern web browsers.

Ubuntu natively supports Brotli upgrades via apt, but only if you use the stock Nginx packages provided in Ubuntu's official repositories.The moment you switch Nginx installation sources (such as using the official nginx.org stable/mainline repository), Ubuntu's native Brotli packages will break and refuse to update

In this post, we will be compiling the ModSecurity NGINX connector, Brotli and GeoIP2 as dynamic modules. Any time you upgrade nginx, you will have to recompile the modules, so I have written a shell script you can download to automate the process when updating. The ModSecurity Web Application Firewall is required, but this process will install GeoIP2 and Brotli even if you do not have them installed.
I have tested the shell script vigorously, but as all systems are different, you may need to make modification(s). The script is designed to stop at any error and can re-run as many times as necessary after you make your modifications (if any).

Prerequisites:

Ubuntu 26.04 installed on a VPS or Bare-Metal host
Nginx 1.14.0 or later
User with sudo privileges
ModSecurity v3 installed and running

Let’s go

Proceed as root for convenience otherwise most commands would have to be preceeded with ’sudo’.
sudo -i

Back up Your Current Configuration

cp -r /etc/nginx /etc/nginx_backup

Install Dependencies & Download NGINX Source.

Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIP
apt-get update
apt-get install build-essential libpcre2 libpcre2-dev zlib1g-dev libssl-dev libbrotli-dev libmaxminddb0 libmaxminddb-dev mmdb-bin git g++ flex bison curl doxygen libyajl-dev libgeoip-dev libtool dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev libxml2-dev make -y

Create a workspace
cd /opt/
mkdir -p /opt/nginx-upgrade
cd /opt/nginx-upgrade
Get your nginx version
nginx -t
Output will be something like this:
nginx version: nginx/[nginx version number]
Note the version number for future reference

Download the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gz

Create Nginx modules directory
mkdir -p /etc/nginx/modules

Clone and Compile the ModSecurity-nginx Module

cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

Navigate to your cloned ModSecurity-nginx folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
Note: Using --with-compat ensures binary compatibility with official Nginx packages.

Compile only the ModSecurity-nginx module:
make modules

Copy the freshly compiled .so file into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Clone and Compile the Brotli Module

cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git

Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
/configure --with-compat --add-dynamic-module=../ngx_brotli

Compile only the Brotli modules:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/

Clone and Compile the Clone GeoIP2 Module

cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git

Navigate to your cloned ngx_http_geoip2_module folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module

Compile only the GeoIP2 module:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules

Test and reload Nginx

nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx

Shell script to compile Brotli, and GeoIP2 after Nginx Upgrade

This script will automate everything covered above, as well as reading the correct Nginx version and keeping a log of the process. It is designed to stop on errors and can be re-run as many times as necessary.

#!/bin/bash
# Build against a specific nginx.org NGINX version (nginx -v).
# Intended to run inside an Ubuntu container
# matching the target distribution.
# Compiling GeoIP2 as a dynamic module (.so file)
# Compiling Brotli as a dynamic module (.so file)
# Compiling ModSecurity-nginx as a dynamic module (.so file)
# Must be run in root home as root (sudo -i)

if ! id | grep -q "uid=0(root)"; then
        echo "Must be run as root" 
	exit 1
fi
# Set log file
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
logname=`basename "$0"`
logname+=".log"
logfile=$scriptdir/$logname
touch "$logfile"

# Functions
logger(){
    echo "$(date): $@" >> $logfile
    echo "## $@"
}
logger "Starting script"

# Setup
## NeedRestart config change (automatically restart required services instead of prompting/blocking script. Revert at end).
sed -i 's/#$nrconf{restart} = '\''i'\'';/$nrconf{restart} = '\''a'\'';/' /etc/needrestart/needrestart.conf
#
# Best practice settings for running bash scripts:
# Exit the script when an error is encountered
set -o errexit
# Exit the script when a pipe operation fails
set -o pipefail
# Exit the script when there are undeclared variables
set -o nounset
# Uncomment this to see a log to the screen of each command run in the script
# set -o xtrace
# Credit: nginx.org 2020-10-05 https://gist.github.com/nginx-gists/bdc7da70b124c4f3e472970c7826cccc 

# Back up Your Current Configuration
cp -r /etc/nginx /etc/nginx__backup

# Pre-reqs
apt-get -qq update
apt-get -qq install -y \
libpcre2-dev \
libssl-dev \
zlib1g-dev \
libbrotli-dev \
g++ \
flex \
bison \
curl \
doxygen \
libyajl-dev \
libgeoip-dev \
libtool \
dh-autoreconf \
libcurl4-gnutls-dev \
libxml2-dev \
make \
libmaxminddb0 \
libmaxminddb-dev \
mmdb-bin

# Install the modules
# Get installed Nginx version number
NGINX_VER=$(nginx -v |& sed 's/nginx version: nginx\///' | sed 's/\s.*$//')
logger "Nginx version: $NGINX_VER"

# Create a workspace and download the exact matching Nginx ${NGINX_VER} source code:
cd /opt/

if [ ! -d /opt/nginx-upgrade ]; then
  mkdir -p /opt/nginx-upgrade
fi

cd /opt/nginx-upgrade

if [ ! -f /opt/nginx-upgrade/nginx-${NGINX_VER}/configure ]; then
  curl -O https://nginx.org/download/nginx-${NGINX_VER}.tar.gz
  tar -zxf nginx-${NGINX_VER}.tar.gz
  logger "nginx-${NGINX_VER} source downloaded"
fi

# Clone Module Repositories
# Download the source code for the Brotli GeoIP2 ModSecurity-nginx modules into your workspace.

# delete previous clone directories
if [ -d /opt/nginx-upgrade/ngx_brotli ]; then
  rm -r /opt/nginx-upgrade/ngx_brotli
fi

if [ -d /opt/nginx-upgrade/ngx_http_geoip2_module ]; then
  rm -r /opt/nginx-upgrade/ngx_http_geoip2_module
fi

if [ -d /opt/nginx-upgrade/ModSecurity-nginx ]; then
  rm -r /opt/nginx-upgrade/ModSecurity-nginx
fi

# Clone Brotli module
cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "Brotli dynamic module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Remove previous configs
if [ -d /opt/nginx-upgrade/nginx-${NGINX_VER}/objs ]; then
  make clean
fi
logger "make clean invoked"

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_brotli
logger "Brotli dynamic module completed"

# Compile only the modules:
make modules
logger "Brotli dynamic modules compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
if [ ! -d /etc/nginx/modules/ ]; then
  mkdir -p /etc/nginx/modules
fi
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
logger "Brotli dynamic modules copied to /etc/nginx/modules/"

# Clone GeoIP2 module
cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "GeoIP2 module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
logger "GeoIP2 dynamic module completed"

# Compile only the modules:
make modules
logger "GeoIP2 module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/
logger "GeoIP2 dynamic module copied to /etc/nginx/modules/"

# Clone ModSecurity-nginx module
cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "ModSecurity-nginx cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
logger "ModSecurity dynamic module configured"

# Note: Using --with-compat ensures binary compatibility with official Nginx packages.

# Compile only the modules:
make modules
logger "ModSecurity dynamic module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
logger "ModSecurity dynamic module copied to /etc/nginx/modules/"

# Verify
# nginx -t
if [ "$(command nginx -t) | grep 'ok'" ]; then
        logger "Nginx configuration ok, reloading.."
	if [ "systemctl status nginx | grep 'Started nginx.service'" ]; then 
		systemctl reload nginx
	else
		systemctl start nginx
	fi
else
        logger "Nginx errors"
fi

ls -la /opt/nginx-upgrade/nginx-${NGINX_VER}/objs

logger "Operation complete"

Download

re-build-modules-after-nginx-upgrade.tgz    raw

Introduction

ModSecurity, GeoIP, and Fail2Ban are powerful, complimentary tools used by system administrators to protect web servers from malicious traffic, brute-force attacks, and unauthorized access.

ModSecurity (often called "Modsec") is an open-source Web Application Firewall (WAF) that operates directly at the web server level (like Apache, Nginx, or IIS). It inspects incoming HTTP/HTTPS traffic and watches exactly what visitors are sending to your website. It blocks advanced web application attacks like SQL injection (SQLi), Cross-Site Scripting (XSS), and session hijacking before they reach your website's code. It typically relies on the OWASP Core Rule Set (CRS) for detection.

The ModSecurity-nginx connector is the connection point between nginx and libmodsecurity (ModSecurity v3). This connector is required to use LibModSecurity with nginx. The ModSecurity-nginx connector takes the form of an nginx module.

GeoIP (Geolocation IP) is a database and technology that maps an IP address to a physical geographic location (country, region, or city). When a user visits your website, the server looks up their IP in a database (e.g., MaxMind) to determine where they are physically connecting from. t is used for geoblocking or geographic filtering. For instance, you can configure your server to drop traffic or show a 403 Forbidden error if a request originates from a specific foreign country or if you only want traffic from local users.

Fail2Ban is a server intrusion prevention framework that actively monitors your server's log files (like SSH, FTP, or web server logs) for suspicious activity. It looks for patterns, such as multiple failed login attempts or repeated 404 errors indicating a bot is scanning the site.Once a predefined threshold is met, it automatically updates the server's firewall (like iptables, nftables or UFW) to ban the malicious IP address for a specified amount of time. Although installation of Fail2ban is not required for this article, I strongly recommend that you implement.
These tools form a strong, layered defense.

Brotli is an open-source, lossless data compression algorithm developed by Google. Primarily used on web servers and content delivery networks (CDNs), it reduces the size of website files—like HTML, CSS, and JavaScript—so they transfer faster from the server to your browser. It delivers superior compression with file sizes roughly 15% to 25% smaller than older methods like Gzip. It contains a pre-built static dictionary of common web terms and phrases, allowing it to efficiently encode standard web text and it is natively supported by over 95% of modern web browsers.

Ubuntu natively supports Brotli upgrades via apt, but only if you use the stock Nginx packages provided in Ubuntu's official repositories.The moment you switch Nginx installation sources (such as using the official nginx.org stable/mainline repository), Ubuntu's native Brotli packages will break and refuse to update

In this post, we will be compiling the ModSecurity NGINX connector, Brotli and GeoIP2 as dynamic modules. Any time you upgrade nginx, you will have to recompile the modules, so I have written a shell script you can download to automate the process when updating. The ModSecurity Web Application Firewall is required, but this process will install GeoIP2 and Brotli even if you do not have them installed.
I have tested the shell script vigorously, but as all systems are different, you may need to make modification(s). The script is designed to stop at any error and can re-run as many times as necessary after you make your modifications (if any).

Prerequisites:

Ubuntu 26.04 installed on a VPS or Bare-Metal host
Nginx 1.14.0 or later
User with sudo privileges
ModSecurity v3 installed and running

Let’s go

Proceed as root for convenience otherwise most commands would have to be preceeded with ’sudo’.
sudo -i

Back up Your Current Configuration

cp -r /etc/nginx /etc/nginx_backup

Install Dependencies & Download NGINX Source.

Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIP
apt-get update
apt-get install build-essential libpcre2 libpcre2-dev zlib1g-dev libssl-dev libbrotli-dev libmaxminddb0 libmaxminddb-dev mmdb-bin git g++ flex bison curl doxygen libyajl-dev libgeoip-dev libtool dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev libxml2-dev make -y

Create a workspace
cd /opt/
mkdir -p /opt/nginx-upgrade
cd /opt/nginx-upgrade
Get your nginx version
nginx -t
Output will be something like this:
nginx version: nginx/[nginx version number]
Note the version number for future reference

Download the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gz

Create Nginx modules directory
mkdir -p /etc/nginx/modules

Clone and Compile the ModSecurity-nginx Module

cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

Navigate to your cloned ModSecurity-nginx folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
Note: Using --with-compat ensures binary compatibility with official Nginx packages.

Compile only the ModSecurity-nginx module:
make modules

Copy the freshly compiled .so file into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Clone and Compile the Brotli Module

cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git

Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure from the Nginx source directory with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
/configure --with-compat --add-dynamic-module=../ngx_brotli

Compile only the Brotli modules:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/

Clone and Compile the Clone GeoIP2 Module

cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git

Navigate to your cloned ngx_http_geoip2_module folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade

Run configure with the --add-dynamic-module flags appended to your configuration:
cd /opt/nginx-upgrade/nginx-[nginx version number]
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module

Compile only the GeoIP2 module:
make modules

Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules

Test and reload Nginx

nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx

Shell script to compile Brotli, and GeoIP2 after Nginx Upgrade

This script will automate everything covered above, as well as reading the correct Nginx version and keeping a log of the process. It is designed to stop on errors and can be re-run as many times as necessary.

#!/bin/bash
# Build against a specific nginx.org NGINX version (nginx -v).
# Intended to run inside an Ubuntu container
# matching the target distribution.
# Compiling GeoIP2 as a dynamic module (.so file)
# Compiling Brotli as a dynamic module (.so file)
# Compiling ModSecurity-nginx as a dynamic module (.so file)
# Must be run in root home as root (sudo -i)

if ! id | grep -q "uid=0(root)"; then
        echo "Must be run as root" 
	exit 1
fi
# Set log file
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
logname=`basename "$0"`
logname+=".log"
logfile=$scriptdir/$logname
touch "$logfile"

# Functions
logger(){
    echo "$(date): $@" >> $logfile
    echo "## $@"
}
logger "Starting script"

# Setup
## NeedRestart config change (automatically restart required services instead of prompting/blocking script. Revert at end).
sed -i 's/#$nrconf{restart} = '\''i'\'';/$nrconf{restart} = '\''a'\'';/' /etc/needrestart/needrestart.conf
#
# Best practice settings for running bash scripts:
# Exit the script when an error is encountered
set -o errexit
# Exit the script when a pipe operation fails
set -o pipefail
# Exit the script when there are undeclared variables
set -o nounset
# Uncomment this to see a log to the screen of each command run in the script
# set -o xtrace
# Credit: nginx.org 2020-10-05 https://gist.github.com/nginx-gists/bdc7da70b124c4f3e472970c7826cccc 

# Back up Your Current Configuration
cp -r /etc/nginx /etc/nginx__backup

# Pre-reqs
apt-get -qq update
apt-get -qq install -y \
libpcre2-dev \
libssl-dev \
zlib1g-dev \
libbrotli-dev \
g++ \
flex \
bison \
curl \
doxygen \
libyajl-dev \
libgeoip-dev \
libtool \
dh-autoreconf \
libcurl4-gnutls-dev \
libxml2-dev \
make \
libmaxminddb0 \
libmaxminddb-dev \
mmdb-bin

# Install the modules
# Get installed Nginx version number
NGINX_VER=$(nginx -v |& sed 's/nginx version: nginx\///' | sed 's/\s.*$//')
logger "Nginx version: $NGINX_VER"

# Create a workspace and download the exact matching Nginx ${NGINX_VER} source code:
cd /opt/

if [ ! -d /opt/nginx-upgrade ]; then
  mkdir -p /opt/nginx-upgrade
fi

cd /opt/nginx-upgrade

if [ ! -f /opt/nginx-upgrade/nginx-${NGINX_VER}/configure ]; then
  curl -O https://nginx.org/download/nginx-${NGINX_VER}.tar.gz
  tar -zxf nginx-${NGINX_VER}.tar.gz
  logger "nginx-${NGINX_VER} source downloaded"
fi

# Clone Module Repositories
# Download the source code for the Brotli GeoIP2 ModSecurity-nginx modules into your workspace.

# delete previous clone directories
if [ -d /opt/nginx-upgrade/ngx_brotli ]; then
  rm -r /opt/nginx-upgrade/ngx_brotli
fi

if [ -d /opt/nginx-upgrade/ngx_http_geoip2_module ]; then
  rm -r /opt/nginx-upgrade/ngx_http_geoip2_module
fi

if [ -d /opt/nginx-upgrade/ModSecurity-nginx ]; then
  rm -r /opt/nginx-upgrade/ModSecurity-nginx
fi

# Clone Brotli module
cd /opt/nginx-upgrade
git clone --recursive https://github.com/google/ngx_brotli.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "Brotli dynamic module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Remove previous configs
if [ -d /opt/nginx-upgrade/nginx-${NGINX_VER}/objs ]; then
  make clean
fi
logger "make clean invoked"

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_brotli
logger "Brotli dynamic module completed"

# Compile only the modules:
make modules
logger "Brotli dynamic modules compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
if [ ! -d /etc/nginx/modules/ ]; then
  mkdir -p /etc/nginx/modules
fi
cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
logger "Brotli dynamic modules copied to /etc/nginx/modules/"

# Clone GeoIP2 module
cd /opt/nginx-upgrade
git clone https://github.com/leev/ngx_http_geoip2_module.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ngx_http_geoip2_module
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "GeoIP2 module cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
logger "GeoIP2 dynamic module completed"

# Compile only the modules:
make modules
logger "GeoIP2 module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/
logger "GeoIP2 dynamic module copied to /etc/nginx/modules/"

# Clone ModSecurity-nginx module
cd /opt/nginx-upgrade
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
# Navigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd /opt/nginx-upgrade/ModSecurity-nginx
git submodule update --init --recursive
cd /opt/nginx-upgrade
logger "ModSecurity-nginx cloned"

cd /opt/nginx-upgrade/nginx-${NGINX_VER}

# Run configure with the --add-dynamic-module flags appended to your configuration:
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
logger "ModSecurity dynamic module configured"

# Note: Using --with-compat ensures binary compatibility with official Nginx packages.

# Compile only the modules:
make modules
logger "ModSecurity dynamic module compiled"

# Copy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
logger "ModSecurity dynamic module copied to /etc/nginx/modules/"

# Verify
# nginx -t
if [ "$(command nginx -t) | grep 'ok'" ]; then
        logger "Nginx configuration ok, reloading.."
	if [ "systemctl status nginx | grep 'Started nginx.service'" ]; then 
		systemctl reload nginx
	else
		systemctl start nginx
	fi
else
        logger "Nginx errors"
fi

ls -la /opt/nginx-upgrade/nginx-${NGINX_VER}/objs

logger "Operation complete"

Download

re-build-modules-after-nginx-upgrade.tgz    raw
Leave A Comment