host_firewall: log dropped inbound packets with a global rate limit and reject outbound TCP 25 except on the mail host
This commit is contained in:
@@ -45,6 +45,14 @@ firewall:
|
||||
# traffic to other addresses is not filtered.
|
||||
forward_guard: {}
|
||||
ssh_rate_limit: "10/minute burst 5 packets"
|
||||
# Kernel log of dropped inbound packets (fw-in-drop: ) and of rejected
|
||||
# outbound mail (fw-out-reject: ), read from the journal by CrowdSec. Each
|
||||
# rate is one limit shared by all matching packets.
|
||||
log:
|
||||
in_rate: "5/second burst 30 packets"
|
||||
out_rate: "6/minute burst 5 packets"
|
||||
# Reject outbound TCP 25; the mail group turns it off.
|
||||
block_smtp_out: true
|
||||
# EU-27 plus CH, NO, GB, IS, LI (ipdeny country codes). Empty leaves the geo
|
||||
# ports to the admin set; a load peaks at about 60 MB of kernel memory, too much for a 1 GB host.
|
||||
geo_countries: [at, be, bg, hr, cy, cz, dk, ee, fi, fr, de, gr, hu, ie, it, lv, lt, lu, mt, nl, pl, pt, ro, sk, si, es, se, ch, "no", gb, is, li]
|
||||
|
||||
@@ -50,7 +50,7 @@ table inet host {
|
||||
type filter hook input priority filter; policy drop;
|
||||
|
||||
ct state established,related accept
|
||||
ct state invalid drop
|
||||
ct state invalid jump drop_log
|
||||
iif lo accept
|
||||
|
||||
icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } accept
|
||||
@@ -85,8 +85,31 @@ table inet host {
|
||||
# VPN peers get the vpn ports, then everything public.
|
||||
iifname "wt0" jump vpn
|
||||
jump public
|
||||
|
||||
# Broadcasts and multicasts are never scans; they stay out of the log.
|
||||
meta pkttype { broadcast, multicast } drop
|
||||
jump drop_log
|
||||
}
|
||||
|
||||
# A single rule makes the limit global: a flood logs at the limit and the
|
||||
# rest drops silently. The kernel log line has the iptables LOG fields that
|
||||
# the CrowdSec iptables-logs parser reads.
|
||||
chain drop_log {
|
||||
limit rate {{ firewall.log.in_rate }} log prefix "fw-in-drop: "
|
||||
drop
|
||||
}
|
||||
{% if firewall.block_smtp_out %}
|
||||
|
||||
# Outbound mail goes through the mail host only. Loopback stays open for a
|
||||
# local MTA; the log lines carry OUT=, which CrowdSec does not count as a scan.
|
||||
chain output {
|
||||
type filter hook output priority filter; policy accept;
|
||||
|
||||
oifname != "lo" tcp dport 25 limit rate {{ firewall.log.out_rate }} log prefix "fw-out-reject: "
|
||||
oifname != "lo" tcp dport 25 reject with tcp reset
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
chain vpn {
|
||||
{% if list(scrapers.tcp) %}
|
||||
{% if list(scrapers.v4) %}
|
||||
@@ -133,9 +156,9 @@ table inet host {
|
||||
{% endif %}
|
||||
ip saddr @admin_v4 accept
|
||||
ip6 saddr @admin_v6 accept
|
||||
tcp dport 22 ct state new update @ssh_meter_v4 { ip saddr limit rate over {{ firewall.ssh_rate_limit }} } drop
|
||||
tcp dport 22 ct state new update @ssh_meter_v4 { ip saddr limit rate over {{ firewall.ssh_rate_limit }} } jump drop_log
|
||||
# One IPv6 client usually holds a whole /64.
|
||||
tcp dport 22 ct state new update @ssh_meter_v6 { ip6 saddr & ffff:ffff:ffff:ffff:: limit rate over {{ firewall.ssh_rate_limit }} } drop
|
||||
tcp dport 22 ct state new update @ssh_meter_v6 { ip6 saddr & ffff:ffff:ffff:ffff:: limit rate over {{ firewall.ssh_rate_limit }} } jump drop_log
|
||||
{% if firewall.geo_countries %}
|
||||
ip saddr @geo_v4 accept
|
||||
ip6 saddr @geo_v6 accept
|
||||
@@ -162,7 +185,7 @@ table inet host {
|
||||
{% if list(zone.icmp) %}
|
||||
{{ match }} {{ icmp }} type { {{ list(zone.icmp) }} } accept
|
||||
{% endif %}
|
||||
{{ match }} drop
|
||||
{{ match }} jump drop_log
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user