ansible-debian-firewall

DOCUMENTATION

Architecture

How the Debian firewall roles fit together on fw1 and fw2.

The base system

The base role installs the Debian packages and baseline services used by the appliance. It enables security upgrades, local syslog, SSH hardening and optional time and monitoring services.

Interfaces and networks

The network role configures physical interfaces, VLAN subinterfaces, bonds, LACP, addresses, routes and kernel forwarding. Switching remains on the dedicated switch; the firewall routes between the networks it owns.

Filtering and NAT

nftables starts with closed input and forward policies. Explicit rules allow management, routing, VPN, published web and mail services, then postrouting handles the required private network masquerade.

Routing and VPN

FRR provides OSPF or BGP when dynamic routing is required. WireGuard and strongSwan manage encrypted connectivity, while the firewall rules limit which tunnel networks can reach each other.

High availability

Keepalived owns the service VIP and Conntrackd synchronizes connection state. fw1 and fw2 must have matching interfaces and policy, with only the active node answering for the VIP.

Traffic flow

Internet traffic enters through the WAN interface, is classified by nftables and is forwarded only when a destination group and service rule match. Return traffic is handled by conntrack, while masquerade is applied only to private networks that need Internet access.

Packet path

Incoming traffic is DNATed to a destination host before the forward chain evaluates the translated destination. The input chain protects addresses owned by the firewall itself. The forward chain protects traffic crossing between WAN, LAN, VPN and transit networks.

Internet -> Proxmox NAT -> VIP 10.10.10.2
VIP -> fw1 or fw2 -> nftables forward
forward -> backend host -> conntrack reply

Routing ownership

FRR installs dynamic routes through zebra. OSPF should be accepted only on the internal routing interface, never on the WAN transit. Keepalived owns the service VIP, while FRR owns routes and next hops. Do not use VRRP as a replacement for dynamic routing.

Stateful HA

Conntrackd synchronizes connection tracking state, but it does not synchronize every application session or VPN handshake. Test failover with active TCP connections, NAT sessions and VPN traffic. The standby must have the same nftables policy before it becomes active.

Detailed implementation notes

Component responsibilities

The base role owns operating-system hygiene and service prerequisites. The network role owns link state, addresses, VLANs, bonds and forwarding. nftables owns packet decisions and NAT. VPN roles create encrypted interfaces, FRR owns dynamic route calculation, Keepalived owns VIP ownership and Conntrackd copies connection state. Keeping these boundaries clear makes incident analysis faster.

Traffic lifecycle

A packet enters on a physical, bonded or VLAN interface, is classified by nftables, may be translated by DNAT or masquerade, and is then routed toward its destination. Return traffic is matched through conntrack. A successful tunnel or route does not bypass firewall policy: every path still needs an explicit security decision.

Failure domains

Network configuration, filtering, routing, VPN negotiation and HA election fail differently. Check the layer that owns the symptom instead of changing several variables at once. Interface state points to network, missing paths to FRR or static routes, dropped packets to nftables, and duplicate VIPs to Keepalived or the underlying L2 network.

Role order in site.yml

- hosts: firewalls
  become: true
  roles:
    - base
    - network
    - nftables
    - wireguard
    - strongswan
    - frr
    - keepalived
    - conntrackd

The order ensures that interfaces and forwarding exist before nftables, VPN, routing and HA services are started.

Packet path

WAN eth0
  -> nftables prerouting
  -> DNAT to nftables_hosts.web
  -> nftables forward
  -> LAN eth1
  -> 10.20.10.7:443
nft list chain inet firewall prerouting
nft list chain inet firewall forward
tcpdump -ni eth0 port 443
tcpdump -ni eth1 host 10.20.10.7