Skip to content

Instantly share code, notes, and snippets.

@biophonc
Created April 28, 2022 11:45
Show Gist options
  • Save biophonc/5f718a87a3fdbfb8dc1d7f0a32323e5a to your computer and use it in GitHub Desktop.
Save biophonc/5f718a87a3fdbfb8dc1d7f0a32323e5a to your computer and use it in GitHub Desktop.
Fail2Ban filter for structured logs from Caddy for WordPress login atemps
#
# matches structured logs emitted by caddy 2.5.0+
# requires Fail2Ban v0.11.0+ because of the unix timestamp aka "Epoch"
#
# test regex: {"level":"info","ts":1651134734.5565865,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"98.42.231.11","remote_port":"40578","proto":"HTTP/1.1","method":"POST","host":"redacted.foo","uri":"/wp-login.php","headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"User-Agent":["Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36"],"Content-Length":["88"],"Content-Type":["application/x-www-form-urlencoded"],"Cookie":[]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","server_name":"kgparl.de"}},"user_id":"","duration":0.214159319,"size":2739,"status":200,"resp_headers":{"Content-Encoding":["gzip"],"Alt-Svc":["h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"],"Cache-Control":["no-cache, must-revalidate, max-age=0, no-store"],"Content-Type":["text/html; charset=UTF-8"],"X-Frame-Options":["SAMEORIGIN"],"Vary":["Accept-Encoding"],"Server":["Caddy"],"Set-Cookie":[],"Expires":["Wed, 11 Jan 1984 05:00:00 GMT"]}}
# Important log entries
# "ts":1651134734.5565865
# "remote_ip":"98.42.231.11"
# "method":"POST", <- only post requests
# "uri":"/wp-login.php", <- the requested uri
# "status":200, <- only http status code 200. a successfull login will return a 302
[INCLUDES]
before = common.conf
[Definition]
datepattern = (?:\"ts\":({Epoch})),
str_start = ^\{[^{]+{
str_end = [^}}]+}}$
ip = (?:"remote_ip":"<HOST>")
method = (?:"method":"POST")
uri = (?:"uri":"/wp-login.php")
status = (?:"status":200,)
failregex = %(str_start)s%(ip)s.+?%(method)s.+?%(uri)s.+?%(status)s%(str_end)s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment