diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5c199eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# ---> Ansible +*.retry + diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..545f62a --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,24 @@ +common_development: false + +# common_fail2ban.conf + +common_fail2ban_loglevel: INFO +common_fail2ban_logtarget: /var/log/common_fail2ban.log +common_fail2ban_syslog_socket: auto +common_fail2ban_dbpurgeage: 1d +common_fail2ban_dbmaxmatches: 10 + +# jail.conf + +common_fail2ban_ignoreself: "true" +common_fail2ban_ignoreips: + - 127.0.0.1/8 + - ::1 + +common_fail2ban_findtime: 600 +common_fail2ban_maxretry: 5 +common_fail2ban_bantime: 600 +common_fail2ban_protocol: "tcp" + +common_fail2ban_jails: + - ssh.conf diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..294fc6b --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,12 @@ +# +# handlers: main +# +# +# @author Björn Hase +# + +- name: restart fail2ban + service: + name: fail2ban + enabled: yes + state: restarted diff --git a/playbooks/common-configure.yml b/playbooks/common-configure.yml new file mode 100644 index 0000000..8f791e5 --- /dev/null +++ b/playbooks/common-configure.yml @@ -0,0 +1,17 @@ +# +# playbook: configure +# +# +# @author Björn Hase +# + +- name: Install + hosts: all + become: yes + roles: + - common + + tasks: + - include_role: + name: common + tasks_from: configure-fail2ban.yml diff --git a/playbooks/common-install.yml b/playbooks/common-install.yml new file mode 100644 index 0000000..2baf770 --- /dev/null +++ b/playbooks/common-install.yml @@ -0,0 +1,21 @@ +# +# playbook: install basic stuff +# +# +# @author Björn Hase +# + +- name: Install + hosts: all + become: yes + roles: + - common + + tasks: + - include_role: + name: common + tasks_from: install.yml + + - include_role: + name: common + tasks_from: deployer.yml diff --git a/playbooks/common-update.yml b/playbooks/common-update.yml new file mode 100644 index 0000000..f8ee3ae --- /dev/null +++ b/playbooks/common-update.yml @@ -0,0 +1,18 @@ +# +# playbook: update +# +# +# @author Björn Hase +# + +- name: Update Server + hosts: all + become: yes + + roles: + - common + + tasks: + - include_role: + name: common + tasks_from: update.yml diff --git a/resources/fail2ban/filters/common-botssearch.conf b/resources/fail2ban/filters/common-botssearch.conf new file mode 100644 index 0000000..f1a32ca --- /dev/null +++ b/resources/fail2ban/filters/common-botssearch.conf @@ -0,0 +1,21 @@ +# Generic configuration file for -botsearch filters +# +# @source https://scalastic.io/en/ufw-fail2ban-nginx/#step-4-configuring-fail2bans-basic-rules +# + +[Init] + +# Block is the actual non-found directories to block +block = \/?(|||cgi-bin|mysqladmin)[^,]* + +# These are just convenient definitions that assist the blocking of stuff that +# isn't installed + +webmail = roundcube|(ext)?mail|horde|(v-?)?webmail +phpmyadmin = (typo3/|xampp/|admin/|)(pma|(php)?[Mm]y[Aa]dmin) +wordpress = wp-(login|signup|admin)\.php + +# DEV Notes: +# Taken from apache-botsearch filter +# +# Author: Frantisek Sumsal diff --git a/resources/fail2ban/filters/nginx-4xx.conf b/resources/fail2ban/filters/nginx-4xx.conf new file mode 100644 index 0000000..0076f66 --- /dev/null +++ b/resources/fail2ban/filters/nginx-4xx.conf @@ -0,0 +1,9 @@ +# block +# +# @source https://scalastic.io/en/ufw-fail2ban-nginx/#step-4-configuring-fail2bans-basic-rules +# + +[Definition] + +failregex = ^.*"(GET|PUT|POST).*" (403) .*$ +ignoreregex = .*(robots.txt|favicon.ico|css|htc|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip) diff --git a/resources/fail2ban/filters/nginx-botssearch.conf b/resources/fail2ban/filters/nginx-botssearch.conf new file mode 100644 index 0000000..d49419f --- /dev/null +++ b/resources/fail2ban/filters/nginx-botssearch.conf @@ -0,0 +1,20 @@ +# Fail2Ban filter to match web requests for selected URLs that don't exist +# Based on apache-botsearch filter +# +# Author: Frantisek Sumsal +# +# @source https://scalastic.io/en/ufw-fail2ban-nginx/#step-4-configuring-fail2bans-basic-rules + +[INCLUDES] + +# Load regexes for filtering +before = botsearch-common.conf + +[Definition] + +failregex = ^ \- \S+ \[\] \"(GET|POST|HEAD) \/ \S+\" 404 .+$ +^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: \, server\: \S*\, request: \"(GET|POST|HEAD) \/ \S+\"\, .*?$ +ignoreregex = +datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)? +^[^\[]*\[({DATE}) +{^LN-BEG} diff --git a/resources/fail2ban/filters/nginx-error-common.conf b/resources/fail2ban/filters/nginx-error-common.conf new file mode 100644 index 0000000..2fe4e3f --- /dev/null +++ b/resources/fail2ban/filters/nginx-error-common.conf @@ -0,0 +1,31 @@ +# Generic nginx error_log configuration items (to be used as interpolations) in other +# filters monitoring nginx error-logs +# +# @source https://scalastic.io/en/ufw-fail2ban-nginx/#step-4-configuring-fail2bans-basic-rules + +[DEFAULT] + +# Type of log-file resp. log-format (file, short, journal): +logtype = file + +# Daemon definition is to be specialized (if needed) in .conf file +_daemon = nginx + +# Common line prefixes (beginnings) which could be used in filters +# +# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces +# +# This can be optional (for instance if we match named native log files) + +__prefix = /__prefix> +__err_type = error +__prefix_line = %(__prefix)s\[%(__err_type)s\] \d+#\d+: \*\d+\s+ + +[lt_file] +__prefix = \s* + +[lt_short] +__prefix = \s*(?:(?!\[)\S+ %(_daemon)s\[\d+\]: [^\[]*)? + +[lt_journal] +__prefix = %(lt_short/__prefix)s diff --git a/resources/fail2ban/filters/nginx-forbidden.conf b/resources/fail2ban/filters/nginx-forbidden.conf new file mode 100644 index 0000000..3943a06 --- /dev/null +++ b/resources/fail2ban/filters/nginx-forbidden.conf @@ -0,0 +1,9 @@ +# targets attempts to access forbidden directories +# +# @source https://scalastic.io/en/ufw-fail2ban-nginx/#step-4-configuring-fail2bans-basic-rules +# + +[Definition] + +failregex = directory index of .+ is forbidden, client: , server: .+ +ignoreregex = diff --git a/resources/fail2ban/filters/nginx-http-auth.conf b/resources/fail2ban/filters/nginx-http-auth.conf new file mode 100644 index 0000000..4f00c75 --- /dev/null +++ b/resources/fail2ban/filters/nginx-http-auth.conf @@ -0,0 +1,44 @@ +# Blocking auth +# +# @source https://github.com/fail2ban/fail2ban/blob/master/config/filter.d/nginx-http-auth.conf +# + +# fail2ban filter configuration for nginx + +[INCLUDES] + +before = nginx-error-common.conf + +[Definition] + +mode = normal + +__err_type = <_ertp-> + +_ertp-auth = error +mdre-auth = ^%(__prefix_line)suser "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: , server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$ +_ertp-fallback = crit +mdre-fallback = ^%(__prefix_line)sSSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: + +_ertp-normal = %(_ertp-auth)s +mdre-normal = %(mdre-auth)s +_ertp-aggressive = (?:%(_ertp-auth)s|%(_ertp-fallback)s) +mdre-aggressive = %(mdre-auth)s + %(mdre-fallback)s + +failregex = > +ignoreregex = +datepattern = {^LN-BEG} +journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx + +# DEV NOTES: +# mdre-auth: +# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files +# Extensive search of all nginx auth failures not done yet. +# +# Author: Daniel Black + +# mdre-fallback: +# Ban people checking for TLS_FALLBACK_SCSV repeatedly +# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608 +# Author: Stephan Orlowsky diff --git a/resources/fail2ban/filters/nginx-limit-req.conf b/resources/fail2ban/filters/nginx-limit-req.conf new file mode 100644 index 0000000..e23548a --- /dev/null +++ b/resources/fail2ban/filters/nginx-limit-req.conf @@ -0,0 +1,46 @@ +# Fail2ban filter configuration for nginx :: limit_req +# used to ban hosts, that were failed through nginx by limit request processing rate +# +# Author: Serg G. Brester (sebres) +# +# To use 'nginx-limit-req' filter you should have `ngx_http_limit_req_module` +# and define `limit_req` and `limit_req_zone` as described in nginx documentation +# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html +# +# Example: +# +# http { +# ... +# limit_req_zone $binary_remote_addr zone=lr_zone:10m rate=1r/s; +# ... +# # http, server, or location: +# location ... { +# limit_req zone=lr_zone burst=1 nodelay; +# ... +# } +# ... +# } +# ... +# + +[Definition] + +# Specify following expression to define exact zones, if you want to ban IPs limited +# from specified zones only. +# Example: +# +# ngx_limit_req_zones = lr_zone|lr_zone2 +# +ngx_limit_req_zones = [^"]+ + +# Use following full expression if you should range limit request to specified +# servers, requests, referrers etc. only : +# +# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: , server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$ + +# Shortly, much faster and stable version of regexp: +failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: , + +ignoreregex = + +datepattern = {^LN-BEG} diff --git a/resources/fail2ban/filters/nginx-noscript.conf b/resources/fail2ban/filters/nginx-noscript.conf new file mode 100644 index 0000000..a7499b2 --- /dev/null +++ b/resources/fail2ban/filters/nginx-noscript.conf @@ -0,0 +1,19 @@ +# +# nginx-noscript +# +# + +[INCLUDES] + +# overwrite with apache-common.local if _apache_error_client is incorrect. +before = apache-common.conf + +[Definition] + +script = /\S*(?:php(?:[45]|[.-]cgi)?|\.asp|\.exe|\.pl|\bcgi-bin/) + +prefregex = ^%(_apache_error_client)s (?:AH0(?:01(?:28|30)|1(?:264|071)|2811): )?(?:(?:[Ff]ile|script|[Gg]ot) ).+$ + +failregex = ^(?:does not exist|not found or unable to stat):