The puzzle.opnsense Ansible Collection

Ansible is the de facto standard for Automation and IT-Orchestration. One of its strengths lies in the ability to expand its functionality by Ansible collections. At Puzzle ITC we use OPNsense as our firewall and routing tool. Further, we use state-of-the-art IT methods and write all of our configuration down as code in the form of Ansible plays and roles. That’s why we were looking for a way to manage our OPNsense appliances with Ansible.

OPNsense

OPNsense is an open-source firewall and routing platform stemming originally from the m0n0wall and pfsense projects. It runs on FreeBSD and provides a handy WebGUI for easy configuration. OPNsense is backed by a large community actively contributing to the project. After using pfsense for several years we switched to OPNsense because of changes in the licensing of the source code. Configuring OPNsense using the WebGUI is easy, however, this solution does not scale very well on infrastructures using multiple OPNsense instances. So how can we manage such infrastructures using Ansible?

source: opnsense.org

We searched the internet for an Ansible collection that fits our needs and stumbled upon AnsibleGuys very good collection for managing OPNsense which applies changes to OPNsense using its API. The problem here is that older versions of OPNsense don’t have an API yet and that not all changes to the OPNsense functionality are supported via API. That’s why we decided to start developing our own Ansible collection for managing OPNsense. Our goal is not to write an alternative to AnsibleGuy’s collection but to provide additional functionality and contribute to the Ansible community.

Ansible

We have been using Ansible for a long time now, and we are very experienced in writing Ansible roles and playbooks as well as automating workflows around Ansible runs. Modifying or adding functionality to Ansible, however, was not something we encountered as often. Fortunately, Ansible content is usually written in Python, a programming language we are familiar with. But how do you write an Ansible collection? This was uncharted waters to us. To get started with this task, great resources such as documentation and a repository template are provided by the Ansible community. This helped us a lot to get going:

puzzle.opnsense on Github.com

 

Problems encountered and solved

First, it was essential to understand how OPNsense manages and persists its configuration. Therefore, we started by studying the core of OPNsense and how changes affect the system. Changes done in the WebGUI could not only change the underlying XML configuration file but sometimes also trigger PHP functions which in turn could restart services.  We have also observed that different versions of OPNsense had their settings located at different paths inside the XML configuration file.

These insights led us to the realization, that we first need to think about two things: How do we provide a streamlined way to modify the XML configuration for all modules we intend to implement? And how do we support that across different OPNsense versions?

Consequently, we started by building a utility named  OPNsenseModuleConfig, which handles the previously mentioned issues for us. It does not only provide the module developer with a handy API that enables CRUD operations against the configuration file, but it also detects the OPNsense version of the system and handles the configuration accordingly. When the module is done modifying its configurations, it also knows how to apply these changes on the firewall.

This approach enables us to support multiple OPNsense versions while maintaining the same Ansible collection release. To ensure this multi-version compatibility, we use molecule tests, which start instances of different versions of OPNsense, run various testing playbooks against them, and check the sanity of the result.

Example

To demonstrate how the collection can handle different OPNsense versions, let’s have a look at the system_settings_logging module that already ships with the first release of the puzzle.opnsense collection. This module allows to configure the logging settings of an OPNsense system.

Let’s say you have an inventory that includes OPNsense instances using versions 22.7, 23.1, 23.7, and 24.1. Using Ansible you want to change the number of log files retained on the system. Such an ansible playbook could look like this:

- name: Manage OPNsense logging
  hosts: all
  tasks:
    - name: Set the number of logs to preserve 
      puzzle.opnsense.system_settings_logging:
        preserve_logs: 10

Running that playbook against our four instances results in the following Ansible run:

In addition to the Playbook report, we can also verify the changes in the WebGUIs:

Now OPNsense 24.1 introduced a setting for the max log file size which can be configured using the max_log_file_size_mb parameter. If you attempt to set the max_log_file_size_mb setting, you will encounter problems with earlier versions simply because it was not available. This is where version compatibility becomes crucial – the collection needs to know which setting is supported in which version to prevent misconfiguration by the user. In this specific example, when configuring the max_log_file_size_mb setting, the action will not be applied on versions earlier than 24.1 and the module will fail. To set it we could run this playbook:

- name: Manage OPNsense logging
  hosts: all
  tasks:
    - name: Set max log file size
      puzzle.opnsense.system_settings_logging:
        max_log_file_size_mb: 5

Since this setting is only supported on 24.1 we get this result:

As you can see in the output we get the feedback that the OPNsense version of a specific host does not support the setting we want to configure. This behavior of the collection enables engineers managing infrastructure to handle such cases in their playbooks and target specific OPNsense versions for specific configurations.

Release

We are proud to announce, that our Ansible collection puzzle.opnsense will be released on 20. April 2024. Let us know your thoughts and – if you like – contribute and help us grow the new collection!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert