Closed eduar-hte closed 6 months ago
I set up a GitHub workflow to build and test libModSecurity v3 & nginx w/ModSecurity-nginx in my fork's development branch. If and when this PR is merged, it'd be useful include this too.
build-windows:
runs-on: windows-2022
defaults:
run:
shell: msys2 {0}
steps:
- name: Set up MSVC
uses: ilammy/msvc-dev-cmd@v1
- name: Set up msys
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
path-type: inherit
- name: Get Nginx source
uses: actions/checkout@v4
with:
repository: nginx/nginx
path: nginx
fetch-depth: 1
- name: Get Nginx tests
uses: actions/checkout@v4
with:
repository: nginx/nginx-tests
path: nginx/test
fetch-depth: 1
- name: Set up third-party libraries
working-directory: nginx
run: |
mkdir objs
mkdir objs/lib
cd objs/lib
wget -q -O - https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.gz | tar -xzf -
wget -q -O - https://www.zlib.net/fossils/zlib-1.3.tar.gz | tar -xzf -
wget -q -O - https://www.openssl.org/source/openssl-3.0.13.tar.gz | tar -xzf -
- name: Get libModSecurity source
uses: actions/checkout@v4
with:
repository: eduar-hte/ModSecurity
ref: windows-port
submodules: true
path: nginx/objs/lib/ModSecurity
fetch-depth: 1
- name: Setup Conan
shell: cmd
run: |
pip3 install conan --upgrade
conan profile detect
- name: Build libModSecurity
working-directory: nginx/objs/lib/ModSecurity
shell: cmd
run: |
vcbuild.bat
- name: Get ModSecurity-nginx source code
uses: actions/checkout@v4
with:
path: nginx/objs/lib/ModSecurity-nginx
- name: Copy ModSecurity-nginx tests to nginx/test
working-directory: nginx/test
run: |
cp ../objs/lib/ModSecurity-nginx/tests/* .
- name: Remove /usr/bin/link conflicting with MSVC link.exe
run: |
set -ex
which link
rm /usr/bin/link
- name: Build nginx w/ModSecurity-nginx module
working-directory: nginx
run: |
: # Windows native version of Perl is required by nginx build
export PATH=/c/Strawberry/perl/bin:$PATH
: # Set env variables to point to libModSecurity v3 include & lib directories
export MODSECURITY_INC=objs/lib/ModSecurity/headers
export MODSECURITY_LIB=objs/lib/ModSecurity/build/win32/build/Release
: # Copy libModSecurity.dll to objs dir (to be able to run nginx later)
cp $MODSECURITY_LIB/libModSecurity.dll objs
: # Configure nginx build w/ModSecurity-nginx module
auto/configure \
--with-cc=cl \
--with-debug \
--prefix= \
--conf-path=conf/nginx.conf \
--pid-path=logs/nginx.pid \
--http-log-path=logs/access.log \
--error-log-path=logs/error.log \
--sbin-path=nginx.exe \
--http-client-body-temp-path=temp/client_body_temp \
--http-proxy-temp-path=temp/proxy_temp \
--http-fastcgi-temp-path=temp/fastcgi_temp \
--http-scgi-temp-path=temp/scgi_temp \
--http-uwsgi-temp-path=temp/uwsgi_temp \
--with-cc-opt=-DFD_SETSIZE=1024 \
--with-pcre=objs/lib/pcre2-10.39 \
--with-zlib=objs/lib/zlib-1.3 \
--with-openssl=objs/lib/openssl-3.0.13 \
--with-openssl-opt=no-asm \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_auth_request_module \
--add-module=objs/lib/ModSecurity-nginx
nmake
- name: Run ModSecurity-nginx tests
working-directory: nginx/test
shell: cmd # tests need to run on a "windows" shell
run: |
md temp
set TEMP=temp
set TEST_NGINX_BINARY=..\objs\nginx.exe
prove modsecurity*.t
I took the liberty to make a couple of changes on the Linux builds too. The changes are:
ngx_http_v2_module
& ngx_http_auth_request_module
modules to the nginx w/ModSecurity-nginx build for the associated tests to be executed as well.checkout
action (and executing of build.sh
before configure
).
GITHUB_TOKEN
to download the source using gh
. build-linux:
permissions:
contents: read
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
compiler: [gcc, clang]
env:
CC: "/usr/bin/${{ matrix.compiler }}"
CXX: "/usr/bin/${{ matrix.compiler == 'gcc' && 'g' || 'clang' }}++"
COMPDEPS: "${{ matrix.compiler == 'gcc' && 'gcc g++' || 'clang' }}"
steps:
- name: Setup Dependencies
run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y -qq
sudo apt-get install -y make autoconf automake make libyajl-dev libxml2-dev libmaxminddb-dev libcurl4-gnutls-dev $COMPDEPS
- name: Get libModSecurity source
uses: actions/checkout@v4
with:
repository: owasp-modsecurity/ModSecurity
path: ModSecurity
submodules: true
fetch-depth: 1
- name: Build libModSecurity
working-directory: ModSecurity
run: |
./build.sh
./configure --without-lmdb --prefix=/usr
make -j $(nproc)
sudo make install
- uses: actions/checkout@v4
with:
path: ModSecurity-nginx
fetch-depth: 1
- name: Get Nginx source
uses: actions/checkout@v4
with:
repository: nginx/nginx
path: nginx
fetch-depth: 1
- name: Get Nginx tests
uses: actions/checkout@v4
with:
repository: nginx/nginx-tests
path: nginx/test
fetch-depth: 1
- name: Copy ModSecurity-nginx tests to nginx/test
run: |
cp ModSecurity-nginx/tests/* nginx/test
- name: Build nginx with ModSecurity-nginx module
working-directory: nginx
run: |
./auto/configure --with-ld-opt="-Wl,-rpath,/usr/local/lib" --without-pcre2 --with-http_v2_module --with-http_auth_request_module --add-module=../ModSecurity-nginx
make
make modules
sudo make install
- name: Run ModSecurity-nginx tests
working-directory: nginx/test
run: |
TEST_NGINX_BINARY=../objs/nginx prove modsecurity*.t
- name: Start Nginx
run: |
sudo /usr/local/nginx/sbin/nginx -c /home/runner/work/ModSecurity-nginx/ModSecurity-nginx/ModSecurity-nginx/.github/nginx/nginx.conf
- name: Run attack test vhost 1
run: |
status=$(curl -sSo /dev/null -w %{http_code} -I -X GET -H "Host: modsectest1" "http://localhost/?q=attack")
if [ "${status}" == "403" ]; then
echo "OK"
else
echo "FAIL"
exit 1
fi
- name: Run non-attack test vhost 1
run: |
status=$(curl -sSo /dev/null -w %{http_code} -I -X GET -H "Host: modsectest1" "http://localhost/?q=1")
if [ "${status}" == "200" ]; then
echo "OK"
else
echo "FAIL"
exit 1
fi
- name: Run attack test vhost 2
run: |
status=$(curl -sSo /dev/null -w %{http_code} -I -X GET -H "Host: modsectest2" "http://localhost/?q=attack")
if [ "${status}" == "403" ]; then
echo "OK"
else
echo "FAIL"
exit 1
fi
- name: Run non-attack test vhost 2
run: |
status=$(curl -sSo /dev/null -w %{http_code} -I -X GET -H "Host: modsectest2" "http://localhost/?q=1")
if [ "${status}" == "200" ]; then
echo "OK"
else
echo "FAIL"
exit 1
fi
I updated the changes to the config file and the one that introduces strdup so that they apply only when the MSVC C++ compiler is used, because it may be possible to cross-compile for Windows using gcc/clang (looking at the build configuration of nginx) and they may not be needed in that case.
Issues
0 New issues
0 Accepted issues
Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code
I've just updated the branch to reference that ModSecurity PR 3132 has been merged. The documentation and Docker build no longer references the forked repository in order to build the library.
I've also updated the GitHub workflow based on the previous comment to:
Thanks for contributing, this is also a huge step!
This PR includes changes to support building nginx with the ModSecurity-nginx module on Windows (which has been requested in the past in ModSecurity Issue #2480).
This work depends on the PR to build libModSecurity v3 on Windows, see ModSecurity PR #3132.
The changes to build the ModSecurity-nginx module are few. The build process requires a number of tools and third-party libraries due to the fact that both libModSecurity v3 and nginx w/ModSecurity-nginx need to be built. This process is documented step-by-step in the
README.md
file included in the newwin32
folder.Additionally, a Windows Docker container configuration is included to simplify prerequisites setup and build.
Summary of changes
ngx_config.h
first on all source code files because the nginx build process on Windows uses precompiled headers.ngx_inline
in two functions inngx_http_modsecurity_module.c
that prevent the functions to be exported and thus trigger linker errors.Tests
All ModSecurity-nginx tests were executed successfully on Windows by building nginx with the optional
ngx_http_v2_module
&ngx_http_auth_request_module
modules. Additionally, the tests were successfully run on the Linux gcc/clang builds too.Miscellaneous
The ModSecurity-nginx connector is built as a static nginx module. It looks as if there's currently no support for dynamic modules on nginx for Windows using MSVC.
It may be possible to cross-compile for Windows using gcc/clang, which may enable building using dynamic modules too.