-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add CMake and CI Pipeline for ModSecurityIIS in ModSecurity V2 #3452
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 53 commits into
owasp-modsecurity:v2/master
from
A13501350:v2/test-ci-windows
Oct 25, 2025
+837
−469
Merged
Changes from 50 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
336ef39
添加 CI/CD 工作流和 CMake 配置以支持 IIS 模块构建
A13501350 68483e1
Test CI Windows
A13501350 8769f16
fix powershell
A13501350 18095c0
test
A13501350 5802c01
test again
A13501350 8442520
test 3
A13501350 0e2b4b9
test workflow_dispatch
A13501350 45c1514
........
A13501350 85f60f4
here we go again
A13501350 952ac5f
da.n
A13501350 53bcd83
my bad
A13501350 dc7fcdc
forget json
A13501350 3eafb4e
tt
A13501350 87ae85f
again!
A13501350 5977c8c
fffff
A13501350 c432a6a
vcpkg Caching
A13501350 4662e75
change target
A13501350 9165787
Test winget availability
A13501350 44813cb
test x86
A13501350 a05038e
no ucrt64
A13501350 3881488
path error?
A13501350 bd6d638
find path
A13501350 3dabde3
where are you?
A13501350 73531e9
should fine
A13501350 d4a9129
test package
A13501350 d75eea0
untest
A13501350 3b67dde
but untest
A13501350 df8e7e4
sorry
A13501350 66b20ea
find iis
A13501350 955e99d
oh
A13501350 7024ef9
fix
A13501350 a97e8e6
comment
A13501350 0561440
LLM
A13501350 2563b1c
add def
A13501350 67cab1c
should?
A13501350 3c173f2
ok..
A13501350 f82b27b
......
A13501350 1fde9d8
testing
A13501350 e9a9850
there there
A13501350 691617b
try to fix ipv6
A13501350 e67f3a4
why config error
A13501350 5320e36
fix include
A13501350 c0dc37f
mujiansu
A13501350 a273cd1
Merge branch 'v2/test-ci-windows' of https://github.com/A13501350/Mod…
A13501350 65546f0
fix: SonarCloud issues
A13501350 6f53e50
build: add ftw cloud test
A13501350 e6192b8
fix: go bin location
A13501350 fa4166f
fix: go-ftw command
A13501350 7eca5bb
fix: testing error
A13501350 c85d399
fix: version number
A13501350 b4e245e
build: Enable ssdeep and revert Version
A13501350 98a1f9a
fix: pinning commit for some action
A13501350 326da02
fix: make SonarCloud happy
A13501350 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,333 @@ | ||
| name: CI/CD for IIS Module | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - v2/test-ci-windows | ||
| pull_request: | ||
| branches: | ||
| - v2/test-ci-windows | ||
airween marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| jobs: | ||
| build: | ||
| strategy: | ||
| matrix: | ||
| arch: [x64, x86] | ||
| config: [Release, RelWithDebInfo] | ||
| runs-on: windows-latest | ||
|
|
||
| # For Caching | ||
| permissions: | ||
| actions: read | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Install Apache for x86 | ||
| if: matrix.arch == 'x86' | ||
| shell: pwsh | ||
| run: | | ||
| $apachePath = "${{ github.workspace }}\apache-x86" | ||
| New-Item -ItemType Directory -Path $apachePath -Force | ||
| choco install apache-httpd -y --force --forcex86 --no-progress -r --params="'/installLocation:$apachePath /noService'" | ||
| echo "APACHE_ROOT=$apachePath\Apache24" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | ||
|
|
||
| - name: Set Apache path for x64 | ||
| if: matrix.arch == 'x64' | ||
| shell: pwsh | ||
| run: | | ||
| echo "APACHE_ROOT=C:\tools\Apache24" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | ||
|
|
||
| # Original Make file contain comment build script for ssdeep, | ||
| # which is rely on MSYS2, so we need to install MSYS2. | ||
| # If it's enabled, it need msys2 library for ssdeep. | ||
|
|
||
| # - name: Setup MSYS2 | ||
| # uses: msys2/setup-msys2@v2 | ||
| # with: | ||
| # msystem: ${{ matrix.arch == 'x86' && 'MINGW32' || 'UCRT64' }} | ||
| # update: true | ||
| # install: > | ||
| # git | ||
| # make | ||
| # autoconf | ||
| # automake | ||
| # libtool | ||
| # ${{ matrix.arch == 'x86' && 'mingw-w64-i686-gcc' || 'mingw-w64-ucrt-x86_64-gcc' }} | ||
| # ${{ matrix.arch == 'x86' && 'mingw-w64-i686-pkg-config' || 'mingw-w64-ucrt-x86_64-pkg-config' }} | ||
|
|
||
| # - name: Clone and build ssdeep | ||
| # shell: msys2 {0} | ||
| # run: | | ||
| # MSYS2_WORKSPACE=$(cygpath -u '${{ github.workspace }}') | ||
| # echo "Converted workspace path: $MSYS2_WORKSPACE" | ||
|
|
||
| # git clone https://github.com/ssdeep-project/ssdeep.git --depth 1 | ||
| # cd ssdeep | ||
| # autoreconf -i | ||
|
|
||
| # if [ "${{ matrix.arch }}" = "x86" ]; then | ||
| # ./configure --enable-shared --disable-static CFLAGS="-O3" CXXFLAGS="-O3" --build=i686-pc-mingw32 | ||
| # else | ||
| # ./configure --enable-shared --disable-static CFLAGS="-O3" CXXFLAGS="-O3" | ||
| # fi | ||
|
|
||
| # make dll | ||
|
|
||
| # mkdir -p "${MSYS2_WORKSPACE}/ssdeep-install-${{ matrix.arch }}/bin" | ||
| # mkdir -p "${MSYS2_WORKSPACE}/ssdeep-install-${{ matrix.arch }}/include" | ||
| # cp -v fuzzy.dll "${MSYS2_WORKSPACE}/ssdeep-install-${{ matrix.arch }}/bin/" | ||
| # cp -v fuzzy.h "${MSYS2_WORKSPACE}/ssdeep-install-${{ matrix.arch }}/include/" | ||
| # cp -v fuzzy.def "${MSYS2_WORKSPACE}/ssdeep-install-${{ matrix.arch }}/" | ||
|
|
||
| - name: Restore vcpkg cache | ||
| id: vcpkg-cache | ||
| uses: TAServers/vcpkg-cache@v3 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| prefix: vcpkg-iis-module-${{ matrix.arch }}/ | ||
|
|
||
| - uses: ammaraskar/msvc-problem-matcher@master | ||
|
|
||
| - name: Configure CMake for IIS Module | ||
| env: | ||
| VCPKG_FEATURE_FLAGS: "binarycaching" | ||
| VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite" | ||
| VCPKG_DEFAULT_TRIPLET: ${{ matrix.arch }}-windows | ||
| run: | | ||
| $archFlag = "${{ matrix.arch }}" | ||
| $cmakeArch = if ($archFlag -eq "x86") { "Win32" } else { "x64" } | ||
| $installDir = if ($archFlag -eq "x86") { "x86" } else { "amd64" } | ||
|
|
||
| cmake ` | ||
| -DAPACHE_ROOT="$env:APACHE_ROOT" ` | ||
| -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}\iis\release\$installDir" ` | ||
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" ` | ||
| -A $cmakeArch ` | ||
| -DWITH_LUA=ON ` | ||
| -DWITH_YAJL=ON ` | ||
| -S IIS -B "iis\build" | ||
|
|
||
| # -DSSDEEP_ROOT="${{ github.workspace }}\ssdeep-install-${{ matrix.arch }}" ` | ||
| # -DWITH_SSDEEP=ON ` | ||
|
|
||
| - name: Build IIS Module | ||
| shell: pwsh | ||
| run: | | ||
| cmake --build "iis\build" --config ${{ matrix.config }} | ||
|
|
||
| - name: Upload artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: iis-module-${{ matrix.arch }}-${{ matrix.config }} | ||
| path: iis/build/${{ matrix.config }}/ | ||
|
|
||
| package: | ||
| needs: build | ||
| runs-on: windows-latest | ||
| strategy: | ||
| matrix: | ||
| config: [Release, RelWithDebInfo] | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Download x64 artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: iis-module-x64-${{ matrix.config }} | ||
| path: iis/release/amd64/ | ||
|
|
||
| - name: Download x86 artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: iis-module-x86-${{ matrix.config }} | ||
| path: iis/release/x86/ | ||
|
|
||
| - name: Generate MSI files | ||
| shell: pwsh | ||
| run: | | ||
| heat dir "iis\release\amd64" -cg ModSec64Components -dr inetsrv64 -gg -sreg -srd -var var.ModSecurityIISRelease64 -out "iis\ModSec64.wxs" | ||
| heat dir "iis\release\x86" -cg ModSec32Components -dr inetsrv32 -gg -sreg -srd -var var.ModSecurityIISRelease32 -out "iis\ModSec32.wxs" | ||
| candle.exe -ext WixUtilExtension -ext WixUIExtension "iis\installer.wxs" "iis\ModSec64.wxs" -arch x64 -dModSecurityIISRelease64="iis\release\amd64\" -out iis\ | ||
| candle.exe -ext WixUtilExtension -ext WixUIExtension "iis\ModSec32.wxs" -arch x86 -dModSecurityIISRelease32="iis\release\x86\" -out iis\ | ||
| light.exe -ext WixUtilExtension -ext WixUIExtension "iis\installer.wixobj" "iis\ModSec32.wixobj" "iis\ModSec64.wixobj" -out "iis\modsecurityiis.msi" | ||
|
|
||
| - name: Upload artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: modsecurityiis-installers-${{ matrix.config }} | ||
| path: iis/modsecurityiis.msi | ||
|
|
||
| test: | ||
| needs: package | ||
| runs-on: windows-latest | ||
| strategy: | ||
| matrix: | ||
| config: [Release, RelWithDebInfo] | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Download MSI files | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: modsecurityiis-installers-${{ matrix.config }} | ||
| path: ${{ github.workspace }}/ | ||
|
|
||
| - name: Install MSI | ||
| shell: pwsh | ||
| run: | | ||
| $msiPath = "${{ github.workspace }}\modsecurityiis.msi" | ||
| if (-not (Test-Path $msiPath)) { | ||
| Write-Error "MSI file not found at $msiPath" | ||
| exit 1 | ||
| } | ||
|
|
||
| # Install with logging for debugging | ||
| $installLog = "${{ github.workspace }}\install.log" | ||
| $installResult = Start-Process -FilePath "msiexec.exe" -ArgumentList @( | ||
| "/i", "`"$msiPath`"", | ||
| "/qn", | ||
| "/norestart", | ||
| "/l*", "`"$installLog`"" | ||
| ) -Wait -PassThru | ||
|
|
||
| if ($installResult.ExitCode -ne 0) { | ||
| Write-Error "MSI installation failed with exit code $($installResult.ExitCode)" | ||
| Get-Content $installLog | Write-Host | ||
| exit 1 | ||
| } | ||
|
|
||
| $installDir = "C:\Program Files\ModSecurity IIS" | ||
| $requiredFiles = @( | ||
| "modsecurity.conf", | ||
| "modsecurity_iis.conf" | ||
| ) | ||
|
|
||
| foreach ($file in $requiredFiles) { | ||
| $filePath = Join-Path $installDir $file | ||
| if (-not (Test-Path $filePath)) { | ||
| Write-Error "Required file $file not found in installation directory" | ||
| exit 1 | ||
| } | ||
| } | ||
|
|
||
| - name: Install OWASP Core Rules | ||
| shell: pwsh | ||
| run: | | ||
| $crsVersion = "v4.18.0" | ||
| $crsUrl = "https://github.com/coreruleset/coreruleset/archive/refs/tags/$crsVersion.tar.gz" | ||
| $crsDir = "C:\Program Files\ModSecurity IIS\coreruleset" | ||
| $modSecurityConfigDir = "C:\Program Files\ModSecurity IIS" | ||
|
|
||
| try { | ||
| New-Item -ItemType Directory -Path $crsDir -Force | ||
| Invoke-WebRequest -Uri $crsUrl -OutFile "$crsDir\$crsVersion.tar.gz" | ||
| tar -xzf "$crsDir\$crsVersion.tar.gz" -C $crsDir --strip-components=1 | ||
|
|
||
| Get-ChildItem "$crsDir" -Recurse -Filter "*.example" | ForEach-Object { | ||
| $newName = $_.Name.Replace(".example", "") | ||
| Rename-Item -Path $_.FullName -NewName $newName | ||
| } | ||
|
|
||
| $modSecurityConfigFile = "$modSecurityConfigDir\modsecurity_iis.conf" | ||
|
|
||
| $crsRules = @( | ||
| "Include coreruleset/crs-setup.conf", | ||
| "Include coreruleset/plugins/*-config.conf", | ||
| "Include coreruleset/plugins/*-before.conf", | ||
| "Include coreruleset/rules/*.conf", | ||
| "Include coreruleset/plugins/*-after.conf" | ||
| ) | ||
|
|
||
| Add-Content -Path $modSecurityConfigFile -Value $crsRules | ||
|
|
||
| (Get-Content -Path $modSecurityConfigDir\modsecurity.conf) -replace 'SecRuleEngine DetectionOnly', 'SecRuleEngine On' | Set-Content -Path $modSecurityConfigDir\modsecurity.conf | ||
|
|
||
| } | ||
| catch { | ||
| Write-Error "Failed to install OWASP Core Rules: $($_.Exception.Message)" | ||
| exit 1 | ||
| } | ||
|
|
||
| - name: Test IIS Module | ||
| shell: pwsh | ||
| run: | | ||
| $iisConfigDir = "C:\Program Files\ModSecurity IIS\" | ||
|
|
||
| Restart-Service W3SVC -Force | ||
|
|
||
| $modules = & "$env:SystemRoot\system32\inetsrv\appcmd.exe" list modules | ||
| Write-Host "IIS modules: $modules" | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Error "appcmd failed with exit code $LASTEXITCODE" | ||
| exit 1 | ||
| } | ||
|
|
||
| if (-not ($modules -match "ModSecurity")) { | ||
| Write-Error "ModSecurity module not found in IIS modules" | ||
| Write-Host "IIS modules: $modules" | ||
| exit 1 | ||
| } | ||
|
|
||
| $testCases = @( | ||
| @{Url = "http://localhost/"; Description = "Normal request"; ExpectedCode = 200}, | ||
| @{Url = "http://localhost/?id=1' OR '1'='1"; Description = "SQL injection attempt"; ExpectedCode = 403}, | ||
| @{Url = "http://localhost/?q=<script>alert('test')</script>"; Description = "XSS attempt"; ExpectedCode = 403} | ||
| ) | ||
|
|
||
| foreach ($test in $testCases) { | ||
| try { | ||
| $response = Invoke-WebRequest $test.Url -UseBasicParsing -SkipHttpErrorCheck -TimeoutSec 30 | ||
|
|
||
| if ($response.StatusCode -eq $test.ExpectedCode) { | ||
| Write-Host "PASS: $($test.Description) - returned $($response.StatusCode)" | ||
| } | ||
| else { | ||
| Write-Host "FAIL: $($test.Description) - expected $($test.ExpectedCode) but got $($response.StatusCode)" | ||
| } | ||
| } | ||
| catch { | ||
| Write-Host "ERROR: $($test.Description) - request failed: $($_.Exception.Message)" | ||
| } | ||
| } | ||
|
|
||
|
|
||
| # Check event log | ||
| $badMessagePattern = 'Failed to find the RegisterModule entrypoint|The description for Event ID|The data is the error|dll failed to load' | ||
|
|
||
| $events = Get-EventLog -LogName Application -Newest 100 | | ||
| Where-Object { $_.Message -match $badMessagePattern } | | ||
| Where-Object { $_.Source -match 'IIS|W3SVC|mscor|IIS-W3SVC|IIS-W3WP|ModSecurity' } | ||
|
|
||
| if ($events -and $events.Count -gt 0) { | ||
| Write-Host '::error:: Found errors in event log' | ||
| $events | Select-Object TimeGenerated, Source, EntryType, EventID, Message | Format-List | ||
| Exit 1 | ||
| } | ||
|
|
||
| Get-EventLog -LogName Application -Source ModSecurity | Format-List | ||
|
|
||
| - name: Install go-ftw | ||
| shell: pwsh | ||
| run: | | ||
| go install github.com/coreruleset/go-ftw@latest | ||
|
|
||
| - name: Test ModSecurity Rules | ||
| shell: pwsh | ||
| run: | | ||
| $testRuleDir = "C:\Program Files\ModSecurity IIS\coreruleset\tests\regression\tests" | ||
| $goBinPath = "" | ||
| if ($env:GOBIN) { | ||
| $goBinPath = $env:GOBIN | ||
| } elseif ($env:GOPATH) { | ||
| $goBinPath = Join-Path $env:GOPATH "bin" | ||
| } else { | ||
| $goBinPath = Join-Path $env:USERPROFILE "go\bin" | ||
| } | ||
|
|
||
| & "$goBinPath\go-ftw.exe" run -d $testRuleDir --cloud -e "920100-2$|920100-4$|920100-8$|920100-12$|920272-5$|920290-1$|920620-1$|920380-1$" --show-failures-only | ||
airween marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.