-
Notifications
You must be signed in to change notification settings - Fork 87
228 lines (203 loc) · 8.9 KB
/
verifyimage.yml
File metadata and controls
228 lines (203 loc) · 8.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
---
name: Verify Images
on:
pull_request:
branches:
- main
env:
# sha256sum format: <hash><space><format (space for text)><file name>
MODSECURITY_RECOMMENDED: "ccff8ba1f12428b34ff41960d8bf773dd9f62b9a7c77755247a027cb01896d4f modsecurity.conf-recommended"
GO_FTW_VERSION: '1.3.0'
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # actions/checkout@v5
- name: Generate matrix
id: generate
uses: docker/bake-action/subaction/matrix@v6
with:
target: default
- name: Check modsecurity recommended
run: |
curl -sSL https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/modsecurity.conf-recommended -o modsecurity.conf-recommended
echo '${{ env.MODSECURITY_RECOMMENDED }}' > sha256sum.txt
sha256sum -c sha256sum.txt
build:
runs-on: ubuntu-latest
needs:
- prepare
strategy:
matrix:
include: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # actions/checkout@v5
with:
fetch-depth: 1
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # docker/setup-qemu-action@v3
with:
image: tonistiigi/binfmt:qemu-v9.2.0
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # docker/setup-buildx-action@v3
with:
driver-opts: image=moby/buildkit:master
- name: Login to GitHub Container Registry
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # docker/login-action@v3.5.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build ${{ matrix.target }}-verification
uses: docker/bake-action@3acf805d94d93a86cce4ca44798a76464a75b88c # docker/bake-action@v6.9.0
with:
files: |
./docker-bake.hcl
targets: ${{ matrix.target }}
# Build only linux/amd64 and tag the images as verification builds.
# Create a tar archive and load the image into Docker.
set: |
*.platform=linux/amd64
${{ matrix.target }}.tags=${{ matrix.target }}-verification
*.output=type=docker,dest=${{ matrix.target }}-verification.tar
*.output=type=docker
push: false
- name: Upload image artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-verification.tar
path: ${{ matrix.target }}-verification.tar
retention-days: 7
overwrite: true
- name: Run ${{ matrix.target }}
run: |
# get the major version from the matrix.target
# The targets end with `<major>-<minor>-<patch>`.
CRS_VERSION="v$(awk -F'-' '{print $(NF-2)}' <<< ${{ matrix.target }})"
. .github/workflows/configure-rules-for-test.sh \
"src/opt/modsecurity/configure-rules.${CRS_VERSION}.conf" \
README.md \
"${{ matrix.target }}.env"
echo "Starting container ${{ matrix.target }}-verification"
# The backend is a dummy
docker run \
--pull "never" \
-d \
--name ${{ matrix.target }}-test \
--env-file "${{ matrix.target }}.env" \
-p 8080:8080 \
-e BACKEND=http://localhost:9999 \
"${{ matrix.target }}-verification"
- name: Verify ${{ matrix.target }}
run: |
HOST_AND_PORT="localhost:8080"
counter=10
while true; do
printf "Checking whether container is running..."
if [ $(docker inspect ${{ matrix.target }}-test --format='{{.State.Running}}') = 'true' ]; then
echo "ok"
printf "Trying to connect..."
if curl -s --connect-timeout 5 --max-time 1 "${HOST_AND_PORT}" > /dev/null 2>&1; then
echo "ok"
break
fi
fi
echo "failed"
((counter--))
if [ ${counter} -gt 0 ]; then
echo "Will retry in 5 seconds"
sleep 5
else
printf "No more retries. Here's the log output from the container\n\n\n"
docker logs ${{ matrix.target }}-test
exit 1
fi
done
if grep -q "nginx"<<< "${{ matrix.target }}"; then
printf "\n\n### nginx tests ###\n\n"
printf "Storing headers for sample attack..."
curl -s -D headers.txt -o /dev/null "${HOST_AND_PORT}/?test=../../etc/passwd"
printf "...done\n\n\n"
printf "Check status 403..."
grep -q "HTTP/1.1 403 Forbidden" headers.txt
printf "yes\n\n\n"
printf "Check 'Access-Control-Allow-Origin' header..."
grep -q "Access-Control-Allow-Origin: *" headers.txt
printf "yes\n\n\n"
printf "Check 'Access-Control-Max-Age' header..."
grep -q "Access-Control-Max-Age: 3600" headers.txt
printf "yes\n\n\n"
printf "Check 'Access-Control-Allow-Methods' header..."
grep -q "Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS" headers.txt
printf "yes\n\n\n"
printf "Check 'Access-Control-Allow-Headers'..."
grep -q "Access-Control-Allow-Headers: *" headers.txt
printf "yes\n\n\n"
echo "### nginx tests - done ###"
fi
printf "\n\n### generic tests ###\n\n"
echo "Test HTTP/2 upgrade..."
curl -v --http2 --no-progress-meter -o /dev/null "${HOST_AND_PORT}" 2>&1 | tee out.txt
grep -iP "< 101 Switching Protocols|< HTTP/2" < out.txt | tee out2.txt
wc -l out2.txt | grep -qoP "\d+" | xargs -I % test % -eq 2
rm out*.txt
printf "...yes\n\n\n"
echo "Test HTTP/2 prior knowledge..."
curl -v --http2-prior-knowledge --no-progress-meter -o /dev/null "${HOST_AND_PORT}" 2>&1 | tee out.txt
grep -iq "< HTTP/2" out.txt
grep -iqv "< 101 Switching Protocols" out.txt
printf "...yes\n\n\n"
echo "### generic tests - done ###"
- name: Checkout CRS
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # actions/checkout@v5
with:
fetch-depth: 1
repository: coreruleset/coreruleset
path: crs
- name: "Install go-ftw"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd crs
gh release download -R coreruleset/go-ftw "v${{ env.GO_FTW_VERSION }}" \
-p "ftw_${{ env.GO_FTW_VERSION }}_linux_amd64.tar.gz" -O - | tar -xzvf - ftw
- name: Patch CRS compose file to use verification image
run: |
sed -i \
's#image: owasp/modsecurity-crs:${{ contains(matrix.target, 'apache') && 'apache' || 'nginx' }}.*#image: ${{ matrix.target }}-verification#' \
crs/tests/docker-compose.yml
- name: Run CRS tests for ${{ matrix.target }}
# Log flushing isn't reliable enough for go-ftw (https://github.com/coreruleset/go-ftw/issues/473)
if: ${{!contains(matrix.target, 'nginx-alpine')}}
run: |
cd crs
modsec_version="${{ contains(matrix.target, 'apache') && 'modsec2-apache' || 'modsec3-nginx' }}"
backend="${{ contains(matrix.target, 'apache') && 'httpd' || 'nginx' }}"
mkdir -p "tests/logs/${modsec_version}/{nginx,apache2}"
docker compose -f ./tests/docker-compose.yml up -d "${modsec_version}"
sleep 10
docker compose -f ./tests/docker-compose.yml logs
if ! [ "$(docker inspect ${modsec_version} --format='{{.State.Running}}')" = "true" ]; then
echo "Web server failed to start. Aborting."
exit 1
fi
./ftw check -d tests/regression/tests
./ftw run \
-d tests/regression/tests \
--log-file "tests/logs/${modsec_version}/error.log" \
--overrides "tests/regression/${backend}-overrides.yaml" \
--show-failures-only
- name: Upload logs
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4
if: always()
with:
name: ${{ matrix.target }}-error.log
path: "crs/tests/logs/${{ contains(matrix.target, 'apache') && 'modsec2-apache' || 'modsec3-nginx' }}/error.log"
retention-days: 7
overwrite: true