Skip to content

The lockout guard

Intrusion prevention has one failure mode that matters most: banning yourself. A mistyped passphrase, a script with a wrong key, or a scanner behind the same address as your office is enough.

security_allowlist is the guard against it. It is a list of IP addresses or CIDRs that both fail2ban (as ignoreip) and crowdsec (through a whitelist parser) never ban.

Put your management networks here, such as your VPN or private network.

Define it for all hosts, for example in group_vars/all:

group_vars/all.yml
security_allowlist:
- 192.0.2.0/24 # office
- 100.64.0.0/10 # Tailscale, IPv4
- "fd7a:115c:a1e0::/48" # Tailscale, IPv6
- 2001:db8:1234::/48 # IPv6 range of the office

Quote IPv6 values that start with letters or contain :: at the start, so YAML does not misread them.

Each role adds its own list on top:

VariableRoleMeaning
fail2ban_ignoreipfail2banFurther addresses never banned. Default: loopback (127.0.0.1/8, ::1).
crowdsec_allowlistcrowdsecFurther addresses never banned on this host.

The effective list of a role is security_allowlist plus its own list, without duplicates.

Both roles stop the run if an entry is not an IP address or CIDR. The check is deliberately simple: it catches typos, but does not validate every IPv6 spelling. A bad value therefore fails early instead of producing a ban list that silently excludes nothing.

  • An empty list protects nothing. The default is []. Setting it is the first thing to do before you apply either role.
  • Allowlisting is not authentication. A listed address is never banned, but is still subject to sshd’s own rules. A listed address that an attacker controls is a hole; keep the list to networks you control.
  • Mind the networks you use to reach the hosts. If you connect through a VPN or a bastion host, list that network, not your home address.
  • The list is read when a role runs. Changing it takes effect at the next run of the roles.