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
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 hostNginx 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_backupInstall Dependencies & Download NGINX Source.
Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIPapt-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 -yCreate 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 referenceDownload the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gzCreate 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 modulesCopy 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.gitNavigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgradeRun 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_brotliCompile only the Brotli modules:
make modulesCopy 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.gitNavigate 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-upgradeRun 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_moduleCompile only the GeoIP2 module:
make modulesCopy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modulesTest 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 nginxShell 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 rawIntroduction
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
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 hostNginx 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_backupInstall Dependencies & Download NGINX Source.
Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIPapt-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 -yCreate 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 referenceDownload the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gzCreate 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 modulesCopy 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.gitNavigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgradeRun 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_brotliCompile only the Brotli modules:
make modulesCopy 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.gitNavigate 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-upgradeRun 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_moduleCompile only the GeoIP2 module:
make modulesCopy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modulesTest 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 nginxShell 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 rawTotal Views: 906Daily Views: 21
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
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 hostNginx 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_backupInstall Dependencies & Download NGINX Source.
Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIPapt-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 -yCreate 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 referenceDownload the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gzCreate 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 modulesCopy 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.gitNavigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgradeRun 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_brotliCompile only the Brotli modules:
make modulesCopy 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.gitNavigate 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-upgradeRun 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_moduleCompile only the GeoIP2 module:
make modulesCopy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modulesTest 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 nginxShell 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 rawIntroduction
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
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 hostNginx 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_backupInstall Dependencies & Download NGINX Source.
Install the underlying compilation tools and development libraries needed for ModSecurity, Brotli and GeoIPapt-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 -yCreate 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 referenceDownload the Nginx source code
curl -O https://nginx.org/download/nginx-[nginx version number].tar.gz
tar -zxf nginx-[nginx version number].tar.gzCreate 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 modulesCopy 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.gitNavigate to your cloned ngx_brotli folder and pull down missing dependencies:
cd ngx_brotli
git submodule update --init --recursive
cd /opt/nginx-upgradeRun 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_brotliCompile only the Brotli modules:
make modulesCopy 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.gitNavigate 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-upgradeRun 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_moduleCompile only the GeoIP2 module:
make modulesCopy the freshly compiled .so files into your system’s Nginx modules directory:
cp objs/ngx_http_geoip2_module.so /etc/nginx/modulesTest 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 nginxShell 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"