111 lines
5.8 KiB
YAML
111 lines
5.8 KiB
YAML
---
|
|
# Port and address maps are name -> value so group_vars and host_vars levels
|
|
# merge into one map (hash_behaviour = merge); a null value drops an entry.
|
|
# Ports are numbers or "first-last" ranges.
|
|
firewall:
|
|
public:
|
|
tcp: {}
|
|
udp: {}
|
|
# Accepted only from the geo sets or the admin set.
|
|
geo:
|
|
tcp: {}
|
|
# Accepted on wt0 before the public zone is evaluated.
|
|
vpn:
|
|
tcp: {}
|
|
udp: {}
|
|
# tcp: ports accepted from the admin set alone, never from the geo sets.
|
|
admin:
|
|
tcp: {}
|
|
v4: {}
|
|
v6: {}
|
|
# Metrics scrapers: on wt0 only these source addresses reach the listed tcp
|
|
# ports (the vpn zone applies to every peer). Rendered only when both are set.
|
|
scrapers:
|
|
tcp: {}
|
|
v4: {}
|
|
v6: {}
|
|
# Interface names (nft wildcards allowed) whose traffic is trusted.
|
|
internal_ifaces: {}
|
|
# Guest bridges (Proxmox vmbr*): DHCP, router solicitations and the public
|
|
# zone only, never the geo ports.
|
|
guest_ifaces: {}
|
|
# Kubernetes ring: pod interfaces, and node NetBird IPs / pod CIDRs on wt0.
|
|
cluster:
|
|
ifaces: {}
|
|
v4: {}
|
|
v6: {}
|
|
# IPv4 port forwards: name -> {daddr, to, tcp: ports, udp: ports}, ports as in
|
|
# the maps above. Forwarded traffic passes the forward hook, not input.
|
|
dnat: {}
|
|
# IPv4 source NAT: name -> nft match, e.g. 'oifname "vmbr0"'.
|
|
masquerade: {}
|
|
# Forwarded traffic to guarded guests: name -> {ifaces, v4, v6}, where v4 and
|
|
# v6 are {daddr, tcp: ports, icmp: icmp or icmpv6 types}. Replies and traffic
|
|
# in on ifaces pass, the listed ports and types pass, the rest to daddr drops;
|
|
# traffic to other addresses is not filtered.
|
|
forward_guard: {}
|
|
# Limits on new inbound TCP connections per service, applied to the public and geo ports the host serves (input) and to
|
|
# DNATed traffic (forward: port forwards and Docker-published ports), after the admin, cluster, VPN, guest and internal
|
|
# sources and the public_ips of every inventory host (IPv4 per address, IPv6 per /64) are exempted. Each service has a tier
|
|
# per source (IPv4 /32, IPv6 /64) and a tier per range (IPv4 /24, IPv6 /48) at rate * range_factor. The excess drops with the log prefix fw-ratelimit: (log.ratelimit_rate).
|
|
# name -> {ports: port or list, rate: connections per `per`, per: second|minute (minute), burst: connections (2 * rate),
|
|
# range_factor_v4, range_factor_v6: override the factors below}; null drops a service, a service is idle unless a port is served.
|
|
# Values are 3x the highest legitimate rate seen, with a floor of 12 per minute (3x four connections per minute) where
|
|
# there is no or too little history; the measurement is noted at each service.
|
|
ratelimit:
|
|
range_factor:
|
|
v4: 6
|
|
v6: 3
|
|
services:
|
|
# 14 days of sshd Accepted lines in VictoriaLogs (all hosts, per host and source, /64 and /24 grouped): at most 8 per
|
|
# minute and 4 per 10 seconds from one address or /64 (Ansible runs), 22 per 10 minutes.
|
|
ssh:
|
|
ports: 22
|
|
rate: 24
|
|
# 14 days of Traefik access logs of the cluster: distinct client ports of one source within a minute, which bounds the
|
|
# new connections, at most 51 (IPv4) and 58 (IPv6 /64); 16 per second at most. Applies to the host ports 80 and 443.
|
|
web:
|
|
ports: [80, 443]
|
|
rate: 180
|
|
# Kernel log of dropped inbound packets (fw-in-drop: ), rate-limited connections (fw-ratelimit: ) 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"
|
|
# Shared by all rate-limited connections (fw-ratelimit: ), one limit.
|
|
ratelimit_rate: "5/second burst 30 packets"
|
|
out_rate: "6/minute burst 5 packets"
|
|
# Lets the kernel log the nft log statements of container network
|
|
# namespaces (LXC guests) into the host kernel log.
|
|
all_netns: false
|
|
# Shared by the Spamhaus (fw-spamhaus-in: , fw-spamhaus-out: ), FireHOL (fw-firehol-in: , fw-firehol-out: ) and scanner (fw-scanners-in: ) chains, one limit each.
|
|
spamhaus_rate: "6/minute burst 10 packets"
|
|
# Spamhaus DROP, DROPv6 and ASN-DROP: traffic from the listed networks drops
|
|
# (input, forward), traffic to them is rejected (output, forward). The sets
|
|
# are refreshed daily by nft-host-spamhaus.
|
|
spamhaus: true
|
|
# FireHOL level1 (IPv4): treated like the Spamhaus lists, with the prefixes
|
|
# fw-firehol-in: and fw-firehol-out: and the same log limit. Entries in
|
|
# private or reserved space and ones holding an address of the host are left
|
|
# out. Refreshed daily by nft-host-firehol.
|
|
firehol: true
|
|
# Internet-wide scanners (Censys, Shodan, ONYPHE, Shadowserver, ...), IPv4
|
|
# and IPv6: the cidr files of github.com/OpenFilters/internet-scanners
|
|
# (Unlicense). Inbound traffic from the listed networks drops (input,
|
|
# forward) once the established rule has passed; outbound traffic is never
|
|
# filtered. Log prefix fw-scanners-in: with the Spamhaus log limit, which
|
|
# CrowdSec whitelists. Entries in private or reserved space, overlapping the
|
|
# admin, scraper and cluster sets, the CrowdSec whitelist or the public_ips
|
|
# of any host, and ones holding an address of the host are left out
|
|
# (/etc/nft-host-scanners.allowlist). Refreshed daily by nft-host-scanners.
|
|
scanners: true
|
|
# 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]
|
|
rollback_seconds: 120
|
|
# name -> shell command that has to exit 0 through the new rule set before the
|
|
# rollback is disarmed; retried for a quarter of the rollback window.
|
|
confirm: {}
|