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.
|
# traffic to other addresses is not filtered.
|
||||||
forward_guard: {}
|
forward_guard: {}
|
||||||
ssh_rate_limit: "10/minute burst 5 packets"
|
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
|
# 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.
|
# 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]
|
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;
|
type filter hook input priority filter; policy drop;
|
||||||
|
|
||||||
ct state established,related accept
|
ct state established,related accept
|
||||||
ct state invalid drop
|
ct state invalid jump drop_log
|
||||||
iif lo accept
|
iif lo accept
|
||||||
|
|
||||||
icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } 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.
|
# VPN peers get the vpn ports, then everything public.
|
||||||
iifname "wt0" jump vpn
|
iifname "wt0" jump vpn
|
||||||
jump public
|
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 {
|
chain vpn {
|
||||||
{% if list(scrapers.tcp) %}
|
{% if list(scrapers.tcp) %}
|
||||||
{% if list(scrapers.v4) %}
|
{% if list(scrapers.v4) %}
|
||||||
@@ -133,9 +156,9 @@ table inet host {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
ip saddr @admin_v4 accept
|
ip saddr @admin_v4 accept
|
||||||
ip6 saddr @admin_v6 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.
|
# 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 %}
|
{% if firewall.geo_countries %}
|
||||||
ip saddr @geo_v4 accept
|
ip saddr @geo_v4 accept
|
||||||
ip6 saddr @geo_v6 accept
|
ip6 saddr @geo_v6 accept
|
||||||
@@ -162,7 +185,7 @@ table inet host {
|
|||||||
{% if list(zone.icmp) %}
|
{% if list(zone.icmp) %}
|
||||||
{{ match }} {{ icmp }} type { {{ list(zone.icmp) }} } accept
|
{{ match }} {{ icmp }} type { {{ list(zone.icmp) }} } accept
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ match }} drop
|
{{ match }} jump drop_log
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user