Skip to content

Commit 4a9387f

Browse files
authored
Merge pull request #376 from coreruleset/chore/update-crs-v3.3
chore: roll updated crs v3.3 containers
2 parents 8132a96 + c01d5d2 commit 4a9387f

File tree

8 files changed

+96
-26
lines changed

8 files changed

+96
-26
lines changed

.github/workflows/verifyimage.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ jobs:
8383

8484
- name: Run ${{ matrix.target }}
8585
run: |
86+
# get the major version from the matrix.target
87+
# The targets end with `<major>-<minor>-<patch>`.
88+
CRS_VERSION="v$(awk -F'-' '{print $(NF-2)}' <<< ${{ matrix.target }})"
8689
. .github/workflows/configure-rules-for-test.sh \
87-
src/opt/modsecurity/configure-rules.conf \
90+
"src/opt/modsecurity/configure-rules.${CRS_VERSION}.conf" \
8891
README.md \
8992
"${{ matrix.target }}.env"
9093
echo "Starting container ${{ matrix.target }}-verification"

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ Stable Tags are composed of:
2424
* date, in the format `YYYYMMDDHHMM`
2525

2626
The stable tag format is `<CRS version>-<web server>[-<os>][-<writable>]-<date>`.
27-
Examples:
28-
* `4-nginx-202401121309`
29-
* `4.0-apache-alpine-202401121309`
27+
Examples (do not blindly copy these labels):
28+
* `4-nginx-202509051009`
29+
* `4.18-nginx-202509051009`
30+
* `4.18.0-nginx-202509051009`
31+
Or for the previous major release:
32+
* `3-nginx-alpine-202509051009`
33+
* `3.3-nginx-alpine-202509051009`
34+
* `3.3.7-nginx-alpine-202509051009`
3035

3136
### Rolling Tags
3237

docker-bake.hcl

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,22 @@ variable "modsec2-flags" {
1717
default = "--with-yajl --with-ssdeep --with-pcre2"
1818
}
1919

20-
variable "crs-version" {
20+
variable "previous-major-crs-version" {
21+
default = "3.3.7"
22+
}
23+
24+
variable "major-crs-version" {
2125
# renovate: depName=coreruleset/coreruleset datasource=github-releases
2226
default = "4.18.0"
2327
}
2428

29+
variable "crs-versions" {
30+
default = {
31+
"previous" = previous-major-crs-version,
32+
"latest" = major-crs-version
33+
}
34+
}
35+
2536
variable "nginx-version" {
2637
# renovate: depName=nginxinc/nginx-unprivileged datasource=docker
2738
default = "1.28.0"
@@ -115,7 +126,6 @@ target "platforms-base" {
115126
"org.opencontainers.image.source" = "https://github.com/coreruleset/modsecurity-crs-docker"
116127
}
117128
args = {
118-
CRS_RELEASE = "${crs-version}"
119129
MODSEC2_VERSION = "${modsec2-version}"
120130
MODSEC2_FLAGS = modsec2-flags
121131
MODSEC3_VERSION = "${modsec3-version}"
@@ -127,6 +137,7 @@ target "platforms-base" {
127137

128138
target "apache" {
129139
matrix = {
140+
crs_release = crs-versions
130141
base = [
131142
{
132143
name = "debian"
@@ -146,21 +157,23 @@ target "apache" {
146157
}
147158

148159
inherits = ["platforms-base"]
149-
name = "apache-${base.name}"
160+
name = "apache-${base.name}-${replace(crs_release, ".", "-")}"
150161
contexts = {
151162
image = base.image
152163
}
153164
dockerfile = base.dockerfile
154165
args = {
166+
CRS_RELEASE = "${crs_release}"
155167
LUA_MODULES = base.lua_modules
156168
}
157169
tags = concat(tag(base.tag_base),
158-
vtag("${crs-version}", base.tag_base)
170+
vtag("${crs_release}", base.tag_base)
159171
)
160172
}
161173

162174
target "nginx" {
163175
matrix = {
176+
crs_release = crs-versions
164177
base = [
165178
{
166179
name = "debian"
@@ -175,6 +188,7 @@ target "nginx" {
175188
image = "docker-image://nginxinc/nginx-unprivileged:${nginx-version}-alpine"
176189
lua_modules = join(" ", lua-modules-alpine)
177190
tag_base = "nginx-alpine"
191+
crs_release = crs-versions
178192
}
179193
],
180194
read-only-fs = [
@@ -189,19 +203,20 @@ target "nginx" {
189203
]
190204
}
191205
inherits = ["platforms-base"]
192-
name = "nginx-${base.name}-${read-only-fs.name}"
206+
name = "nginx-${base.name}-${read-only-fs.name}-${replace(crs_release, ".", "-")}"
193207
contexts = {
194208
image = base.image
195209
}
196210
dockerfile = base.dockerfile
197211
args = {
212+
CRS_RELEASE = crs_release
198213
NGINX_VERSION = nginx-version
199214
LUA_MODULES = base.lua_modules
200215
NGINX_DYNAMIC_MODULES = join(" ", [for mod in nginx-dynamic-modules : join(" ", [mod.owner, mod.name, mod.version])])
201216
NGINX_HOME = "/etc/nginx"
202217
READ_ONLY_FS = read-only-fs.read-only
203218
}
204219
tags = concat(tag("${base.tag_base}${equal(read-only-fs.read-only, "true") ? "-read-only" : ""}"),
205-
vtag("${crs-version}", "${base.tag_base}${equal(read-only-fs.read-only, "true") ? "-read-only" : ""}")
220+
vtag("${crs_release}", "${base.tag_base}${equal(read-only-fs.read-only, "true") ? "-read-only" : ""}")
206221
)
207222
}

nginx/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ COPY src/etc/modsecurity.d/setup.conf /etc/nginx/templates/modsecurity.d/setup.c
225225
COPY nginx/docker-entrypoint.d/*.sh /docker-entrypoint.d/
226226
COPY src/opt/modsecurity/activate-plugins.sh /docker-entrypoint.d/94-activate-plugins.sh
227227
COPY src/opt/modsecurity/configure-rules.sh /docker-entrypoint.d/95-configure-rules.sh
228-
COPY src/opt/modsecurity/configure-rules.conf /docker-entrypoint.d/
228+
COPY src/opt/modsecurity/configure-rules.*.conf /docker-entrypoint.d/
229229
# We use the templating mechanism from the nginx image here.
230230
COPY nginx/templates /etc/nginx/templates/
231231
COPY src/bin/* /usr/local/bin/

nginx/Dockerfile-alpine

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ COPY src/etc/modsecurity.d/setup.conf /etc/nginx/templates/modsecurity.d/setup.c
225225
COPY nginx/docker-entrypoint.d/*.sh /docker-entrypoint.d/
226226
COPY src/opt/modsecurity/activate-plugins.sh /docker-entrypoint.d/94-activate-plugins.sh
227227
COPY src/opt/modsecurity/configure-rules.sh /docker-entrypoint.d/95-configure-rules.sh
228-
COPY src/opt/modsecurity/configure-rules.conf /docker-entrypoint.d/
228+
COPY src/opt/modsecurity/configure-rules.*.conf /docker-entrypoint.d/
229229
# We use the templating mechanism from the nginx image here.
230230
COPY nginx/templates /etc/nginx/templates/
231231
COPY src/bin/* /usr/local/bin/

src/opt/modsecurity/configure-rules.sh

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,36 @@ if [ -n "${MANUAL_MODE}" ]; then
1717
return
1818
fi
1919

20-
20+
# Default config file path
2121
setup_conf_path="/etc/modsecurity.d/owasp-crs/crs-setup.conf"
2222

23+
# Accept optional config file
24+
if [ -n "${CONFIG_FILE}" ]; then
25+
setup_conf_path="${CONFIG_FILE}"
26+
fi
27+
28+
# Detect CRS version based on the config file content
29+
detect_crs_version() {
30+
if grep -q "tx\.blocking_paranoia_level" "${setup_conf_path}"; then
31+
echo "v4"
32+
elif grep -q "tx\.paranoia_level" "${setup_conf_path}"; then
33+
echo "v3"
34+
else
35+
echo "Unknown CRS version"
36+
exit 10
37+
fi
38+
}
39+
40+
# Get the CRS version
41+
CRS_VERSION="$(detect_crs_version)"
42+
echo "Detected CRS config file version: ${CRS_VERSION}"
43+
2344
set_value() {
24-
local rule="${1}"
25-
local var_name="${2}"
26-
local tx_var_name="${3}"
27-
local var_value="${4}"
45+
rule="${1}"
46+
var_name="${2}"
47+
tx_var_name="${3}"
48+
var_value="${4}"
49+
2850
echo "Configuring ${rule} for ${var_name} with ${tx_var_name}=${var_value}"
2951

3052
# For each rule, we do one pass to uncomment the rule (up to first blank line after the rule),
@@ -45,6 +67,7 @@ EOF
4567
# by either `,`, `'`, or `"`, depending on whether it's the last line of the rule
4668
# and whether the expression is enclosed in single quotes.
4769
# Use `#` as pattern delimiter, as `/` is part of some variable values.
70+
# Try to find and update the variable (with or without quotes)
4871
ed -s "${setup_conf_path}" <<EOF 2 > /dev/null
4972
/id:${rule}/
5073
/setvar:'\?tx\.${tx_var_name}=/
@@ -58,16 +81,15 @@ should_set() {
5881
}
5982

6083
can_set() {
61-
local rule="${1}"
62-
local tx_var_name="${2}"
84+
rule="${1}"
85+
tx_var_name="${2}"
6386

6487
if ! grep -q "id:${rule}" "${setup_conf_path}"; then
6588
return 1
6689
elif ! grep -Eq "setvar:'?tx\.${tx_var_name}" "${setup_conf_path}"; then
6790
return 1
68-
else
69-
return 0
7091
fi
92+
return 0
7193
}
7294

7395
get_legacy() {
@@ -80,7 +102,7 @@ get_var_name() {
80102

81103
get_var_value() {
82104
# Get the variable name, produce "${<var name>}" and use eval to expand
83-
eval "echo $(echo "${1}" | awk -F'\|' '{print "${"$2"}"}')"
105+
eval "echo $(echo "${1}" | awk -F'\|' '{print "${"$2"}"}' || true)"
84106
}
85107

86108
get_rule() {
@@ -101,7 +123,6 @@ while read -r line; do
101123
var_value="$(get_var_value "${line}")"
102124
rule="$(get_rule "${line}")"
103125
tx_var_name="$(get_tx_var_name "${line}")"
104-
105126
if should_set "${var_value}" "${tx_var_name}"; then
106127
if ! can_set "${rule}" "${tx_var_name}"; then
107128
if [ "${legacy}" = "true" ]; then
@@ -114,14 +135,14 @@ while read -r line; do
114135

115136
set_value "${rule}" "${var_name}" "${tx_var_name}" "${var_value}"
116137
fi
117-
done < "${DIRECTORY}/configure-rules.conf"
138+
done < "${DIRECTORY}/configure-rules.${CRS_VERSION}.conf"
118139

119140
# Add SecDefaultActions
120141
var="${MODSEC_DEFAULT_PHASE1_ACTION}"
121142
if should_set "${var}"; then
122143
if ! grep -Eq "^SecDefaultAction.*phase:1" "${setup_conf_path}"; then
123144
echo "Failed to find definition of SecDefaultAction for phase 1 in ${setup_conf_path}. Aborting"
124-
exit 1
145+
exit 2
125146
fi
126147
ed -s "${setup_conf_path}" <<EOF 2 > /dev/null
127148
/^SecDefaultAction.*phase:1/
@@ -133,7 +154,7 @@ var="${MODSEC_DEFAULT_PHASE2_ACTION}"
133154
if should_set "${var}"; then
134155
if ! grep -Eq "^SecDefaultAction.*phase:2" "${setup_conf_path}"; then
135156
echo "Failed to find definition of SecDefaultAction for phase 2 in ${setup_conf_path}. Aborting"
136-
exit 1
157+
exit 3
137158
fi
138159
ed -s "${setup_conf_path}" <<EOF 2 > /dev/null
139160
/^SecDefaultAction.*phase:2/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Format: <legacy (0|1)>|<env var>|<rule ID>|<tx var name>|<test value>
2+
# The octothorpe (#) designates a comment, comments are ignored
3+
# See `.github/workflows/configure-rules-for-test.sh` for how the test value is used.
4+
5+
# Superceded by BLOCKING_PARANOIA
6+
true|PARANOIA|900000|paranoia_level|4
7+
false|BLOCKING_PARANOIA|900000|paranoia_level|4
8+
# Superceded by DETECTION_PARANOIA
9+
true|EXECUTING_PARANOIA|900001|executing_paranoia_level|4
10+
false|DETECTION_PARANOIA|900001|executing_paranoia_level|4
11+
false|ENFORCE_BODYPROC_URLENCODED|900010|enforce_bodyproc_urlencoded|0
12+
false|ANOMALY_INBOUND|900110|inbound_anomaly_score_threshold|6
13+
false|ANOMALY_OUTBOUND|900110|outbound_anomaly_score_threshold|6
14+
false|ALLOWED_METHODS|900200|allowed_methods|GET OPTIONS
15+
false|ALLOWED_REQUEST_CONTENT_TYPE|900220|allowed_request_content_type|application/json
16+
false|ALLOWED_REQUEST_CONTENT_TYPE_CHARSET|900280|allowed_request_content_type_charset|utf-8
17+
false|ALLOWED_HTTP_VERSIONS|900230|allowed_http_versions|1.1
18+
false|RESTRICTED_EXTENSIONS|900240|restricted_extensions|.exe/
19+
false|RESTRICTED_HEADERS_BASIC|900250|restricted_headers|/if/
20+
false|MAX_NUM_ARGS|900300|max_num_args|100
21+
false|ARG_NAME_LENGTH|900310|arg_name_length|200
22+
false|ARG_LENGTH|900320|arg_length|300
23+
false|TOTAL_ARG_LENGTH|900330|total_arg_length|400
24+
false|MAX_FILE_SIZE|900340|max_file_size|500
25+
false|COMBINED_FILE_SIZES|900350|combined_file_sizes|600
26+
false|VALIDATE_UTF8_ENCODING|900950|crs_validate_utf8_encoding|0
File renamed without changes.

0 commit comments

Comments
 (0)