Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Merged
airween merged 7 commits into owasp-modsecurity:master from eduar-hte:windows-port
May 23, 2024
Merged

Add support to build ModSecurity-nginx on Windows #321

airween merged 7 commits into owasp-modsecurity:master from eduar-hte:windows-port
May 23, 2024

Conversation

Copy link
Contributor

@eduar-hte eduar-hte commented May 1, 2024
edited
Loading

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 new win32 folder.

Additionally, a Windows Docker container configuration is included to simplify prerequisites setup and build.

Summary of changes

  • Adjust how to config in ModSecurity-nginx the libModSecurity library dependency for the Windows build.
  • Include ngx_config.h first on all source code files because the nginx build process on Windows uses precompiled headers.
  • Add an alias for strdup (not included in the MSVC C++ compiler)
  • Remove incorrect ngx_inline in two functions in ngx_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.

airween reacted with thumbs up emoji airween reacted with eyes emoji
Copy link
Contributor Author

eduar-hte commented May 1, 2024
edited
Loading

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 of build.sh before configure).
    • This avoids referencing the 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

eduar-hte added 4 commits May 4, 2024 12:40
- 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.
Copy link
Contributor Author

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.

eduar-hte added 3 commits May 15, 2024 07:17
- Windows Docker container to build libModSecurity v3 & nginx w/ModSecurity-nginx
- Include steps to run all ModSecurity-nginx tests
- Simplify checkout of libModSecurity
Copy link

Copy link
Contributor Author

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).

Copy link
Member

airween commented May 23, 2024

Thanks for contributing, this is also a huge step!

eduar-hte reacted with thumbs up emoji

@airween airween merged commit ef64996 into owasp-modsecurity:master May 23, 2024
@eduar-hte eduar-hte deleted the windows-port branch May 23, 2024 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@airween airween airween approved these changes

Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /