`smallwebwaf` with no command now prints the commands and exits with status 2. The image runs rproxy, or servewaf with SMALLWEBWAF_COMMAND=servewaf. The passing-on code, its settings and its log fields and metric go. internal/proxy keeps the checks, answers, reports and own endpoints; its tests run through the real rproxy. The documents describe the pair. Judgement call: clients.json keeps token_refused, since state files refuse unknown fields. Deviation: script/gitea-requests sets SWWAF_LOG_REQUEST_HEADERS, to label requests. Model: opus-5-5
2.9 KiB
Rule files
The format of a rule file, and the default file the image ships. "Rule files" in
SPEC.md says how the files are read, watched and mounted, and
what each action leads to.
The format
A rule is a line of four fields separated by spaces or tabs: an id, a target, an
action and a regex. The regex runs to the end of the line. Blank lines and lines
starting with # are ignored.
# id target action regex
env-file path ban (?i)^/\.env(\.[a-z]+)?$
scanner-agent user_agent ban (?i)\b(sqlmap|nikto|nuclei|wpscan)\b
- The id is letters, digits,
-and_, unique across all files. The log line, the metrics, the alerts and a ban's notes name the rule by it. - The target is what the regex is matched against:
path: the path without the query;uri: the path and the query together;query: the query as sent;method,host,user_agentandreferer;header:<Name>: any one request header butHostandTransfer-Encoding.
- The action is
log,blockorban. - The regex is in Go's syntax, RE2. It matches anywhere in the target unless
anchored with
^and$.(?i)at its front makes it ignore case.
The default file
The image ships one file, share/rules.d/00-default.rules, installed as
/etc/smallwebwaf/rules.d/00-default.rules:
# 00-default.rules: probes no real visitor sends, anchored at the site root
# id target action regex
env-file path ban (?i)^/\.env(\.[a-z]+)?$
vcs-dir path ban (?i)^/\.(git|svn|hg|bzr)(/|$)
secrets-dir path ban (?i)^/\.(aws|ssh|docker|kube)/
secret-file path ban (?i)^/\.(htpasswd|htaccess|npmrc|netrc|pgpass|git-credentials|bash_history|DS_Store)$
editor-dir path ban (?i)^/\.(vscode|idea)/
backup-file path ban (?i)^/[^/]+\.(php(\.[a-z0-9]+|~)|sql(\.[a-z0-9]+)?)$
log-file path ban (?i)^/(debug|error|access)\.log$
compose-file path ban (?i)^/(docker-)?compose\.ya?ml$
php-shell path ban (?i)^/(shell|c99|r57|wso|alfa)\.php$
scanner-agent user_agent ban (?i)\b(sqlmap|nikto|nuclei|masscan|zgrab|wpscan)\b
path-traversal uri block (\.\./){2,}
empty-agent user_agent log ^$
A file of your own
servewaf reads the rule files in its own container. Rules of your own go in a
file named to sort after the default, such as 50-gitea.rules:
# 50-gitea.rules: WordPress probes, which gitea never serves
wp-probe path ban (?i)^/(wp-login\.php|xmlrpc\.php|wp-admin/)
A Dockerfile built on the smallwebwaf image, for servewaf to run from,
adds it:
COPY 50-gitea.rules /etc/smallwebwaf/rules.d/50-gitea.rules
Or mount it there. A path rule applies on every site behind that servewaf.