Skip to content

audit_open_ports

Audit WAN-facing exposure: port forwards plus WAN accept rules and policies.

Side effects: None (read-only).

Cross-references port forwards with BOTH firewall models a controller can run, so a site on the Zone-Based Firewall is not reported as clean just because its legacy rulesets are empty (issue #112):

  • Active port forwards (DNAT into the LAN).
  • Legacy WAN_* accept rules, excluding the boilerplate established/related rule.
  • Zone-Based Firewall ALLOW policies whose source zone is the WAN (External) zone, excluding return-traffic allowances (connection_state_type == "RESPOND_ONLY"); the number excluded is reported. predefined policies are NOT excluded: the zone matrix implements “External to Internal: Allow” as a predefined “Allow All Traffic” policy, which is exactly the exposure this audit exists to surface, so each record carries predefined and the caller can tell matrix defaults from hand-written policies.

A controller mirrors each port forward into its own predefined WAN policy, so the same exposure can appear in both halves of this audit. Those carry duplicates_port_forward: true and are counted in port_forward_mirror_policies; they are tagged rather than dropped, and a port_forward policy whose origin matches no listed forward stays untagged, because it admits traffic the port-forward half does not show.

Returns {"port_forwards", "wan_accept_rules", "wan_accept_policies", "firewall_model", "wan_zone_resolved", "return_traffic_policies_excluded", "port_forward_mirror_policies", "summary"}. Each entry in wan_accept_policies carries source_zone, destination_zone and duplicates_port_forward alongside the controller’s own fields. firewall_model is legacy, zone-based, mixed or none from what the controller actually returned. If the zone-based read fails the audit still answers from the legacy side and carries the failure in firewall_policies_error rather than reporting a clean WAN. If policies exist but no zone could be identified as WAN, wan_zone_resolved is false and none are classified.

Useful as a “did I leave something open?” sanity check before publishing a service or shipping a config.

audit_open_ports(controller="default")
Parameter Type Required Default Description
controller string no “default” Name of the UniFi controller to target. Defaults to "default".