Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
A donation makes a contribution towards the costs, the time and effort that's going in this site and building.
Thank You! Steffen
Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
| |
|
Topic: HOWTO: Building ModSecurity using MSVC toolset |
|
| Author |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 400 Location: UK
|
Posted: Mon 03 Nov '25 18:13 Post subject: HOWTO: Building ModSecurity using MSVC toolset |
|
|
This post is supplemental to, and dependent on, the related HOWTO "Building Apache and dependencies using CMake" https://www.apachelounge.com/viewtopic.php?t=8609
Specifically, it assumes the same build platform and toolset.
The intention is to track the mod_security build listed under the Apache Lounge download section, but allowing the user to customise build options if so desired. To that end, this build script is based around the 2.x (rather than the later 3.x) series of ModSecurity.
Additional configuration options are currently edited into the default apache2\Makefile.win file, including options for WITH_PCRE2, WITH_APU_CRYPTO and HTACCESS_CONFIG.
Note, this post does not cover configuring ModSecurity within Apache.
Change log :
03 Nov 2025 : 1.0 - Initial release.
Sequence
- Prerequisites
Complete the Apache build process detailed in HOWTO "Building Apache and dependencies using CMake" - https://www.apachelounge.com/viewtopic.php?t=8609
- Preparation
Add the following source folders based on the appropriate version of the following packages. This list matches the latest package versions at the time of writing.
| Code: | C:\Development
└ Apache24
├ src
│ ├ modsecurity-2.9.12
│ ├ yajl-2.1.0
│
└ build |
Source Packages
Download and extract the above packages (*.tar.gz or *.zip format) into the corresponding source folders shown above. These packages can be download from GitHub, currently here:
https://github.com/owasp-modsecurity/ModSecurity/tags
https://github.com/lloyd/yajl/tags
Build Batch File
Download the build batch file code from the post below in this thread, and save it in the above 'build' folder as build_mod_security.bat
a) Edit the build batch file to set BUILD_BASE as required, if using a different build path to that above.
b) Update the target PREFIX, if the default location of C:\Apache24 isn't correct.
c) Choose 32 or 64 bit builds by setting the PLATFORM variable in the build batch file to x86 or x64 as required, matching your Apache build.
d) Similarly, set the variable BUILD_TYPE to Release or Debug.
e) Update the path to the vcvarsall.bat file if need be, to match your Visual Studio toolset.
f) Edit the package version details to match your downloads as appropriate.
Build
Open a command or Powershell window with administrative rights, change to the above build folder, and run the build_mod_security.bat batch file. Ideally, redirect the build process output to a log file so you can check for errors. If using Powershell, you can use the tee command, viz:
| Code: | | C:\Development\Apache24\build> .\build_mod_security.bat 2>&1 | tee build_mod_security.log |
N.B. A Windows native binary of tee can be found still at https://gnuwin32.sourceforge.net/packages/coreutils.htm
Checks
When finished search the log file output for fatal errors (hopefully none).
Confirm the ModSecurity files have been created below PREFIX as expected, e.g.
| Code: | C:\Development\apache24\build>dir C:\Apache24\modules\mod_security2.so
Volume in drive C has no label.
Volume Serial Number is 6874-FF76
Directory of c:\Apache24\modules
03/11/2025 15:52 743,936 mod_security2.so
1 File(s) 743,936 bytes
0 Dir(s) 65,599,393,792 bytes free
C:\Development\apache24\build>dir c:\Apache24\conf\modsecurity*
Volume in drive C has no label.
Volume Serial Number is 6874-FF76
Directory of c:\Apache24\conf
05/08/2025 19:13 9,047 modsecurity.conf-recommended
1 File(s) 9,047 bytes
0 Dir(s) 65,599,393,792 bytes free |
Prepare and test your ModSecurity configuration within Apache as required.
I hope people find this HOWTO useful.
Last edited by tangent on Mon 03 Nov '25 19:06; edited 3 times in total |
|
| Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 400 Location: UK
|
Posted: Mon 03 Nov '25 18:14 Post subject: |
|
|
Change log :
03 Nov 2025 : 1.0 - Initial release.
| Code: | @echo off
rem @(#)build_mod_security.bat 1.0 - 2025-11-03 tangent
rem
rem 1.0 - Initial release. 2025-11-03
rem These instructions build ModSecurity and YAJL, assuming you've already built Apache
rem HTTPD following the HOWTO details at https://www.apachelounge.com/viewtopic.php?t=8609
rem
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
rem Set required build base folder and target prefix.
rem
set BUILD_BASE=C:\Development\Apache24\build
set PREFIX=C:\Apache24
rem Set required build platform to x86 or x64.
rem
rem set PLATFORM=x86
set PLATFORM=x64
rem Set required build type to Release or Debug.
rem
rem set BUILD_TYPE=Debug
set BUILD_TYPE=Release
rem Request PDB files - ON or OFF.
rem
set INSTALL_PDB=OFF
rem Define build packages with their version. This is also the recommended build order.
rem PCRE2 is supported with ModSecurity 2.9.8 onwards, as is LUA 5.4 series.
rem YAJL is an optional package for ModSecurity.
rem
set YAJL=yajl-2.1.0
set MOD_SECURITY=modsecurity-2.9.12
rem ------------------------------------------------------------------------------
rem
rem Define path to MS Visual Studio build environment script.
set VCVARSALL=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat
if exist "%VCVARSALL%" (
call "%VCVARSALL%" %PLATFORM%
) else (
echo Could not find "%VCVARSALL%"
exit /b
)
rem ------------------------------------------------------------------------------
rem
rem YAJL (for ModSecurity)
rem Check for package and switch to source folder.
rem
call :check_package_source %YAJL%
if !STATUS! == 0 (
rem Patch relevant CMakeLists.txt file to adjust install locations.
rem
perl -pi.bak -e ^" ^
s~(RUNTIME DESTINATION^) lib~${1} bin~; ^
s~(DESTINATION^) share(/pkgconfig^)~${1} lib${2}~; ^
^" src\CMakeLists.txt
set YAJL_CMAKE_OPTS=-DCMAKE_INSTALL_PREFIX=%PREFIX% -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
call :build_package %YAJL% "!YAJL_CMAKE_OPTS!" & if not !STATUS! == 0 exit /b !STATUS!
)
rem ------------------------------------------------------------------------------
rem
rem ModSecurity
rem Check for package and switch to source folder.
rem
call :check_package_source %MOD_SECURITY%
if !STATUS! == 0 (
echo. & echo Building %MOD_SECURITY%
rem Build from Makefile.win in apache2 sub-folder.
rem
pushd apache2
rem Patch Makefile.win to revise various library and include paths.
rem Notably, revise the LUA lua5.1.lib reference to lib54.lib.
rem Add required build macros, and correct libinjection path.
rem
perl -pi.bak -e ^" ^
s~(PCRE\^)\\^)(pcre^)(.lib \\^)\n~${1}lib\\${2}2-8${3}\n~; ^
s~(CURL\^)\\^)(libcurl^)(.lib^)~${1}lib\\${2}_imp${3}~; ^
s~(LIBXML2\^)\\^).+\\(libxml2^)(.lib^)~${1}lib\\${2}${3}~; ^
s~(LIBXML2\^)\\include^) ~${1}\\libxml2~; ^
s~(LIBS = .+^)\$\((LUA^)(.+^)~${1}\$\(LUA^)\\lib\\lua54.lib~; ^
s~(APR_INLINE.+VERSION\^)$^)~${1} -DWITH_PCRE2 -DWITH_PCRE_JIT -DWITH_PCRE_STUDY -DWITH_APU_CRYPTO -DHTACCESS_CONFIG -D_CRT_SECURE_NO_WARNINGS~; ^
s~(libinjection^)/~${1}\\~; ^
^" Makefile.win
rem Set configure options.
rem
set MOD_SECURITY_CONFIGURE_OPTS=APACHE=%PREFIX% PCRE=%PREFIX% LIBXML2=%PREFIX% LUA=%PREFIX% CURL=%PREFIX% YAJL=%PREFIX%
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! clean
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! & call :get_status
if !STATUS! == 0 (
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! install & call :get_status
if not !STATUS! == 0 (
echo nmake install for %MOD_SECURITY% failed with status !STATUS!
) else (
rem Some additional manual installation is required.
rem
rem Define extra files as src_dir#src_file#dst_dir#dst_file
rem If dst_file is missing, then use src_file as destination filename
rem
set EXTRAS=.#mod_security2.exp#%PREFIX%\lib ^
.#mod_security2.lib#%PREFIX%\lib ^
..#modsecurity.conf-recommended#%PREFIX%\conf ^
..#unicode.mapping#%PREFIX%\conf
for %%a in (!EXTRAS!) do (
for /f "tokens=1,2,3,4 delims=#" %%c in ("%%a") do (
if "%%f" == "" (set DST=%%d) else (set DST=%%f)
echo -- Installing: "%%e\!DST!
copy /b /y "%%c\%%d" "%%e\!DST!"
)
)
)
) else (
echo nmake for %MOD_SECURITY% failed with status !STATUS!
)
popd
rem Build from Makefile.win in mlogc sub-folder.
rem
pushd mlogc
rem Patch Makefile.win to revise various paths and required build macros.
rem
perl -pi.bak -e ^" ^
s~(\^)\\^)(pcre^)(.lib \\^)\n~${1}lib\\${2}2-8${3}\n~; ^
s~(\^)\\^)(libcurl^)(.lib^)~${1}lib\\${2}_imp${3}~; ^
s~(APR_INLINE.+VERSION\^)$^)~${1} -DWITH_PCRE2 -D_CRT_SECURE_NO_WARNINGS~; ^
^" Makefile.win
rem Set configure options.
rem
set MOD_SECURITY_CONFIGURE_OPTS=APACHE=%PREFIX% PCRE=%PREFIX% CURL=%PREFIX%
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! clean
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! & call :get_status
if !STATUS! == 0 (
nmake /f Makefile.win !MOD_SECURITY_CONFIGURE_OPTS! install & call :get_status
if not !STATUS! == 0 (
echo nmake install for %MOD_SECURITY% failed with status !STATUS!
) else (
rem Install additional files.
rem
rem Define extra files as src_dir#src_file#dst_dir#dst_file
rem If dst_file is missing, then use src_file as destination filename
rem
set EXTRAS=.#mlogc-default.conf#%PREFIX%\conf ^
.#mlogc-batch-load.pl.in#%PREFIX%\bin#mlogc-batch-load.pl
for %%a in (!EXTRAS!) do (
for /f "tokens=1,2,3,4 delims=#" %%c in ("%%a") do (
if "%%f" == "" (set DST=%%d) else (set DST=%%f)
echo -- Installing: "%%e\!DST!
copy /b /y "%%c\%%d" "%%e\!DST!"
)
)
)
) else (
echo nmake for %MOD_SECURITY% failed with status !STATUS!
exit /b !STATUS!
)
popd
)
exit /b !STATUS!
rem ------------------------------------------------------------------------------
rem
rem Get current errorlevel value and assign it to the status variable.
:get_status
call doskey /exename=err err=%%errorlevel%%
for /f "usebackq tokens=2 delims== " %%i in (`doskey /m:err`) do (set STATUS=%%i)
exit /b !STATUS!
rem ------------------------------------------------------------------------------
rem
rem Get package and version from release variable passed as first parameter.
:get_package_details
set RELEASE=%~1
for /f "delims=-" %%i in ('echo(%RELEASE:-=^&echo(%') do call set "PACKAGE=%%RELEASE:-%%i=%%"
for %%i in (%RELEASE:-= %) do set VERSION=%%i
exit /b
rem ------------------------------------------------------------------------------
rem
rem Check package source folder exists, from release variable passed as first parameter.
rem
:check_package_source
set SRC_DIR=%BUILD_BASE%\..\src\%~1
if not exist "!SRC_DIR!" (
echo Warning for package %~1
echo Could not find package source folder "!SRC_DIR!"
set STATUS=1
) else (
cd /d "!SRC_DIR!"
set STATUS=0
)
exit /b !STATUS!
rem ------------------------------------------------------------------------------
rem
rem Build subroutine.
rem Parameter one is the package release variable.
rem Parameter two is any required CMake options.
rem Parameter three (optional) is any package sub-folder to the CMakeLists.txt file.
:build_package
call :get_package_details %~1
rem Check source folder exists, else exit (non-fatal).
call :check_package_source %~1
if not !STATUS! == 0 (
exit /b
) else (
if not "%~3" == "" (
set SRC_DIR=!SRC_DIR!\%~3
)
)
rem Clean up any previous build.
if exist "%BUILD_BASE%\!PACKAGE!" rmdir /s /q "%BUILD_BASE%\!PACKAGE!" 1>nul 2>&1
mkdir "%BUILD_BASE%\!PACKAGE!" 1>nul 2>&1
rem Build, make and install.
if exist "%BUILD_BASE%\!PACKAGE!" (
cd /d "%BUILD_BASE%\!PACKAGE!"
echo. & echo Building %~1
rem Patch CMakeLists.txt to remove debug suffix from libraries. Messes up various builds.
rem Tried setting CMAKE_DEBUG_POSTFIX to an empty string on the CMake command line but
rem this doesn't work with all packages, e.g. PCRE2, EXPAT, LIBXML2, etc.
perl -pi -e ^" ^
s~((DEBUG_POSTFIX^|POSTFIX_DEBUG^)\s+^)([\x22]*^)[-_]*(^|s^)d([\x22]*^)~${1}\x22${4}\x22~; ^
^" "!SRC_DIR!\CMakeLists.txt"
rem Run CMake to create an NMake makefile, which we then process.
cmake -G "NMake Makefiles" %~2 -S "!SRC_DIR!" -B . & call :get_status
if !STATUS! == 0 (
nmake & call :get_status
if !STATUS! == 0 (
nmake install & call :get_status
if !STATUS! == 0 (
exit /b !STATUS!
) else (
echo nmake install for !PACKAGE! failed with exit status !STATUS!
exit /b !STATUS!
)
) else (
echo nmake for !PACKAGE! failed with exit status !STATUS!
exit /b !STATUS!
)
) else (
echo cmake for !PACKAGE! failed with exit status !STATUS!
exit /b !STATUS!
)
) else (
echo Failed to make folder "%BUILD_BASE%\!PACKAGE!"
exit /b 1
)
exit /b
|
|
|
| Back to top |
|
|
|
|
|
|