2018-01-30 05:40:13 -05:00
|
|
|
|
============
|
|
|
|
|
|
Architecture
|
|
|
|
|
|
============
|
|
|
|
|
|
|
|
|
|
|
|
The main focus of the OPNsense project is to provide a secure and
|
|
|
|
|
|
manageable platform for all your security applications. This means high
|
|
|
|
|
|
quality software that is easily maintainable and bug free. We think that
|
|
|
|
|
|
having a framework with a clear separation of concerns is essential to
|
|
|
|
|
|
achieving these goals.
|
|
|
|
|
|
|
|
|
|
|
|
OPNsense is a fork of pfSense ®. The existing code base of pfSense ®
|
|
|
|
|
|
does not always apply a clear separation of concerns. This means we need
|
|
|
|
|
|
a transition of the old (legacy) code base to a new one with a clear
|
|
|
|
|
|
separation. We have chosen a gradual transition to avoid a big bang and
|
|
|
|
|
|
keep the product feature rich while increasing code quality. This
|
|
|
|
|
|
enables simple addition of new features with less bugs and shorter time
|
|
|
|
|
|
to market.
|
|
|
|
|
|
|
|
|
|
|
|
This article describes how this will be achieved.
|
|
|
|
|
|
|
|
|
|
|
|
-----------------------
|
|
|
|
|
|
High-level architecture
|
|
|
|
|
|
-----------------------
|
|
|
|
|
|
|
2025-05-12 12:22:26 -04:00
|
|
|
|
|OPNsense Components.svg|
|
2018-01-30 05:40:13 -05:00
|
|
|
|
|
|
|
|
|
|
As the above model shows there are two main areas in our stack, the
|
|
|
|
|
|
frontend implemented with PHP/Phalcon and the backend using a custom
|
|
|
|
|
|
service built in Python.
|
|
|
|
|
|
|
|
|
|
|
|
The frontend handles user interaction and communicates with the backend
|
|
|
|
|
|
service. Applying configuration changes, monitoring and controlling
|
|
|
|
|
|
services offered by OPNsense is done by the backend service.
|
|
|
|
|
|
|
|
|
|
|
|
By using a fully configurable backend service, we avoid hardcoding of
|
|
|
|
|
|
services and ease the implementation of new features.
|
|
|
|
|
|
|
|
|
|
|
|
The frontend stack delivers a model driven approach to handle
|
|
|
|
|
|
configuration data, including automatic validation.
|
|
|
|
|
|
|
|
|
|
|
|
Manipulation of the core configuration file is handled at the frontend
|
|
|
|
|
|
model; the backend service is merely a consumer of the information
|
|
|
|
|
|
provided.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------------
|
|
|
|
|
|
Frontend Architecture
|
|
|
|
|
|
---------------------
|
|
|
|
|
|
|
2025-05-12 12:22:26 -04:00
|
|
|
|
|OPNsense frontend.svg|
|
2018-01-30 05:40:13 -05:00
|
|
|
|
|
|
|
|
|
|
Routing
|
|
|
|
|
|
-------
|
|
|
|
|
|
|
2024-10-26 11:42:26 -04:00
|
|
|
|
The OPNsense framework uses standard components where possible; the
|
|
|
|
|
|
first layer initializes routing, which handles requests and
|
2018-01-30 05:40:13 -05:00
|
|
|
|
delivers them to the controller based on its url. User content is
|
2024-10-26 11:42:26 -04:00
|
|
|
|
generated using Volt templates (using Phalcon), which are picked by the controller.
|
|
|
|
|
|
|
|
|
|
|
|
For a detailed description on the routing principles used in OPNsense, visit Frontend
|
2018-01-30 05:40:13 -05:00
|
|
|
|
:doc:`/development/frontend/routing`.
|
|
|
|
|
|
|
|
|
|
|
|
Controllers and views
|
|
|
|
|
|
---------------------
|
|
|
|
|
|
|
2024-10-26 11:42:26 -04:00
|
|
|
|
Not all parts of the framework are implemented, but by deriving
|
2018-01-30 05:40:13 -05:00
|
|
|
|
all controllers from the base in the OPNsense project it’s easy to
|
|
|
|
|
|
extend and adapt to future needs. Documentation on how to implement
|
|
|
|
|
|
controllers, with the use of views, can be found at :doc:`/development/frontend/controller`.
|
|
|
|
|
|
|
|
|
|
|
|
Models
|
|
|
|
|
|
------
|
|
|
|
|
|
|
2018-11-08 14:59:18 -05:00
|
|
|
|
All models are defined by a combination of a class and an XML containing
|
2018-01-30 05:40:13 -05:00
|
|
|
|
a (nested) definition. More information on defining models can be found
|
|
|
|
|
|
at the frontend model page :doc:`/development/frontend/models`.
|
|
|
|
|
|
|
|
|
|
|
|
Communication
|
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
|
|
|
|
Communication to the backend service is handled via a unix domain
|
|
|
|
|
|
socket.
|
|
|
|
|
|
|
|
|
|
|
|
Core system
|
|
|
|
|
|
-----------
|
|
|
|
|
|
|
2022-01-25 10:27:28 -05:00
|
|
|
|
The core of OPNsense is powered by an almost standard FreeBSD ® system
|
2018-01-30 05:40:13 -05:00
|
|
|
|
extended with packages using the pkg system. GIT is used for version
|
|
|
|
|
|
control and the repositories are split into 4 parts:
|
|
|
|
|
|
|
2022-01-25 10:27:28 -05:00
|
|
|
|
- src : the base (FreeBSD ®) system
|
2018-01-30 05:40:13 -05:00
|
|
|
|
- ports : the ports collection containing third party software
|
|
|
|
|
|
- core : the OPNsense gui and system configuration parts
|
|
|
|
|
|
- tools : easy tools to build OPNsense
|
|
|
|
|
|
|
|
|
|
|
|
.. TIP::
|
|
|
|
|
|
|
|
|
|
|
|
| For detailed information about the development workflow see:
|
|
|
|
|
|
| :doc:`OPNsense development workflow </development/workflow>`
|
|
|
|
|
|
|
2025-05-12 12:22:26 -04:00
|
|
|
|
|
|
|
|
|
|
--------------------
|
|
|
|
|
|
Backend Architecture
|
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Middleware
|
|
|
|
|
|
--------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|OPNsense backend.svg|
|
|
|
|
|
|
|
|
|
|
|
|
Configd, is responsible
|
|
|
|
|
|
for the core system interaction like starting and stopping of daemons
|
|
|
|
|
|
and generating configuration files for used services and applications.
|
|
|
|
|
|
|
|
|
|
|
|
The daemon listens on a unix domain socket and is capable of executing
|
|
|
|
|
|
actions defined in it’s own configuration directory
|
|
|
|
|
|
(“/usr/local/opnsense/service/conf/actions\_\*.conf”).
|
|
|
|
|
|
|
|
|
|
|
|
Currently there are four types of services implemented in the daemon:
|
|
|
|
|
|
|
|
|
|
|
|
- script : execute external (rc) scripts, report back success or failure
|
|
|
|
|
|
- script_output: execute external scripts, report back their contents, usually in json format
|
|
|
|
|
|
- stream_output: open streams to backend components
|
|
|
|
|
|
- inline : perform inline actions which are part of configd, most notable template generation and maintanance.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-05-26 09:57:00 -04:00
|
|
|
|
| Template generation is handled by Jinja2 (https://jinja.palletsprojects.com/en/stable/),
|
2025-05-12 12:22:26 -04:00
|
|
|
|
more information on how to create application templates can be found
|
|
|
|
|
|
at :doc:`/development/backend/templates`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Operating stages
|
|
|
|
|
|
--------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|OPNsense_operating_events.svg|
|
|
|
|
|
|
|
|
|
|
|
|
As all earlier layers describe how user input can be persisted and service information can be exchanged, we still
|
|
|
|
|
|
have a gap in our functionality when looking at the life of a firewall.
|
|
|
|
|
|
Until this point we have means to manually manage services and devices, including ways to collect information on demand,
|
|
|
|
|
|
but still in a rather isolated way (events triggered via the api layer).
|
|
|
|
|
|
|
|
|
|
|
|
This is where :doc:`syshooks <backend/autorun>` and :doc:`plugins <backend/legacy>` come into play,
|
|
|
|
|
|
these offer mechanisms to ensure different types of services can cooperate with the shared functionality available.
|
|
|
|
|
|
|
|
|
|
|
|
Between starting and stopping our firewall, we can identify three stages.
|
|
|
|
|
|
After power-on, we are booting, when this initial stage has been reached we end up with a running firewall with
|
|
|
|
|
|
all configured services available. During time, various events can happen, for example, someone pulling an network cable
|
|
|
|
|
|
and pushing it back in, this is the running stage.
|
|
|
|
|
|
Eventually, if someone decides to power-down or reboot the machine, we are entering shutdown stage, letting services know
|
|
|
|
|
|
we are ending operation.
|
|
|
|
|
|
|
|
|
|
|
|
Further details of each stage can be found in the :doc:`overview <backend/overview>` document.
|
|
|
|
|
|
|
|
|
|
|
|
To avoid endless dependency loops, services should prevent hooking on events that are not strictly required for operating.
|
|
|
|
|
|
For example, forcing a restart of a component when a network interface has changed is usually a sign of not
|
|
|
|
|
|
following best practices for designing network services.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. |OPNsense Components.svg| image:: images/OPNsense_Components.svg
|
2018-01-30 05:40:13 -05:00
|
|
|
|
:width: 600px
|
2025-05-12 12:22:26 -04:00
|
|
|
|
.. |OPNsense backend.svg| image:: images/OPNsense_backend.svg
|
|
|
|
|
|
:width: 500px
|
|
|
|
|
|
.. |OPNsense frontend.svg| image:: images/OPNsense_frontend.svg
|
2018-01-30 05:40:13 -05:00
|
|
|
|
:width: 600px
|
2025-05-12 12:22:26 -04:00
|
|
|
|
.. |OPNsense_operating_events.svg| image:: images/OPNsense_operating_events.svg
|
|
|
|
|
|
:width: 700px
|