-
Notifications
You must be signed in to change notification settings - Fork 297
Add support to build ModSecurity-nginx on Windows #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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:
- Set up the nginx-tests framework
- Add the ModSecurity-nginx tests in that directory
- Run the tests after nginx w/ModSecurity-nginx is built
- This may simplify the current build, as I think the tests are probably more extensive that the set of tests executed with each build (and reduce code and maintenance of the QA workflows).
- Test failures will trigger the build to fail as well, as required in a QA workflow. I'm witness of a few of those myself! :-)
- Added the
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. - Updated the step to download & build libModSecurity v3 by using the
checkout
action (and executing ofbuild.sh
beforeconfigure
).- This avoids referencing the
GITHUB_TOKEN
to download the source usinggh
.
- This avoids referencing the
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
- All source code files need to include `ngx_config.h` and this needs to be the first header file included.
- Added define to avoid the following warning, treated as an error by the nginx build system: warning C4996: 'strdup': The POSIX name for this item is deprecated. Ins tead, use the ISO C++ conformant name: _strdup. See online help for details.
- `ngx_http_modsecurity_process_intervention` & `ngx_http_modsecurity_create_ctx` are exported by `ngx_http_modsecurity_module.c`, so they can't be declared as inline because the MSVC compiler will not export them in the generated object file.
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.
- Windows Docker container to build libModSecurity v3 & nginx w/ModSecurity-nginx
- Include steps to run all ModSecurity-nginx tests - Simplify checkout of libModSecurity
Quality Gate Passed Quality Gate passed
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:
- include the Windows build of ModSecurity-nginx,
- have the Linux configuration to run all the tests (like the Windows build configuration does).
- The manual tests that were setup to validate the ModSecurity-nginx Linux build on the GH workflow could probably be removed to reduce maintenance effort of the workflow (as the full tests cover far more scenarios than them).
Thanks for contributing, this is also a huge step!
Uh oh!
There was an error while loading. Please reload this page.
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.