AZiT

Policy is highlighted; its page is below.

Policy

Everything is blocked and logged unless a rule says otherwise. Each network may reach the internet; no network may reach another, except for a handful of named exceptions.

Principles#

  • Default deny, logged. The first rule drops everything and logs it, so every surprise shows up in the SIEM.
  • Every rule has a label. Logs say allow_trusted_kodi or drop_all, not "rule 214", and the name survives when rules are renumbered.
  • Names, not addresses. Rules refer to tables such as <admin_hosts> and <kodi>; an address changes in one place.
  • Allowed connections are logged too, so the SIEM can answer who talked to what. Rules that only produce heartbeat noise are the exception.
  • Known noise is dropped quietly. Broadcast discovery and late TCP packets would otherwise bury the events that matter.

What may cross between networks#

FromToPortsWhy
Admin hostsCluster nodes, controller, access point, media server22/tcpSSH management
Admin hostsController11443/tcp, WebRTCController web interface
Admin hostsKubernetes API6443/tcpkubectl and Flux
Admin hostsIngress443/tcpWeb interfaces
Trusted Wi-FiHome Assistant8123/tcpThe phone app
Trusted Wi-FiMedia server18080, 9090/tcpRemote control
Home AssistantIoTanyControlling devices
Access pointController8080/tcp, 3478, 5514/udpInform, STUN, device logs
FirewallSIEM6514/tcpLogs over TLS

Guests appear in no row on purpose: they get an address, DNS and the internet, and nothing else.

In the configuration#

/etc/pf.conf
set block-policy drop
set skip on lo
trusted = "vlan10"
table <internal_nets> const { 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24 \
    192.168.4.0/24 192.168.5.0/24 192.168.10.0/24 \
    192.168.20.0/24 192.168.30.0/24 }
table <kodi> const { 192.168.4.10 }
# Everything not allowed below is dropped and logged
block log all label "drop_all"
# Discovery chatter: dropped without logging, so alerts stay meaningful
block in quick on $internal to { 255.255.255.255 224.0.0.0/4 } \
    label "drop_broadcast_multicast"
# Phones may use the media server's remote control
pass in log quick on $trusted inet proto tcp from $trusted:network \
    to <kodi> port { 18080 9090 } label "allow_trusted_kodi"
# Each network may reach the internet, never another network
pass in log quick on $trusted inet from $trusted:network \
    to ! <internal_nets> label "allow_trusted_internet"
  • quick stops evaluation at the first match, so the order reads top to bottom like a checklist.
  • to ! <internal_nets> is how "internet only" is expressed: anywhere except the home networks.