host_firewall: drop inbound traffic from internet-wide scanners (OpenFilters internet-scanners), v4 and v6, daily refresh

This commit is contained in:
2026-10-25 12:12:27 +00:00
parent 38d1ac6ced
commit c50c32059e
7 changed files with 309 additions and 3 deletions
+26 -1
View File
@@ -38,6 +38,9 @@ include "/etc/nftables.d/host-spamhaus.nft"
{% if firewall.firehol %}
include "/etc/nftables.d/host-firehol.nft"
{% endif %}
{% if firewall.scanners %}
include "/etc/nftables.d/host-scanners.nft"
{% endif %}
table inet host {
{{ addr_set('admin_v4', 'ipv4_addr', firewall.admin.v4) }}
@@ -69,6 +72,13 @@ table inet host {
{% endif %}
ct state established,related accept
{% if firewall.scanners %}
# After the established rule: only inbound connections of scanners drop.
ip saddr @scanners_v4 jump scanners_in
ip6 saddr @scanners_v6 jump scanners_in
{% endif %}
ct state invalid jump drop_log
iif lo accept
@@ -143,6 +153,16 @@ table inet host {
reject
}
{% endif %}
{% if firewall.scanners %}
# Own limit and prefix, so scanners use up neither the fw-in-drop budget
# nor the one of the blocklists. CrowdSec whitelists the prefix: scans of
# these networks are known and need no decision.
chain scanners_in {
limit rate {{ firewall.log.spamhaus_rate }} log prefix "fw-scanners-in: "
drop
}
{% endif %}
{% if firewall.block_smtp_out or blocklists %}
# Outbound mail goes through the mail host only. Loopback stays open for a
@@ -220,7 +240,7 @@ table inet host {
ip6 saddr @geo_v6 accept
{% endif %}
}
{% if forward_guard or blocklists %}
{% if forward_guard or blocklists or firewall.scanners %}
chain forward {
type filter hook forward priority filter; policy accept;
@@ -236,6 +256,11 @@ table inet host {
ip saddr @firehol_v4 jump firehol_in
ip daddr @firehol_v4 jump firehol_out
{% endif %}
{% if firewall.scanners %}
ct state new ip saddr @scanners_v4 jump scanners_in
ct state new ip6 saddr @scanners_v6 jump scanners_in
{% endif %}
{% for guard in forward_guard %}
# {{ guard.key }}
@@ -0,0 +1,11 @@
# {{ ansible_managed }}
{% set maps = [
(crowdsec | default({}, true)).whitelist | default({}, true),
firewall.admin.v4 | default({}, true), firewall.admin.v6 | default({}, true),
firewall.scrapers.v4 | default({}, true), firewall.scrapers.v6 | default({}, true),
firewall.cluster.v4 | default({}, true), firewall.cluster.v6 | default({}, true)] %}
{% set entries = (maps | map('dict2items') | sum(start=[]) | rejectattr('value', 'none') | map(attribute='value') | map('string') | list
+ groups['all'] | map('extract', hostvars, 'public_ips') | select('defined') | flatten) | unique %}
{% for entry in entries %}
{{ entry }}
{% endfor %}