OPNsense Firewall Categories

This role manages firewall rule categories on OPNsense via the REST API. Categories help organize and visualize firewall rules by grouping them with colored labels.

Ansible DNS HTTPS JSON OPNsense REST API SSL TLS

OPNsense Firewall Categories Role

Overview

This role manages firewall rule categories on OPNsense via the REST API. Categories help organize and visualize firewall rules by grouping them with colored labels. The role provides full lifecycle management: creating new categories, updating existing ones when configuration changes, and deleting orphaned categories that exist on the firewall but are no longer defined in the vars files.

Purpose

  • Rule Organization: Group related firewall rules by purpose (DNS, Web, Management, etc.)
  • Visual Identification: Color-coded categories for easy identification in the UI
  • Code as Configuration: Define categories in YAML instead of GUI
  • Full Lifecycle Management: Create, update, and delete categories
  • Idempotent: Safe to run multiple times using name-based idempotency
  • Automatic Cleanup: Removes orphaned categories not defined in vars

Requirements

  • Ansible 2.9 or higher
  • OPNsense firewall with API access enabled
  • API key and secret stored in Ansible Vault
  • Network connectivity to OPNsense (VLAN10)
  • OPNsense user with firewall category permissions

What are Firewall Categories?

Categories are labels that can be assigned to firewall rules:

  • Each category has a name and color
  • Rules can belong to multiple categories
  • Categories appear as colored tags in the OPNsense firewall rules UI
  • Helps filter and organize large rule sets

Benefits:

  • Visual organization of firewall rules
  • Quick filtering by category in the UI
  • Group related rules (all DNS rules, all management rules, etc.)
  • Easier auditing and documentation

Role Variables

Required Variables

VariableRequiredDescription
vault_opnsense_bjoffrey_user_api_keyYesOPNsense API key (in vault)
vault_opnsense_bjoffrey_user_api_secretYesOPNsense API secret (in vault)
opnsense_firewall_categories_listYesList of categories to create

Optional Variables

VariableDefaultDescription
opnsense_firewall_categories_validate_certstrueValidate SSL certificates

Category Structure

Each category in the list has these fields:

opnsense_firewall_categories_list:
  - name: "DNS"           # Category name (unique identifier)
    color: "3498db"       # Hex color without # (blue)
    auto: "0"             # Auto-assign matching rules (0=no, 1=yes)

Field descriptions:

FieldRequiredDefaultDescription
nameYes-Category name (unique, used for idempotency)
colorYes-Hex color code without #
autoNo"0"Auto-assign rules matching category name

Common Colors

ColorHex CodeUse Case
Blue3498dbDNS, network services
Green2ecc71Allow rules, web traffic
Purple9b59b6Management, admin access
Orangef39c12Monitoring, logging
Rede74c3cBlock rules, security
Teal1abc9cVPN, encrypted traffic
Gray95a5a6Miscellaneous

Dependencies

This role has no dependencies on other Ansible roles, but requires:

  • OPNsense firewall with API enabled
  • API key with firewall category permissions
  • Ansible Vault for storing API credentials

Example Playbook

Basic Usage

---
- name: Configure OPNsense Firewall Categories
  hosts: mint-vm
  gather_facts: false

  vars_files:
    - ../../roles/opnsense_firewall_categories/vars/categories.yml

  tasks:
    - name: Configure firewall categories on OPNsense
      ansible.builtin.include_role:
        name: opnsense_firewall_categories

Inline Categories

---
- name: Configure Firewall Categories
  hosts: mint-vm
  gather_facts: false

  vars:
    opnsense_firewall_categories_list:
      - name: "DNS"
        color: "3498db"
      - name: "Web"
        color: "2ecc71"
      - name: "Management"
        color: "9b59b6"
      - name: "Block"
        color: "e74c3c"

  roles:
    - opnsense_firewall_categories

What This Role Does

  1. Fetches existing categories via /api/firewall/category/searchItem

  2. Builds name → UUID mapping for idempotency

  3. Creates new categories (name doesn’t exist) via /api/firewall/category/addItem

  4. Updates existing categories (name exists but color/auto differ) via /api/firewall/category/setItem

  5. Deletes orphaned categories (exist on firewall but not in vars) via /api/firewall/category/delItem

  6. Displays summary of configured categories

Note: Categories are applied immediately - no reconfigure step needed.

OPNsense API Endpoints

Search Categories

GET /api/firewall/category/searchItem
Authorization: Basic (API key:secret)

Response:

{
  "rows": [
    {
      "uuid": "f64f42ec-4c1d-4697-8d75-5b476bff755f",
      "name": "DNS",
      "color": "3498db",
      "auto": "0"
    }
  ],
  "rowCount": 1,
  "total": 1,
  "current": 1
}

Add Category

POST /api/firewall/category/addItem
Authorization: Basic (API key:secret)
Content-Type: application/json

Request body:

{
  "category": {
    "name": "DNS",
    "color": "3498db",
    "auto": "0"
  }
}

Response:

{
  "result": "saved",
  "uuid": "f64f42ec-4c1d-4697-8d75-5b476bff755f"
}

Update Category

POST /api/firewall/category/setItem/{uuid}
Authorization: Basic (API key:secret)
Content-Type: application/json

Request body: Same as addItem

Delete Category

POST /api/firewall/category/delItem/{uuid}
Authorization: Basic (API key:secret)

Response:

{
  "result": "deleted"
}

Idempotency

Role uses name-based idempotency:

  • Each category has a unique name
  • Names map to UUIDs on the firewall
  • Create: New name → creates category
  • Update: Existing name with changed color/auto → updates category
  • Delete: Name on firewall but not in vars → deletes category
  • Only applies configuration if changes were made
  • Safe to run repeatedly

Important: Removing a category from your vars file will delete it from the firewall on the next run.

Using Categories in Firewall Rules

After creating categories, reference them in firewall rules:

# In firewall rule definition
opnsense_firewall_rules:
  vlan10:
    - sequence: "100"
      action: "pass"
      interface: "opt1"
      protocol: "UDP"
      destination_port: "53"
      categories: "DNS"  # Reference category by name
      description: "Allow DNS"

Multiple categories can be assigned:

categories: "DNS,Management"

Security Considerations

  • API Credentials: Stored in Ansible Vault
  • HTTPS: Uses SSL/TLS for API calls
  • Basic Auth: API key/secret authentication
  • Certificate Validation: Enabled by default
  • Automatic Deletion: Be careful when removing categories from vars

Tags

This role does not define any tags. Use playbook-level tags if needed:

- hosts: mint-vm
  roles:
    - opnsense_firewall_categories
  tags:
    - opnsense
    - firewall
    - categories

Notes

  • become: false recommended (no root needed for API calls)
  • Categories are identified by name (must be unique)
  • Removing a category from vars will delete it from the firewall
  • Categories can be assigned to rules after creation
  • Color is specified as hex without the # prefix

Troubleshooting

”Authentication failed” errors

Cause: Invalid API key/secret

Solution: Verify credentials in vault.

Category not appearing

Cause: Reconfigure not called or failed

Solution: Check role output for reconfigure task, or manually apply via OPNsense UI.

Cannot delete category

Cause: Category is in use by firewall rules

Solution: Remove category from rules first, then delete.

Best Practices

  1. Meaningful names: Use descriptive category names
  2. Consistent colors: Establish a color scheme for your organization
  3. Document purpose: Use categories that describe rule purpose
  4. Review before running: Removing categories from vars deletes them
  5. Version control: Store category definitions in git

This role is often used with:

  • opnsense_firewall: Create rules using categories
  • opnsense_aliases: Create aliases for use in rules
  • opnsense_source_nat: Configure SNAT rules
  • opnsense_destination_nat: Configure DNAT rules

License

MIT

Author

Created for homelab infrastructure management.