Professional Documents
Culture Documents
OPNsense
OPNsense
OPNsense
documentation!
OPNsense® [https://opnsense.org] is an open source, easy-to-use and easy-to-build
FreeBSD based firewall and routing platform.
Table of Contents
About the Fork
Debunking the Myths
So why did we fork?
First Release
Future Development & Focus
Introduction
Welcome to OPNsense’s documentation!
Mission Statement
Feature set
OPNsense Core Features
1
User Manual
Hardware sizing & setup
Initial Installation & Configuration
Virtual & Cloud based Installation
The OPNsense User Interface
User Management
Using IPv6
Two-factor authentication
System Health & Round Robin Data
Netflow Export & Analyses
Using Aliases
Virtual Private Networking
Inline Intrusion Prevention System
Caching Proxy
Anti Virus Engine
Traffic Shaping
Multi WAN
Mobile Networking
High Availability & Hardware Failover
Captive portal & GuestNET
Dynamic Routing
OPNsense Tools
How to’s
Development Manual
Development Workflow
Coding Guidelines
Architecture
Backend
Frontend
Components
Examples
How to’s
Sources
2
Project Relations
FreeBSD®
Deciso B.V.
HardenedBSD
M0n0wall
Open Source Initiative
Legal notices
OPNsense License & Copyright
Packages and ports
Documentation Copyright
Pictures Copyright
Logo’s Copyright
Trademark policy
Support Options
Commercial
Community
Community Support Levels
Contribute
Financially
Support Contract
Development
Translations
Documentation & wiki articles
Forum & IRC
Social media
Closing Words
3
About the Fork
Welcome to about the fork. This page is intended to explain the original motivation for
forking, but keep in mind that currently less than 10% of the original legacy code base
remains. As it stand today, OPNsense has evolved from being a fork to a whole new
security platform with leading innovations such as weekly security updates for all
components, a REST API, inline Intrusion Prevention and intuitive modern user
interface.
4
So why did we fork?
Back in 2014, after having sponsored pfSense® for years we felt there was no other
option than fork the project and keep the spirit of the - original m0n0wall based fork -
alive. Below you can read about our original motivations and the birth of OPNsense®.
Technical
5
We had technical reasons to fork. As much as we love the functionality/feature set of
pfSense, we do not enjoy the code quality and dispersed development method. We like
structure, achievable goals set forth in a roadmap [https://opnsense.org/about/road-
map/] with regular releases and a decent framework.
Security
On the security part the main issue was the need to separate logic. The GUI should not
perform tasks that require root access and potential security issues should be fixed
before they become a real problem.
Quality
As for quality, all new features will be built using a solid framework with a Model View
Controller. For this purpose we choose Phalcon [https://phalconphp.com/nl/] as it is the
fastest open source PHP framework available. And we will gradually migrate parts
inherited from pfSense to the new framework to avoid a big-bang approach.
Community
A thriving community can only exist when people are willing to share. We want to make it
easier for people to join and help to build the community. With pfSense this has been
rather difficult as the tools to build it are difficult to use and often do not work in the first
few attempts. And since 2014 year they are not freely available any more, you need to
apply for access with ESF. We believe a good open source project has nothing to hide
so access to the sources should be there for all. It will remain a mystery why ESF made
that move as commit rights and read rights are totally different.
Note
ESF has since changed their policy several times with different license models, including
6
the ESF 6 clause license and the latest being a Apache style license.
Transparency
A real concern with pfSense is transparency. Since Netgate bought the majority share of
pfSense and renamed the company to ESF it has been difficult to understand the
direction they want the project to go. Removing the tools from github without prior
warning and using the brand name to fence off competitors has scared quite a lot of
people. Also the license had changed for no apparent reason…
First Release
Much work had already been done before the first official release
[https://opnsense.org/opnsense-version-15-1-released/]:
The build-tools had been completely rewritten from the ground up with clear and easy to
read build scripts that are portable and small,
OPNsense is now a package that can be installed on top of our custom FreeBSD build
(you can literally do pkg remove opnsense and are left with an almost standard
FreeBSD base system),
Captive portal has been rewritten and does not make use of kernel patches anymore,
7
New features (captive portal) have been implemented with a clear structure,
Fully reworked the GUI to a modern Bootstrap based one that is also easier to
customize if you want to.
Note
A lot of work has been done to improve the code quality and with weekly updates we
have proven to be able to act quickly on known security threats. For current status of the
project and future development see our roadmap [https://opnsense.org/about/road-
map/].
Deciso’s involvement
That being said it is important to know that Deciso [https://www.deciso.com/about-
deciso/] has been a long time sponsor of pfSense and invested a lot of time and money
into the project. Deciso helped to make it a success in Europe. Until Netgate bought the
company there was room for many others like us, but that has changed unfortunately.
Closing thoughts
In the end it all boils down to the direction we will go both technical as well as community
involvement and transparency.
8
You are invited! Try OPNsense, be part of the community and help the project move
forward. OPNsense is rapidly becoming the number one open source firewall platform!
9
Introduction
Welcome to the OPNsense documentation & wiki project! The documentation is work in
progress and is updated frequently. If you would like to contribute in anyway, please take
a look at our guide how to Contribute.
Mission Statement
Give users, developers and businesses a friendly, stable and transparent environment.
Make OPNsense the most widely used open source security platform. The project’s
name is derived from open and sense and stands for: “Open (source) makes sense.”
10
Feature set
The feature set of OPNsense includes high-end features such as forward caching proxy,
traffic shaping, intrusion detection and easy OpenVPN client setup. The latest release is
based on a recent FreeBSD for long-term support and uses a newly developed MVC-
framework based on Phalcon. OPNsense’s focus on security brings unique features
such as the option to use LibreSSL instead of OpenSSL (selectable in the GUI) and a
custom version based on HardenedBSD.
11
The robust and reliable update mechanism gives OPNsense the ability to provide
important security updates in a timely fashion.
Captive portal
Voucher support
Template manager
Blacklist support
Site to site
Road warrior
IPsec
OpenVPN
12
High Availability & Hardware Failover
Packet Capture
Dynamic DNS
13
Configuration history with colored diff support
and more..
14
User Manual
15
Inline Intrusion Prevention System
IPS SSLBlacklists & Feodo Tracker
IPS GeoIP Blocking
IPS Block SSL certificates
Caching Proxy
Anti Virus Engine
Traffic Shaping
Multi WAN
Mobile Networking
High Availability & Hardware Failover
Captive portal & GuestNET
Dynamic Routing
OPNsense Tools
How to’s
Configuration Cloud Backup
Organize PF Rules by Category
Transparent Filtering Bridge
IPS SSLBlacklists & Feodo Tracker
IPS GeoIP Blocking
IPS Block SSL certificates
Setup Caching Proxy
Setup Transparent Proxy
Setup Web Filtering
Setup Anti Virus Protection
Configure CARP
Setup IPsec Road-Warrior
Setup IPsec site to site tunnel
Setup SSL VPN Road Warrior
Setup SSL VPN site to site tunnel
Setup FreeRADIUS for accounting
Setup Traffic Shaping
Using Insight - Netflow Analyzer
Configure Netflow Exporter
16
Configure 2FA TOTP & Google Authenticator
Configuring Cellular Modems
IPv6 For Zen UK
c-icap
ClamAV
Dynamic Routing: How To
Dynamic Routing: Configuration: OSPFv2
Dynamic Routing: Configuration: RIP
Dynamic Routing: Configuration: Zebra
Configure Spamhaus (E)DROP
FreeRADIUS
Setup a Guest Network
HAProxy
HAProxy How-Tos
Installing OPNsense AWS image
IPSec BINAT
Configure IPv6 Tunnel Broker
How To: Setting Up A Mail Gateway
Multicast DNS Proxy
Setup Multi WAN
Setup Anti Virus Protection using OPNsense Plugins
Tor Configuration
Configuring LDAP
Creating Users & Groups
Configuring Radius
Zerotier Configuration
Overview
Interface Assignment
17
Hardware sizing & setup
The harware setup requires a careful preparation and selection of the standard PC
hardware components for the intended installation of OPNsense.
⚠ Computer hardware with the open source security software OPNsense® pre-installed
can be purchased directly from various (online) stores.
Tip
The OPNsense development team encourage everyone looking for a turn-key solution to
buy from Deciso [https://www.deciso.com] or one of the other partners listed at our
partner page. Listed partners make significant contributions back to the project
While the range of supported devices are from embedded systems to rack mounted
servers, we recommend to use a 64-bit versions of OPNsense, if the hardware is
capable of running 64-bit operating systems
[https://en.wikipedia.org/wiki/operating_system]. It is possible to install and run 32-bit
(x86-32, i386) versions of OPNsense® on 64-bit (x86-64, amd64) PC hardware, but we
do not recommend it, especially not for new deployments.
Hardware requirements
18
For substantially narrowed OPNsense® functionality there is the basic specification. For
full functionality there are minimum, reasonable and recommended specifications.
Minimum
The minimum specification to run all OPNsense standard features that do not need disk
writes, means you can run all standard features, expect for the ones that require disk
writes, e.g. a caching proxy (cache) or intrusion detection and prevention (alert
database).
RAM 512 MB
Install target SD or CF card with a minimum of 4GB, use nano images for
installation.
Reasonable
The reasonable specification to run all OPNsense standard features, means every
feature is functional, but perhaps not with a lot of users or high loads.
RAM 1 GB
19
Install target 40 GB SSD, a minimum of 1GB memory is needed for the installer to
run.
Recommended
The recommended specification to run all OPNsense standard features, means every
feature is functional and fits most use cases.
RAM 4 GB
Hardware guide
The hardware required for your local OPNsense, will be determined by the intended
minimum throughput [https://en.wikipedia.org/wiki/] and the feature set.
20
Squid [https://en.wikipedia.org/wiki/Squid_(software)]
a caching web proxy which can be used for web-content control, respectively. These
packages rely strongly on CPU load and disk-cache writes.
Throughput
The main hardware-factors of the OPNsense setup involved are CPU, RAM, mass
storage (disc), the number and quality of network interfaces.
21
Mbps (Mbit/s or Mb/s) - Megabit per second - 1,000,000 bits per second
Supported hardware
The FreeBSD 11.1-RELEASE is the base of OPNsense. All FreeBSD drivers are
included in the OPNsense kernel, and the hardware compatibility is the same.
Tip
If you are looking to buy new hardware then take a look at our partner page
[https://opnsense.org/partners] as these partners contribute back to OPNsense and sell
hardware that is know to work well.
List of references
McKusick, Marshall; Neville-Neil, George V; Warson, Robert NM; The Design and
22
Implementation of the FreeBSD Operating System (2015); Addison-Wesley, New Jersey;
ISBN 978-0321968975
23
Initial Installation & Configuration
Software setup
Note
Just looking on how to invoke the installer? When the live environment has been started
just login with user installer and password opnsense.
Architecture
The software setup and installation of OPNsense® is available for x86-32
[https://en.wikipedia.org/wiki/X86-32] and x86-64 [https://en.wikipedia.org/wiki/X86-64]
bit microprocessor architectures.
Embedded vs Full
Full installs can run on SD memory cards [https://en.wikipedia.org/wiki/Secure_Digital],
solid-state disks (SSD) [https://en.wikipedia.org/wiki/Solid-state_drive] or hard disk
drives (HDD) [https://en.wikipedia.org/wiki/Hard_disk_drive].
Since version 15.1.10 (04 May 2015) the option to install an embedded
[https://en.wikipedia.org/wiki/Embedded_operating_system] OPNsense image is also
supported.
The main differences between an embedded image and a full image are:
Embedded Full
24
Writes to RAM disk Writes to local disk
No log data retention after reboot Log data retention after reboot
Not intended for local disk writes Suitable for disk writes.
Embedded only use Can enable RAM disk for embedded mode.
Embedded images (nanobsd) store logging and cache data in memory only, while full
versions will keep the data stored on the local drive. A full version can mimic the
behavior of an embedded version by enabling RAM disks, this is especially useful for SD
memory card installations.
Warning
See the chapter Hardware Setup for further information on hardware requirements prior
to an install.
Download
The OPNsense distribution can be downloaded [https://opnsense.org/download] from
one of our mirrors [https://opnsense.org/download].
Installation Media
Depending on you hardware and use case different installation media are provided:
Type
Description
25
cdrom ISO installer image with live system capabilities
running in VGA-only mode
vga USB installer image with live system capabilities
running in VGA-only mode
serial USB installer image with live system capabilities
running in serial console (115200) mode with
secondary VGA support (no kernel messages
though)
nano a preinstalled serial image for 4GB USB sticks,
SD or CF cards for use with embedded devices
Warning
Flash memory cards will only tolerate a limited number of writes and re-writes. For
embedded (nano) versions memory disks for /var and /tmp are applied by default to
prolong CF (flash) card lifetimes.
26
Note
Please be ware that the latest installation media does not always correspond with the
latest released version. OPNsense installation images are provided on a regular bases
together with mayor versions in January and July. More information on our release
schedule is available from our package repository see README
[https://pkg.opnsense.org/releases/16.1/README]
27
Installation Method
Download the installation image from one of the mirrors listed on the OPNsense
[https://opnsense.org/download/] website.
The easiest method of installation is the USB-memstick installer. If your target platform
has a serial interface choose the “serial image. 64-bit and 32-bit install images are
provided. The following examples apply to both.
Write the image to a USB flash drive (>= 1GB) or an IDE hard disk, either with dd under
FreeBSD or under Windows with physdiskwrite
Before writing an (iso) image you need to unpack it first (use bunzip2).
FreeBSD
Where X = the device number of your USB flash drive (check dmesg )
Linux
28
where X = the IDE device name of your USB flash drive (check with hdparm -i /dev/sdX)
(ignore the warning about trailing garbage - it’s because of the digital signature)
OpenBSD
The device must be the ENTIRE device (in Windows/DOS language: the ‘C’ partition),
and a raw I/O device (the ‘r’ in front of the device “sd6”), not a block mode device.
Mac OS X
where r = raw device, and where X = the disk device number of your CF card (check
Disk Utility) (ignore the warning about trailing garbage - it’s because of the digital
signature)
Windows
physdiskwrite -u OPNsense-##.#.##-[Type]-[Architecture].img
Install Instructions
The boot process gives you the opportunity to run several optional configuration steps. It
has been designed to always boot into a live environment in order to be able to access
the GUI or even SSH directly. If a timeout was missed simply restart the boot procedure.
29
OPNsense Importer
All images feature the new “opnsense-importer” utility, which is now invoked instead of
the early installer. You can stop the automatic timeout by pressing any key. Afterwards
you will have the opportunity to select a disk to import from. If the option times out or the
importer is exited without a disk selection, the factory defaults will be used for the boot.
The next prompt will be for manual interface selection. This step is well-established
since OPNsense 15.7 .
Live environment
The system will then continue into a live environment. If the config importer was used
previously on an existing installation, the system will boot up with a fully functional setup,
but will not overwrite the previous installation. Use this feature for safely previewing
upgrades.
If you have used a CD-ROM, VGA, Serial image without a config import you are by
default able to (a) log into the root shell using the user “root” with password “opnsense”,
or (b) log into the installer using the user “installer” with password “opnsense”. The GUI
will listen on https://192.168.1.1/ for user “root” with password “opnsense”. Using SSH,
the “root” and “installer” users are available as well on IP 192.168.1.1. Note that these
install medias are read-only, which means your current live configuration will be lost after
reboot.
Nano Image
If you have used a Nano image, your system is already up and running as it is designed
as such. It is set to read-write attempting to minimise write cycles by mounting relevant
partitions as memory file systems. If you should require an installer anyway, log in as
user “root”, select option 8 from the menu and type “opnsense-installer”. The “opnsense-
30
importer” can be run this way as well should you require to run the import again.
Create a bootable USB flash drive with the downloaded and unpacked img file.
Configure your system to boot from USB.
Installation Steps
The installation process involves a few simple steps.
Note
To invoke the installer login with user installer and password opnsense
Tip
The installer can also be started from the network using ssh, default ip address is
192.168.1.1
Configure console - The default configuration should be fine for most occasions.
Select task - The Quick/Easy Install option should be fine for most occasions. For
installations on embedded systems or systems with minimal diskspace choose Custom
Installation and do not create a swap slice. Continue with default settings.
Are you SURE? - When proceeding OPNsense will be installed on the first hard disk
in the system.
Reboot - The system is now installed and needs to be rebooted to continue with
configuration.
Warning
31
You will lose all files on the installation disk. If another disk is to be used then choose a
Custom installation instead of the Quick/Easy Install.
Initial configuration
After installation the system will prompt you for the interface assignment, if you ignore
this then default settings are applied. Installation ends with the login prompt.
Welcome message
login:
Tip
A user can login to the console menu with his credentials. The default credentials after a
fresh install are username “root” and password “opnsense”.
32
The first interface is the LAN interface. Type the appropriate interface name, for example
“em0”. The second interface is the WAN interface. Type the appropriate interface name,
eg. “em1” . Possible additional interfaces can be assigned as OPT interfaces. If you
assigned all your interfaces you can press [ENTER] and confirm the settings. OPNsense
will configure your system and present the login prompt when finished.
Then via console, check your /etc/fstab and make sure your primary partition has
rw,noatime instead of just rw.
Console
33
The console menu shows 13 options.
opnsense-update
OPNsense features a command line interface (CLI) tool “opnsense-update”. Via menu
option 8) Shell, the user can get to the shell and use opnsense-update.
The other method to upgrade the system is via console option 12) Upgrade from
console
GUI
34
35
Virtual & Cloud based Installation
Local/Server
Installing OPNsense on a virtual machine can be done by using the cdrom iso image.
Full instructions are available in chapter Initial Installation & Configuration .
General tips
For optimum performance and compatibility, these guides are given:
VMware ESXi
VMware offers full instructions for installing FreeBSD, these can be found here
[http://partnerweb.vmware.com/GOSIG/FreeBSD_11x.html].
To install the VMware tools just goto System->Firmware->Plugins and install os-
36
vmware by clicking on the + sign next to it.
Note
While other network setups may work fine, the e1000 driver seems to work best,
certainly when utilizing the traffic shaper.
Xen
To install the Xen tools just goto System->Firmware->Plugins and install os-xen by
clicking on the + sign next to it.
HyperV
HyperV Generation 1 and 2 are supported out of the box, no additional drivers or tools
are needed.
Others
OPNsense can be installed on all virtual machines that support FreeBSD (such as KVM,
Bhyve, VirtualBox).
Hosted
37
For hosted installations where you can’t install using the cdrom iso an alternative
approach is available in the form of opnsense-bootstrap.
opnsense-bootstrap
opnsense-bootstrap(8) is a tool that can completely reinstall a running system in place
for a thorough factory reset or to restore consistency of all the OPNsense files. It can
also wipe the configuration directory, but won’t do that by default.
It will automatically pick up the latest available version and build a chain of trust by using
current package fingerprints -> CA root certificates -> HTTPS -> OPNsense package
fingerprints.
What it will also do is turn a supported stock FreeBSD release into an OPNsense
installation, given that UFS was used to install the root file system.
Installing OPNsense into the Amazon cloud can be a dounting task as no console is
offered. As part of Deciso’s support packages (see OPNsense commercial Support
38
[https://opnsense.org/support-overview/commercial-support/]), deciso offer free access
to its OPNsense Amazon Machine Image (AMI).
Common Issues
Some common issues have been reported for different virtual environments. You can
find known solutions to these problems below.
If you problem is not listed always try the General tips as mentioned in the article first.
39
NAT issues on XenServer
This issue has been reported to be solved by disabling cheksum offloading on both
OPNsense domU and Vifs.
40
The OPNsense User Interface
This article explains the basics of the OPNsense Graphical User Interface or GUI for
short.
User Login
Before we can take a look at the GUI options we need to login. The default user is root
and the password is opnsense.
41
42
Logo & Link to Lobby
Click on the OPNsense logo wherever you are in the interface and you will be directed to
the lobby and dashboard.
Logout
Menu Area
The Menu area holds all the primary and sub menu’s. Here you can select what part of
the system you want to watch or change.
You can see the layering on the menu. There are three levels:
Category level
43
Function level
In the following sample you see a screenshot of the Category System, with:
Function: Settings
Quick Navigation
A faster way to navigate trough the gui is by using the quick navigation/search box on
the upper right corner of the screen. Either click on it or hit tab to select it.
The search field is a type-a-head field, meaning that it will guess what you are looking
for and fill up while typing. Hit enter or click on an option to select and navigate directly
to the right page.
44
User & Local domain
In the right corner just to the left of the quick navigation you will see your username and
the full domain name the firewall is configured with (to change firewall name, go to
System->Setting->General).
Content Area
The content area is used to display:
Input forms
Popup Forms
Buttons
Form View
45
Lets take a look at how an advanced form may look like:
Full Help
Many Forms are equipped with build-in help. In the upper right corner of the form you
can select to view all help messages at once. The toggle will color green when enabled
and show the help messages beneath the input items.
Advanced Mode
Some forms have hidden advanced features, to view them toggle the advanced mode
in the left corner of the form. Doing so will reveal all advanced options.
46
Single Item Help
Show a single line help by pressing the (i) left of a form item. Like this:
Standard Tabs
A standard tab can be clicked upon to open the corresponding form.
47
Dropdown Tabs
A dropdown tab can be clicked upon to open the first menu item or you can click on the
arrow next to it to show all options, like:
48
User Management
The user manager of OPNsense allows for controlling access to the different part
(pages) of the configurator as well as controlling access to particular services on a per
user bases.
Authentication
OPNsense offers integration with external servers for services that require user
authentication. These services include:
49
IPsec
OpenVPN
Captive Portal
Proxy
Integrated into OPNsense are the Local User Database and Voucher Server. The
Voucher Server is intended to be used with the Captive portal.
Radius
Authorization
Besides authenticating, user authorization to access parts of the configuration can also
be setup with an external server, but in order to grant the appropriate privileges to the
users they need to be imported in OPNsense’s local user manager. This way one can
validate a user against its externally stored password and have a fine grained control
over the configuration pages that user may access.
50
privileges.
Services
The authentication service to use can be configured using the settings in System-
>Access->Settings. Here you can also find timeout settings for the user sessions and
for local user accounts you will have the option to improve security using password
policy constraints.
Duration [Policy] Password duration, optionally define how often the user
should change his or her password.
Configuration
51
Creating Users & Groups
LDAP
Configuring LDAP
Radius
Configuring Radius
52
Using IPv6
OPNsense fully supports IPv6 for routing and firewall. However there are lots of different
options to utilize IPv6. Currently these scenario’s are known to work:
Warning
NAT64, IPv4 <-> IPv6 Network address translations, is currently not supported by
FreeBSD.
Configuring
53
IPv6 For Zen UK
54
Two-factor authentication
55
Two-factor authentication also known as 2FA or 2-Step Verification is an authentication
method that requires two components, such as a pin/password + a token.
56
OPNsense (version >=16.1.14) offers support for Two-factor authentication throughout
the entire system, with one exception being console/ssh access.
Captive Portal
Caching Proxy
57
Time-based One-time Password
TOTP is an algorithm that computes a one-time password from a shared secret key and
the current time. OPNsense supports RFC 6238.
Google Authenticator
OPNsense fully supports the use of Google’s Authenticator application. This application
can generate tokens on Android, iOS and BlackBerry OS. The usage of this application
is free and very simple to setup using OPNsense.
58
Configuration & Setup
To setup see: Configure 2FA TOTP & Google Authenticator.
59
System Health & Round Robin Data
System Health is a dynamic view on RRD data gathered by the system. It allows you to
dive into different statistics that show the overall health and performance of the system
over time.
The system health module will enable you to track down issues faster and easier than
traditional static RRD graphs and it allows you to zoom in.
Data collectors
System Health has the following primary data collectors:
Packets
Packets show the number of packets per second traveling to and from a certain
interface.
Quality
60
Quality show latency and packet loss of the monitored gateways (ip).
System
The system section is used for sensor data regarding the system utilization, such as
memory usage, mbufs, states, processes and (when available) cpu temperature.
Traffic
Shows traffic graphs for each interface including vpn (ipsec).
Depending on the features in use there may be more or less graphs available.
61
62
Toggle menu collapse
This feature will show or hide the top menu.
Category Selection
The category items are tabs with drop down menu’s. Click on one of the categories and
select the graph you like to dive into.
Graph Selection
Part of the drop down menu, where you can select the graph to view.
Inverse
By selecting Inverse each odd dataset is reversed in direction (times minus one), this is
especially useful for traffic flows where you can plot ingoing and outgoing flows in
63
different directions.
Resolution
The resolution determines the maximum number of datapoints that will be shown in the
graph and therefore indirectly influences the scale of the calculated averages.
The table data area consists of the min/max/average and detailed table data area.
64
Name of the graph
Shows the name of the selected graph.
Label filter
The label filter can be used to filer out data you do not want to see. Click once to disable
or double click to select only this set.
A nice sample can be seen here, where the processes obscure all other data.
65
Just click once on processes to hide this data set, notice that the scales will adapt as
well.
66
Main graph area
The main graph area show the full graph or just the part you selected in the zoom area
with more detail.
Zoom Area
The zoom area can be used to select and zoom in on one part of the graph, the scales
are adapted automatically and any tables will be updated as well.
This feature is very useful to zoom in on issues or for showing just part of the graph.
To use, click on it and hold while moving your pointer to another part of the zoom area,
on mouse up (release mouse click) the main graph area will be updated accordingly.
67
The zoom area will also be updated with more detailed data - when available - for the
selected area.
A sample selection:
68
Min/max/average table
If Show Tables is on then this area will show: * Minimum value of each dataset *
Maximum value of each dataset * Average value of each dataset
Detailed table
If Show Tables is on then this area will show each value that is plotted in the graph. You
can toggle the time and date view from timestamp to human readable values and export
the data to as comma separated file (.CSV).
69
The exported dataset can be used for your own reporting.
70
71
Netflow Export & Analyses
72
73
Netflow is a monitoring feature, invented by Cisco, it is implemented in the FreeBSD
kernel with ng_netflow (Netgraph). Since Netgraph is a kernel implementation it is very
fast with little overhead compared to softflowd or pfflowd.
While many monitoring solutions such as Nagios, Cacti and vnstat only capture traffic
statistics, Netflow captures complete packet flows including source, destination ip and
port number.
OPNsense offers full support for exporting Netflow data to external collectors as well as
a comprehensive Analyzer for on-the-box analysis and live monitoring.
OPNsense is the only open source solution with a build-in Netflow analyzer integrated
into it’s Graphical User Interface.
Supported Versions
OPNsense support both Netflow version 5 (IPv4) and version 9 (IPv4 & IPv6).
Netflow Basics
For analyzing the flow data it is important to understand the difference between ingress
and egress traffic.
Ingress
Traffic to or coming from the firewall.
Egress
Traffic passing trough the firewall.
74
Ingress + Egress = Double flow count
When enabling both ingress and egress, traffic gets counted double due to Network
Address Translation as all packets going to the WAN coming from the LAN pass the
Network translation of the firewall therefor also creating an ingress flow.
If you are not interested in ingress traffic then OPNsense offers the option to filter this
traffic. When utilizing a proxy on the same device its important to capture the ingress
flows as well, otherwise all proxy traffic won’t be visible. Downside is of course that all
traffic not passing the proxy will we counted twice due to the mentioned NAT effect.
Netflow Exporter
OPNsense Netflow Exporter supports multiple interfaces, filtering of ingress flows and
multiple destinations including local capture for analysis by Insight (OPNsense Netflow
Analyzer).
75
Netflow Analyzer - Insight
OPNsense offers a full Netflow Analyzer with the following features:
76
Last month, 24 hour average
Detailed view with date selection and port/ip filter (up to 2 months)
Selectable Resolution
77
Configuration
Setup Netflow Exporter
See Configure Netflow Exporter
Setup Insight
See Using Insight - Netflow Analyzer
78
Using Aliases
Aliases are named lists of networks, hosts or ports that can be used as one entity by
selecting the alias name in the various supported sections of the firewall. These aliases
are particularly useful to condense firewall rules and minimize changes.
Alias Types
OPNsense offers the following alias types:
Type Description
Hosts
Hosts can be entered as a single IP address or a fully qualified domain name. When
using a fully qualified domain name, the name will we resolved periodically (default is
each 300 seconds).
Sample
79
Lets say we want to create an alias table for www.youtube.com
Apply changes and look at the content of our newly created pf table. Go to Firewall-
>Diagnostics->pfTables and select our newly created youtube table.
80
As you can see there are multiple ip addresses for this domain.
Networks
Networks are specified in Classless Inter-Domain Routing format (CIDR). Use the the
correct CIDR mask for each entry. For instance a /32 specifies a single IPv4 host, or
/128 specifies a single IPv6 host, whereas /24 specifies 255.255.255.0 and /64 specifies
a normal IPv6 network.
Ports
Ports can be specified as a single number or a range using a colon :. For instance to
add a range of 20 to 25 one would enter 20:25 in the Port(s) section.
81
URL Tables
URL tables can be used to fetch a list of ip addresses from a remote server. There are
several IP lists available for free, most notably are the “Don’t Route Or Peer” lists from
Spamhaus.
GeoIP
With GeoIP alias you can select one or more countries or whole continents to block or
allow. Use the toggle all checkbox to select all countries within the given region.
This feature was reworked with 17.7.7 and supersedes the GeoIP blocking via IPS.
82
Import Feature
To quickly add a list of aliases OPNsense also offers an import feature, where you can
paste or enter a list in text format.
Common examples are lists of IPs, networks, blacklists, etc. The list may contain IP
addresses, with or without CIDR prefix, IP ranges, blank lines (ignored) and an optional
description after each IP. e.g.:
83
172.16.1.2
172.16.0.0/24
10.11.12.100-10.11.12.200
192.168.1.254 Home router
10.20.0.0/16 Office network
10.40.1.10-10.40.1.19 Managed switches
Spamhaus
The Spamhaus Don’t Route Or Peer Lists
DROP (Don’t Route Or Peer) and EDROP are advisory “drop all traffic” lists, consisting
of netblocks that are “hijacked” or leased by professional spam or cyber-crime
operations (used for dissemination of malware, trojan downloaders, botnet controllers).
The DROP and EDROP lists are a tiny subset of the SBL, designed for use by firewalls
and routing equipment to filter out the malicious traffic from these netblocks.
Source : https://www.spamhaus.org/drop/
Downloads
DROP list [https://www.spamhaus.org/drop/drop.txt]
Lets create a simple alias list and assume we have 3 remote ip’s that may access the
ipsec server for a site to site tunnel connection:
84
192.168.100.1
192.168.200.2
192.168.300.3
We call our list remote_ipsec and update our firewall rules accordingly.
85
Notice the list icon to identify a rule with an alias (list).
Advanced
For hosts it is possible to use lists in lists. Per example you could have:
The end result will be a list with all ip addresses in one alias list (servers).
GeoIP’s
While it is possible to use geoIP lists in aliases by importing or using the url feature,
OPNsense has a much more advanced way of blocking or allowing traffic based on the
86
geographical location (country) by utilizing the netmap enabled Inline Intrusion
Prevention System see also IPS GeoIP Blocking
87
Virtual Private Networking
A virtual private network secures public network connections and in doing so it extends
the private network into the public network such as internet. With a VPN you can create
large secure networks that can act as one private network.
88
89
(picture from wikipedia
[https://en.wikipedia.org/wiki/File:Virtual_Private_Network_overview.svg])
Companies use this technology for connecting branch offices and remote users (road
warriors).
OPNsense supports VPN connections for branch offices as well as remote users.
Creating a single secured private network with multiple branch offices connecting to a
single site can easily be setup from within the graphical user interface. For remote users,
certificates can be created and revoked and a simple to use export utility makes the
client configuration a breeze.
90
Note
IPsec
Zerotier - seamlessly connect everything, requires account from zerotier.com, free for
up to 100 devices.
91
Configuration
Please read our how-to’s for configuration examples and more detailed information.
IPsec Site-to-Site
Setup IPsec site to site tunnel
OpenVPN/SSL Site-to-Site
Setup SSL VPN site to site tunnel
Zerotier
Zerotier Configuration
92
93
Inline Intrusion Prevention System
The inline IPS system of OPNsense is based on Suricata and utilizes Netmap to
enhance performance and minimize cpu utilization. This deep packet inspection system
is very powerful and can be used to mitigate security threats at wire speed.
OPNsense has integrated support for ET Open rules. For details and Guidelines see:
http://doc.emergingthreats.net/bin/view/Main/EmergingFAQ For rules documentation:
http://doc.emergingthreats.net/
Abuse.ch
Abuse.ch offer several blacklist for protecting against fraudulent networks. OPNsense
has integrated support for:
SSL Blacklist
SSL Blacklist (SSLBL) is a project maintained by abuse.ch. The goal is to provide a list
of “bad” SSL certificates identified by abuse.ch to be associated with malware or botnet
activities. SSLBL relies on SHA1 fingerprints of malicious SSL certificates and offers
various blacklists.
94
Feodo Tracker
Feodo (also known as Cridex or Bugat) is a Trojan used to commit ebanking fraud and
steal sensitive information from the victims computer, such as credit card details or
credentials. At the moment, Feodo Tracker is tracking four versions of Feodo, and they
are labeled by Feodo Tracker as version A, version B, version C and version D:
Version B Hosted on servers rented and operated by cybercriminals for the exclusive
purpose of hosting a Feodo botnet controller. Usually taking advantage of a domain
name within ccTLD .ru. Botnet traffic usually hits these domain names using port 80
TCP.
Version C Successor of Feodo, completely different code. Hosted on the same botnet
infrastructure as Version A (compromised webservers, nginx on port 8080 TCP or port
7779 TCP, no domain names) but using a different URL structure. This Version is also
known as Geodo and Emotet.
95
For more details see: http://dev.maxmind.com/geoip/geoip2/geolite2/
Finger Printing
OPNsense includes a very polished solution to block protected sites based on their SSL
fingerprint.
How-to’s
IPS SSLBlacklists & Feodo Tracker
IPS GeoIP Blocking
IPS Block SSL certificates
96
IPS SSLBlacklists & Feodo Tracker
This tutorial explains how to setup the IPS system to drop SSL certificates listed on the
abuse.ch [https://www.abuse.ch] SSL Blacklists & Feodo Tracker.
Feodo (also known as Cridex or Bugat) is a Trojan used to commit e-banking fraud and
steal sensitive information from the victim’s computer, such as credit card details or
credentials. For more information see https://feodotracker.abuse.ch
Prerequisites
Always upgrade to latest release first. See Initial Installation & Configuration and/or
upgrade to latest release: System->Firmware: Fetch updates
Minimum Advisable Memory is 2 Gigabyte and sufficient free disk space for logging
(>10GB advisable).
97
Warning
After applying you need to reboot OPNsense otherwise offloading may not completely
be disabled and IPS mode will not function.
Note
Some features described on this page were added in version 16.1.1. Always keep your
system up to date.
98
Apply configuration
First apply the configuration by pressing the Apply button at the bottom of the form.
99
Change default behavior
Now click on the info button right after each rule and change Input Filter from none to
drop actions.
100
Now press Download & Update Rules again to change the behavior to drop.
Keep up to date
Now schedule a regular fetch to keep your server up to date.
101
Select enabled and choose a time. For the example it is set to each day at 11:12. Select
Save changes and wait until you have returned to the IDS screen.
DONE
Your system has now been fully setup to drop known fraudulent SSL certificates as well
102
data phishing attempts by utilizing the Feodo tracking list.
Sample alert
Currently there is no test service available to check your block rules against, however
here is a sample of an actual alert that has been blocked:
103
IPS GeoIP Blocking
This tutorial explains how to setup the IPS system to block ip’s based on their
geographic location. This option is made possible by the integration of the Maxmind
GeoLite2 Country database. More information can be found here:
http://dev.maxmind.com/geoip/geoip2/geolite2/
Prerequisites
Always upgrade to latest release first. See Initial Installation & Configuration and/or
upgrade to latest release: System->Firmware: Fetch updates
Minimum Advisable Memory is 2 Gigabyte and sufficient free disk space for logging
(>10GB advisable).
Warning
104
After applying you need to reboot OPNsense otherwise offloading may not completely
be disabled and IPS mode will not function.
User defined
Select the tab User defined.
Select Country:
105
We selected Netherlands(not) as this server needs to be accessible within The
Netherlands, this will drop all other traffic in both directions.
Add a description:
106
And click Save changes
Apply configuration
If this is the first GeoIP rule you add then you need to Download & Update Rules
Then apply the configuration by pressing the Apply button at the bottom of the form.
107
Sample Alert
See a sample of an alert message below.
108
IPS Block SSL certificates
This tutorial explains how to setup the IPS system to block ssl certificates based on their
SHA1 fingerprint.
Prerequisites
Always upgrade to latest release first. See Initial Installation & Configuration and/or
upgrade to latest release: System->Firmware: Fetch updates
Minimum Advisable Memory is 2 Gigabyte and sufficient free disk space for logging
(>10GB advisable).
Warning
After applying you need to reboot OPNsense otherwise offloading may not completely
109
be disabled and IPS mode will not function.
User defined
Select the tab User defined.
Open your browser and go to https://facebook.com when loaded click on the lock next to
the address : .
Click on the arrow ( > ) and then Select More Information Now open the certificate
110
details and you will see something that looks like this:
111
Select the Action (Alert or Drop):
Add a description:
112
And click Save changes
Apply configuration
First apply the configuration by pressing the Apply button at the bottom of the form.
113
Note
If the browser has cached the certificate no SSL certificate exchange will be done and
the website will not be blocked.
114
Caching Proxy
Features include:
HTTP Proxy
FTP Proxy
User Authentication
(Compressed) Blacklist
115
Category Based Web Filtering
Authenticators
User authentication can be done using OPNsense standard and build-in authenticators.
Currently these include:
Radius
No authentication
Access Control
OPNsense supports fine grained access control, base upon:
Subnets
Ports
MIME types
Banned IP’s
Whitelists
116
Blacklists
Browser/User Agents
Traffic Management
The proxy can be combined with the traffic shaper and take full advantage of its shaping
features.Additionally it includes its own options:
117
Transparent Mode
The transparent mode means all request will be diverted to the proxy without any
configuration on your client. Transparent mode works very well with unsecured http
requests, however with secured (SSL) https connection the proxy will become a man-in-
the-middle as the client will “talk” to the proxy and the proxy will encrypt the traffic with its
master key that the client is required to trust.
While we do not encourage the use of https in transparent mode, this feature is
scheduled for release in version 16.7.
Warning
Using a transparent HTTPS proxy can be a dangerous practice and may not be allowed
by the services you use, for instance e-banking.
Configuration / HOW-TO’s
More information on how to utilize OPNsense’s proxy service can be found in:
118
Setup Transparent Proxy
119
Anti Virus Engine
OPNsense offers the industry standard ICAP to protect http and https connections
120
against ransomware, trojans, viruses and other malware .
OPNsense offers a ClamAV plugin, which can be used with the C-ICAP plugin or relies
on third party engines from well known vendors, such as Symantec’s Protection Engine.
121
Traffic Shaping
Traffic shaping (also known as “packet shaping”) is the control of computer network
traffic in order to optimize or guarantee performance, lower latency, and/or increase
usable bandwidth by delaying packets that meet certain criteria. More specifically, traffic
shaping is any action on a set of packets (often called a stream or a flow), which
imposes additional delay on those packets such that they conform to some
predetermined constraint (a contract or traffic profile).
Introduction
Traffic shaping within OPNsense is very flexible and is organized around pipes, queues
and corresponding rules. The pipes define the allowed bandwidth, the queues can be
used to set a weight within the pipe and finally the rules are used to apply the shaping to
a certain package flow. The shaping rules are handled independently from the firewall
122
rules and other settings.
OPNsense traffic shaping is a reliable solution to limit bandwidth or prioritize traffic and
can be combined with other functions such as captive portal or high availability (CARP).
Bandwidth limitations can be defined based upon the interface(s), ip source &
destination, direction of traffic (in/out) and port numbers (application).
Available bandwidth can be shared evenly over all users, this allows for optimum
performance at all times.
Traffic can also be prioritized by adding queues and defining weights. Strictly speaking
traffic is not really prioritized but applications with a higher weight can consume more
bandwidth than others when the total available bandwidth is limited.
The traffic shaper implementation uses IPFW and dummynet to offer a modern, reliable
solution with a low cpu footprint.
Packets belonging to the same flow are then passed to either of two different objects,
which implement the traffic regulation:
pipe
A pipe emulates a link with given bandwidth, propagation delay, queue size and packet
loss rate. Packets are queued in front of the pipe as they come out from the classifier,
123
and then transferred to the pipe according to the pipe’s parameters.
queue
A queue is an abstraction used to implement the WF2Q+ (Worstcase Fair Weighted Fair
Queueing) policy, which is an efficient variant of the WFQ policy. The queue associates
a weight and a reference pipe to each flow, and then all backlogged (i.e., with packets
queued) flows linked to the same pipe share the pipe’s bandwidth proportionally to their
weights. Note that weights are not priorities; a flow with a lower weight is still guaranteed
to get its fraction of the bandwidth even if a flow with a higher weight is permanently
backlogged.
In practice, pipes can be used to set hard limits to the bandwidth that a flow can use,
whereas queues can be used to determine how different flow share the available
bandwidth.
The shaping rules can be defined in the rules section of the traffic shaper.
Configuration
Read the how to, here: Setup Traffic Shaping
124
Multi WAN
Multi WAN scenario’s are commonly used for failover or load balancing, but
combinations are also possible with OPNsense.
WAN Failover
WAN failover automatically switches between WAN connections in case of connectivity
loss (or high latency) of your primary ISP. As long as the connection is not good all traffic
will be routed of the next available ISP/WAN connection and when connectivity is fully
restored so will the routing switch back to the primary ISP.
The principle is simple: Each WAN connection (gateway) gets a portion of the traffic. The
traffic can be divided equally or weighted.
Configuration
125
For a how to configure read: Setup Multi WAN
126
Mobile Networking
Supported Devices
While all devices supported by FreeBSD will likely function under OPNsense their
configuration depends on a AT command string that can differ from device to device. To
make thing easier some of these strings are part of a easy selectable profile.
127
Huawei ME909u-521 (device cuaUx.0)
Note
If you have tested a cellular modem that is not on this list, but does work then please
report it to the project so we can list it and inform others.
3G - 4G Cellular Failover
To setup Cellular Failover, just follow these two how-tos:
Note
128
High Availability & Hardware Failover
OPNsense utilizes the Common Address Redundancy Protocol or CARP for hardware
failover. Two or more firewalls can be configured as a failover group. If one interface fails
on the primary or the primary goes offline entirely, the secondary becomes active.
Utilizing this powerful feature of OPNsense creates a fully redundant firewall with
automatic and seamless fail-over. While switching to the backup network connections
will stay active with minimal interruption for the users.
Automatic failover
If the primary firewall becomes unavailable, the secondary firewall will take over without
user intervention and minimal interruption.
129
Synchronized state tables
The firewall’s state table is replicated to all failover configured firewalls. This means the
existing connections will be maintained in case of a failure, which is important to prevent
network disruptions.
Configuration synchronization
OPNsense includes configuration synchronization capabilities. Configuration changes
made on the primary system are automatically synchronized to the secondary firewall.
Configure HA CARP
For detailed setup guide see: Configure CARP
130
Captive portal & GuestNET
A Captive Portal allows you to force authentication, or redirection to a click through
page for network access. This is commonly used on hotspot networks, but is also widely
used in corporate networks for an additional layer of security on wireless or Internet
access.
Typical Applications
Guest Network
Template Management
OPNsense’s unique template manager makes setting up your own login page an easy
task. At the same time it offers additional functionalities, such as:
131
URL redirection
Zone Management
Different zones can be setup on each interface or multiple interfaces can share one
zone setup. Each Zone can use a different Captive Portal Template or share it with
another zone.
Authentication
Secure authentication via HTTPS or splash-only portal with URL redirection to a given
page Different sources can be used to authenticate a user in a zone:
Radius
132
Vouchers / Tickets
Voucher Manager
OPNsense’s Captive Portal has an easy voucher creation system that exports the
vouchers to a csv file for use with you favorite application. The export allows you to print
vouchers by merging them with your word or open office template and create a good
looking handout with your logo and company style.
Bandwidth Management
The Build-in traffic shaper can be utilized to:
133
Portal bypass
MAC and IP addresses can be white listed to bypass the portal.
Active Sessions
Platform Integration
Through the integrated REST API the captive portal application can be integrated with
other services. See: Use the API
134
135
Dynamic Routing
Warning
Dynamic Routing (using routing protocols) is supported via an external plugin. Routing
protocols are used to make your network equipment find the best path where your
packets should be sent to.
improve fault tolerance (if a connection breaks, a new route will be found if possible)
you are working in a highly isolated environment, where you have to be in control of
everything happening in your network
OSPFv2 and v3
136
BGPv4
Warning
Not all routing protocols will work in any setup because they may have to be direct
neighbors. Consider the limitations of a routing protocol before using it.
Installation
First of all, select Plugins in the menu:
On this page, you can install the frr plugin by clicking the + icon:
Configuration
Dynamic Routing: Configuration: Zebra
137
Dynamic Routing: Configuration: RIP
How To
Dynamic Routing: How To
138
OPNsense Tools
The OPNsense project offers a bunch of tools to instantly patch the system, revert a
package to a previous (older version) state or revert the whole kernel.
opnsense-update
The opnsense-update utility offers combined kernel and base system upgrades using
remotely fetched binary sets, as well as package upgrades via pkg. For a complete list
of options look at the manpage on the system.
Example:
A minor update also updated the kernel and you experience some driver issues with
your NIC. Open your browser and go to
https://pkg.opnsense.org/FreeBSD:11:amd64/18.1/sets/
Here you can see all the kernels for version 18.1. Be aware to change the version if you
driver a newer version. As an example you updated from 18.1.4 to 18.1.5 you have now
installed kernel-18.1.5. To revert back to the last stable you can see kernel-18.1 so the
syntax would be:
# /usr/local/etc/rc.reboot
Where -k only touches the kernel and -r takes the version number.
139
# opnsense-update -k
# /usr/local/etc/rc.reboot
Warning
Before reverting a kernel please consult the forums or open an issue via Github. You
should only revert kernels on test machines or when qualified team members advise you
to do so!
opnsense-revert
The opnsense-revert utility offers to securely install previous versions of packages found
in an OPNsense release as long as the selected mirror caches said release. For a
complete list of options look at the manpage on the system.
Example 1:
The latest update of OPNsense to version 18.1.5 did da minor jump for the IPSec
package stronswan. From this moment your VPNs are unstable and only a restart helps.
To check if the update of the package is the reason you can easily revert the package to
it’s previous state while running the latest OPNsense version itself
With this command you will on e.g. 18.1.5 while reverting the package strongswan to it’s
version it was in 18.1.4. If you want to go back to the current release version just just
# opnsense-revert strongswan
140
Example 2:
The previous revert of strongswan was not the solution you expected so you try to
completely revert to the previous OPNsense version:
Be aware to also check if there were kernel updates like above to also downgrad the
kernel if needed!
opnsense-patch
The opnsense-patch utility treats all arguments as upstream git repository commit
hashes, downloads them and finally applies them in order. Patches can also be reversed
by reapplying them, but multiple patches must be given in reverse order to succeed. For
a complete list of options look at the manpage on the system.
Example 1:
In the Traffic Shaper a newly introduced typo prevents the system from setting the
correct ipfw ruleset. You were asked by the developer to test a fresh patch 63cfe0a at
URL
https://github.com/opnsense/core/commit/63cfe0a96c83eee0e8aea0caa841f4fc7b92a8d0
At the end of the page there’s the short version 63cfe0a so the command would be:
# opnsense-patch 63cfe0a
If it doesn’t fix your issue of make it even worse, you can just reapply the command to
revert it.
141
Example 2:
You need a special feature for a plugin and ask in Github for it. A developer adds it and
ask you to install the patch 699f1f2 for testing. The full link to it would be
https://github.com/opnsense/plugins/commit/699f1f28a33ce0122fa0e2f5e6e1f48eb3c4f074
The -c changes the default core to plugin repo and adds the patch to the system.
It is also possible to add patches from differnt users, just add -a githubusername before -
c
142
How to’s
Configuration Cloud Backup
Organize PF Rules by Category
Transparent Filtering Bridge
IPS SSLBlacklists & Feodo Tracker
IPS GeoIP Blocking
IPS Block SSL certificates
Setup Caching Proxy
Setup Transparent Proxy
Setup Web Filtering
Setup Anti Virus Protection
Configure CARP
Setup IPsec Road-Warrior
Setup IPsec site to site tunnel
Setup SSL VPN Road Warrior
Setup SSL VPN site to site tunnel
Setup FreeRADIUS for accounting
Setup Traffic Shaping
Using Insight - Netflow Analyzer
Configure Netflow Exporter
Configure 2FA TOTP & Google Authenticator
Configuring Cellular Modems
IPv6 For Zen UK
c-icap
ClamAV
Dynamic Routing: How To
Dynamic Routing: Configuration: OSPFv2
Dynamic Routing: Configuration: RIP
Dynamic Routing: Configuration: Zebra
Configure Spamhaus (E)DROP
FreeRADIUS
143
Setup a Guest Network
HAProxy
HAProxy How-Tos
Installing OPNsense AWS image
IPSec BINAT
Configure IPv6 Tunnel Broker
How To: Setting Up A Mail Gateway
Multicast DNS Proxy
Setup Multi WAN
Setup Anti Virus Protection using OPNsense Plugins
Tor Configuration
Configuring LDAP
Creating Users & Groups
Configuring Radius
Zerotier Configuration
Overview
Interface Assignment
144
Configuration Cloud Backup
Google Drive and Nextcloud
Google Drive is a digital file storage and management service by the information
technology company Google. Amongst other features, like collaborative editing of
documents, spreadsheets, and presentations, it allows signed up users with an account
to store and share files in the digital cloud.
Nextcloud is also an online storage but in contrast to Google Drive it is intended for self
hosting. You can download it freely from their website [https://nextcloud.com/] and install
it on your webserver.
The OPNsense configuration can be stored as a backup file in XML format, to your PC
on an USB stick or remotely in the digital Google Drive cloud.
Easy API
An application programming interfaces (API) for Google Drive was released in 2013.
This API empowers third-party developers to easily write apps for Google Drive.
Nextcloud is using WebDAV which works without a special library so data can be sent
145
directly to the server without a special client library (for example, a file upload is just a
HTTP PUT call).
Remote backup
In OPNsense1 you can backup your configuration directly and automatically to Google
Drive and Nextcloud, using the new backup feature. Every backup to Google Drive will
be encrypted with the same algorithm used in the manual backup so it’s quite easy to
restore to a new installed machine.
After set-up, the backup feature will do first store of the OPNsense config file and
subsequently a daily new backup of changed config content.
Go to https://console.developers.google.com/project
Create a project and give it a name, you may leave it default it doesn’t really matter for
this.
146
Choose “Service account”, followed by “Create Client ID”
Click “Generate new P12 key” and download the key (for your own use, you need this
one later)
Next thing is to create a folder in Google Drive and share it to the “service user” you’ve
just created.
Go to https://drive.google.com
Choose “NEW” and the folder to create a new folder, the name doesn’t really matter (for
example type OPNsense).
paste the email address from the service account and “send”
Now open the folder and copy the folder ID ( in the url, the last piece after #/folders/, it’s
quite long)
Now we can put it all together, login to your OPNsense firewall and go to the backup
feature (default : https://192.168.1.1/diag_backup.php )
147
On the bottom of the page are the options for the Google Drive backup, enable the
feature and fill in the parameters. Email address is acquired in step 2, the key in step 1.
Choose a strong password to protect your data and fill in a number of backups you want
to keep.
When you click Setup/Test Google Drive, the firewall will automatically save and test
your settings and you will receive either an error (connectivity issues) or a list of config
files currently in the backup.
The moment the feature is enabled, it will do a daily compare of the last file in backup
and the current configuration and creates a new backup when something has changed.
148
Click on the user icon top right and click “Users”. In the new page, enter an username
and a password into the boxes and click create to create a new user.
149
Scroll to the Nextcloud Section in System -> Config -> Backup and enter the following
values:
Enable checked
150
If you open it, you will see at lease a single backed up configuration file:
References
Notes
1
As of OPNsense version 1.15.8 .2 (25 March 2015)
151
Organize PF Rules by Category
OPNsense firewall rules can be organized per category. These categories can be freely
chosen or selected.
Note
This feature was added in version 16.1.1. Always keep your system up to date.
152
If you have a large number of categories, then just start typing and in search box to
make a quick selection.
Before Selection
Take a look at this simple rule set before selecting our “My IP’s” category.
153
And after selection
Now when selecting our test category it will look like this:
154
That is all there is to it to organize your rules without messing anything up.
Multi Select
In a later release of OPNsense 16.1 multi selection has been added. This features
makes it possible to select rules from more than one category.
Example:
155
156
Transparent Filtering Bridge
Warning
The Transparent Filtering Bridge is not compatible with Traffic Shaping. Do not enable
the traffic shaper when using the filtering bridge.
Abstract
A transparent firewall can be used to filter traffic without creating different subnets. This
application is called filtering bridge as it acts as a bridge connection two interfaces and
applies filtering rules on top of this.
Requirements
For this howto we need a basic installation of OPNsense with factory defaults as a
starting point.
Considerations
To create this howto version OPNsense 15.7.11 has been used. Some screenshots
maybe outdated, but setting should apply up to at least 17.1.6. If you use a different
version some options can be different.
157
Note
The Menu System of the User Interface has been updated with sub items. Where tabs
are shown in screenshots, these are now likely visible as submenu.
Warning
During the configuration you will be asked to “Apply” your changes several times,
however this may affect the current connection. So don’t apply anything until completely
158
finished! You need to Save your changes for each step.
159
And disable filtering on member interfaces by changing net.link.bridge.pfil_member
from default to 0 in System -> Settings -> System Tuneables
160
Create a bridge of LAN and WAN, go to Interfaces -> Other Types -> Bridge :Add
Select LAN and WAN.
Go to Interfaces -> Assign -> Available network ports , select the bridge from the list
and hit +.
Now Add an IP address to the interface that you would like to use to manage the bridge.
Go to Interfaces -> OPT1 enable the interface and fill-in the ip/netmask.
161
5. Disable Block private networks & bogon
For the WAN interface we nee to disable blocking of private networks & bogus ip’s.
Goto Interfaces -> WAN and unselect Block private networks and Block bogon
networks.
Add the allow rules for all traffic on each of the three interfaces (WAN/LAN/OPT1).
This step is to ensure we have a full transparent bridge without any filtering taking place.
You can setup the correct rules when you have confirmed the bridge to work properly.
162
Goto Firewall -> Rules and add a rule per interface to allow all traffic of any type.
As we now have setup allow rules for each interface we can safely remove the Anti
Lockout rule on LAN
Goto Firewall -> Settings -> Admin Access :Anti-lockout and select this option to
disable
163
Now you can create the correct firewall/filter rules and apply them. To acces the firewall
you need to use the IP adress you configured for the OPT1 Interface.
Warning
Rules need to be configured on the bridge. Rules on member interfaces will be ignored!
Tip
Don’t forget to make sure your PC/Laptop is configured with an IP adress that falls within
the IP range of the OPT1 subnet!
164
Setup Caching Proxy
Enable / Disable
The proxy is delivered with sane default settings for easy setup. To enable the proxy just
go to Services->Proxy Server->Administration and check Enable proxy en click on
Apply. The default will enable the proxy with User Authentication based on the local
user database and runs on port 3128 of the lan interface.
165
changes.
Enable Cache
To enable caching click on the arrow next to the General Proxy Settings to see the
dropdown menu and click on Local Cache Settings.
Important
As the cache is not created by default you will need to stop and start the service under
Services->Diagnostics, this will ensure correct creation of the cache.
Advanced
Under the advanced settings (see mode switch on left top of the form) you can change
the cache size, directory structure and max object size to keep in cache. Again defaults
are fine for normal browsing and creates a 100MB cache with max 4MB object size.
166
Depending on the Authentication Servers you have setup under System->Access-
>Servers You can select one or more of the following:
LDAP
Radius
FTP Proxy
To enable the FTP Proxy Click on the arrow next to the Forward Proxy tab to show the
drop down menu. Now select FTP Proxy Settings and select one or more interfaces in
the FTP proxy interfaces field and Apply.
Note
The FTP proxy will only function if the Proxy Server itself is enabled. And the proxy only
works for non encrypted ftp traffic.
Setup Allowed Subnets (By default the proxy interfaces will be allowed)
167
Add Banned hosts IP address (A ban will stop this client from being able to use the
proxy)
Whitelist (Click on the (i) to see examples, whitelist prevail above blacklists)
Blacklist (If not allowed by a whitelist, this will block traffic based upon a regular
expression)
Warning
Don’t forget to press Enter or a comma after filling in a tag field as otherwise the value
will not be applied. It should look similar to:
http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml
101com.com
101order.com
123found.com
180hits.de
180searchassistant.com
1x1rank.com
207.net
247media.com
168
Control Lists
Now click on the + at the bottom right corner of the form to add a new list.
Fill in:
169
Save changes
Now click on Download ACLSs & Apply to enable the blacklist/ad blocker.
Action Block
Interface LAN
170
Protocol TCP/UDP
Save
Action Block
Interface LAN
Protocol TCP/UDP
171
Configure Browser/Firefox
To configure you browser for use with the proxy, just go to your network settings and
configure a proxy like this in firefox:
172
For a set-for-step guide on full category based web filtering see Setup Web Filtering.
173
Setup Transparent Proxy
OPNsense offers a powerful proxy that can be used in combination with category based
web filtering and any ICAP capable anti virus/malware engine. The proxy can be
configured to run in transparent mode, this mean the clients browser does not have to
be configured for the web proxy, but all traffic is diverted to the proxy automatically by
utilizing Network Address Translation.
In this How To, we will explain the basic http as well as https (ssl bump) transparent
proxy modes.
Warning
The Transparent SSL/HTTPS proxy mode uses a technique also called man-in-the-
middle, only configure and use this if your know what you are doing. When configured
wrong you may end up in lessing your security defenses significantly instead of
enhancing them. Using a transparent https proxy can be a dangerous practice and may
not be allowed by the services you use, for instance e-banking.
Then select General Forward Settings under the Forward Proxy Tab.
174
Select Enable Transparent HTTP proxy And Click Apply.
Interface LAN
Protocol TCP
Destination any
175
NAT reflection Enable
The defaults should be alright, just press Save and Apply Changes.
Click on add or import ca in the upper right corner of the screen to create a new CA.
176
State or Province Zuid Holland
City Middelharnis
Organization OPNsense
Save
Select Enable SSL mode and set CA to use to the CA you have just created. Then
Click Apply.
To enter a new item type in the field and hit enter to accept. start with a . (dot) to add all
subdomains as well. Example: To add all of paypal.com , type .paypal.com and hit enter.
Note
177
Make sure that all banking sites and sites that you provide personal or login information
for are added to this field. If you are not sure what to add, please reconsider using
transparent SSL as its clearly not intended for you!
Interface LAN
Protocol TCP
Destination any
178
Description redirect traffic to proxy
The defaults should be alright, just press Save and Apply Changes.
Import and change trust settings on your favorite OS. Per example on OSX it looks like
this:
179
Warning
Again be very careful with this as your system will accept any page signed with this CA
certificate. As long as no-one gains access to the private key that is no problem, but if
any one can get a get a hold of it then all traffic can be decrypted except those in the do
not bump list. You have been warned!
Note
180
On Android devices, you may get notified about the device being unable to access the
internet. This happens because the certificates are pinned to protect the connection
against man in the middle attacks otherwise trusted certificates. If you want to make the
connection work again, you have to whitelist the following Google domains in your “No
Bump Hosts” settings.
Your local Google domain (for example: google.at for Austria, google.de for Germany,
…)
.google.com
.googleapis.com
.gstatic.com
.1e100.net
DONE
181
Setup Web Filtering
Category based web filtering in OPNsense is done by utilizing the build-in proxy and one
of the freely available or commercial blacklists.
For this this How-to we will utilize the UT1 “web categorization list” [https://dsi.ut-
capitole.fr/blacklists/index_en.php] from the Université Toulouse managed by Fabrice
Prigent. This list is supplied for free under the Creative Commons license
[http://creativecommons.org/licenses/by-sa/4.0/].
Other popular lists that are expected to work well with OPNsense are:
Shallalist.de <http://www.shallalist.de/>
Free for personal usage and partly for commercial usage
URLBlacklist.com <http://urlblacklist.com/>
Commercial paid service
Squidblacklist.org <http://www.squidblacklist.org/>
Commercial paid service
We only want web filtering and nothing else (no caching, no authentication)
Note
For other general/basic setup item of the proxy see Setup Caching Proxy
182
Step 1 - Disable Authentication
To start go to Services->Proxy->Administration.
Click on the arrow next to the Forward Proxy tab to show the drop down menu. Now
select Authentication Settings and click on Clear All to disable user authentication.
And click Apply to save the change.
categories (Leave blank) If left blank the full list will be fetched
The URL of the full compressed UT1 category based list is:
ftp://ftp.ut-capitole.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
183
Press Save Changes.
184
For our example we will filter ads and adult content. The easiest way to do so is clear
the list and select the following from the drop down list:
Now Save changes and press Download ACLs again to download and reconstruct the
list with only the selected categories. This will take roughly the same amount of time as
the first fetch as the adult alone section is ~15MB.
It may take a while for the proxy to start and the play icon on the top right corner of the
screen will turn red. Refresh the page to see if the proxy is done loading (play icon will
turn green).
185
To make sure no-one can bypass the proxy you need to add a firewall rule. Go to
Firewall->Rules and add the following to the top of the list rule on the LAN interface (if
LAN is where your clients and proxy are on).
Action Block
Interface LAN
Protocol TCP/UDP
Save
Action Block
Interface LAN
Protocol TCP/UDP
186
Destination Port Range HTTPS
187
Setup Anti Virus Protection
OPNsense can offer http and https protection by utilizing its highly flexible proxy and the
industry standard ICAP. An external engine from one of the known vendors is used to
offer maximum protection against malware, such as ransomware, trojans and viruses.
This protection can be further enhanced by the build-in Intrusion Prevention System and
Category Based Web filtering.
This How To will utilize Symantec’s Protection Engine, but any other vendor that support
ICAP will work just as well.
Note
The Anti Virus Engine can protect you against malicious websites and infected file
downloads, it does not protect the local clients. Therefore it is always a good idea to
install a client based solution as well to protect against other forms of infection such as
through emails or usb stick.
188
Step 1 - Setup the Proxy
Start with setting up the proxy with its basic configuration, see Setup Caching Proxy.
189
Step 2 - Setup Transparent Mode
To setup the transparent mode, see: Setup Transparent Proxy.
We installed the Engine for Web Proxy purpose and enabled ICAP with its default
settings.
190
Step 4 - Connect the Engine
Now connect the server that the engine is installed on to OPNsense trough either a
switch or a direct cable connection. Preferable use a separate network for this traffic to
make sure the unencrypted ICAP traffic can’s be tapped.
Note
ICAP traffic is not encrypted, meaning you have to make sure the traffic is not visible to
anyone else. When using transparent https mode it is best to configure a separate
interface for ICAP traffic and connect the Server (Engine) directly with a crosslink cable.
Alternatively one may use a VLAN for this purpose.
191
Step 5 - Configure ICAP
To configure ICAP go to Services->Proxy->Administration And select ICAP Settings
for the Forward Proxy tab.
Select enable ICAP and filling the Request and Response URL’s. For Symantecs
Protection Engine the look like this:
First test the http protocol version and if that works the https version if you have also
configured the transparent ssl proxy mode.
Warning
If everything went well you should see something similar to this in you browser:
The content you just requested contains EICAR Test String and was blocked by the
Symantec Protection Engine based on local administrator settings. Contact your
local administrator for further information.
192
DONE
193
Configure CARP
Overview
One of the more powerful features of OPNsense is to set-up a redundant firewall with
automatic fail-over option. This chapter describes step by step how to create a set-up
based on two networks. The 192.168.1.0/24 will be used for the internal network and
172.8.0.0/24 will be used to route our traffic to the internet.
The configuration file (xml) for both firewalls can be downloaded from the wiki.
Terminology
194
There is some terminology involved in setting up a CARP cluster, which we will explain
briefly first:
CARP
Common Address Redundancy Protocol uses IP protocol 112, is derived from OpenBSD
and uses multicast packets to signal it’s neighbours about it’s status. Always make sure
that each interface can receive carp packets. Every virtual interface must have a unique
Virtual Host ID (vhid), which is shared across the physical machines. To determine which
physical machine has a higher priority, the advertised skew is used. A lower skew means
a higher score. (our master firewall uses 0).
pfSync
Together with CARP, we can use pfSync to replicate our firewalls state. When failing
over you need to make sure both machines know about all connections to make the
migration seamless. It’s highly advisable to use a dedicated interface for pfSync packets
between the hosts, both for security reasons (state injection) as for performance.
XMLRPC sync
OPNsense includes a mechanism to keep the configuration of the backup server in sync
with the master. This mechanism is called xmlrpc sync and can be found under System -
> High Availability.
Master
195
Go to interfaces, make sure you have all three interfaces assigned and setup the
following addresses and subnets:
LAN 192.168.1.10/24
WAN 172.18.0.101/24
PFSYNC 10.0.0.1
Next we need to make sure the appropriate protocols can be used on the different
interfaces, go to firewall -> rules and make sure both LAN and WAN accept at least carp
packets (see protocol selection). Because we’re connecting both firewalls using a direct
cable connection, we will add a single rule to accept all traffic on all protocols for that
specific interface. Another option is to only accept traffic to the GUI port and pfSync
protocol.
Backup
The backup server needs it’s own dedicated addresses, we will use these:
LAN 192.168.1.20/24
WAN 172.18.0.102/24
PFSYNC 10.0.0.2
Because we are going to synchronize firewall settings between both hosts, we only need
to make sure that the pfsync interface can accept data from the master for the initial
setup. Use the same rule as used for the master on this interface.
196
On the master node we are going to setup our Virtual IP addresses, which will also be
used for the backup node after synchronisation. Go to Firewall -> Virtual IPs and add a
new one with the following characteristics:
Type Carp
Interface WAN
IP addresses 172.18.0.100 / 24
VHID Group 1
Type Carp
Interface LAN
IP addresses 192.168.1.1 / 24
VHID Group 3
197
Advertising Frequency Base 1 / Skew 0
Go to Firewall -> NAT and select outbound nat. Choose manual outbound nat on this
page and change the rules originating from the 192.168.1.0/24 network to use the CARP
virtual interface (172.18.0.100).
Gateway 192.168.1.1
198
Setup HA sync (xmlrpc) and pfSync
First we should enable pfSync using our dedicated interface using the master firewall.
Go to System -> High Availability, enable pfsync and select the interface used for
pfSync. Next setup the peer ip to the other hosts address (10.0.0.2).
Now we need to configure the settings we want to duplicating to the backup server using
the xmlrpc sync option. For our setup we will enable the following:
Synchronize rules
Synchronize NAT
Synchronize DHCPD
Finalize setup
Just to make sure all settings are properly applied, reboot both firewalls before testing.
Testing setup
First go to Status -> Carp in the OPNsense webinterface and check if both machines are
properly initialized.
To test our setup, we will connect a client to the local area network and open a ssh
connection to a host behind both firewalls. Now when connected you should be able to
look at the state table on both OPNsense firewalls (Diagnostics -> States) and they
should both display the same connection. Next try to pull the network plug from the
199
master firewall and it should move over to the backup without loosing (or freezing) the
ssh connection.
Resources
Configuration for master server ( Carp_example_master.xml )
200
Setup IPsec Road-Warrior
Road Warriors are remote users who need secure access to the companies
infrastructure. IPsec Mobile Clients offer a solution that is easy to setup with OSX
(native) and is know to work with iOS as well as many Android devices.
For more flexibility use SSL VPN’s, OPNsense utilizes OpenVPN for this purpose.
With this example we’ll show you how to configure the Mobile Client Setup in OPNsense
and give you configuration examples for:
OSX
iOS
Android
Note
For the sample we will use a private ip for our WAN connection. This requires us to
disable the default block rule on wan to allow private traffic. To do so, go to the
Interfaces->[WAN] and uncheck “Block private networks”. (Dont forget to save and
apply)
Sample Setup
For the sample configuration we configure OPNsense
201
Company Network with Remote Client
Company Network
Hostname fw1
WAN IP 172.18.0.164
LAN IP 192.168.1.0/24
Protocol ESP
202
To allow traffic passing to your LAN subnet you need to add a rule to the IPsec interface.
IKE Extensions
Enable checked check to enable mobile clients
User Authentication Local For the example we use the Local Database
Database
Virtual Address Pool 10.0.0.0/24 Enter the IP range for the remote clients
You can select other options, but we will leave them all unchecked for this example.
203
Save your settings and select Create Phase1 when it appears. Then enter the Mobile
Client Phase 1 setting.
204
Pre-Shared Key At4aDMOAOub2NwT6gMHA Random key. CREATE YOUR
OWN!
Hash algoritm SHA1 SHA1 for compatibility, you can try a stronger hash
DH key group 1024 bit 1024 bit for compatibility, you can try stronger group
Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expire
205
Step 3 - Phase 2 Mobile Clients
Press the button that says ‘+ Show 0 Phase-2 entries’
Now press the + at the right of this list to add a Phase 2 entry.
General information
Mode Tunnel IPv4 Select Tunnel mode
Local Network
Local Network LAN subnet Route the local LAN subnet
206
Protocol ESP Choose ESP for encryption
Encryption algorithms AES / 256 For the sample we use AES 256
Save:
207
Step 4 - Add IPsec Users
For this example we will create a new user who may access the mobile IPsec vpn.
Go to System->Access->Users and press the + sign in the lower right corner to add a
new user.
Password &test!9T
Add privilege User - VPN - IPsec xauth Dialin by pressing the + under Effective
Privileges.
Save to apply.
208
Note
Configuration samples listed here where created using latest OSX, iOS and Android
devices on time of publication in February 2016.
Now select VPN and Cisco IPSec, give your connection a name and press Create.
209
Next press Authentication Settings to add the group name and pre-shared key.
Now test the connection by selecting it from the list and hit Connect.
210
Done
211
Name IPsec OPNsense Freely chosen name
Save and try connecting. To connect enter Username and Password for the user expert
we created in this example.
212
Setup IPsec site to site tunnel
Site to site VPN’s connect two locations with static public IP addresses and allow traffic
to be routed between the two networks. This is most commonly used to connect an
organization’s branch offices back to its main office, so branch users can access
network resources in the main office.
Note
For the sample we will use a private ip for our WAN connection. This requires us to
disable the default block rule on wan to allow private traffic. To do so, go to the
Interfaces->[WAN] and uncheck “Block private networks”. (Dont forget to save and
apply)
Sample Setup
For the sample configuration we use two OPNsense boxes to simulate a site to site
tunnel, with the following configuration:
Network Site A
213
Site A
Hostname fw1
WAN IP 172.10.1.1/24
LAN IP 192.168.1.1/24
Network Site B
Site B
Hostname fw2
WAN IP 172.10.2.1/24
214
Full Network Diagram Including IPsec Tunnel
IPsec Site-to-Site tunnel network
Protocol ESP
Note
You can further limit the traffic by the source ip of the remote host.
215
To allow traffic passing to your LAN subnet you need to add a rule to the IPsec interface.
General information
Connection method default default is ‘Start on traffic’
216
Peer identifier Peer IP address Simple identification for fixed ip
Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expire
217
Now you should see the following screen:
Now press the + at the right of this list to add a Phase 2 entry.
General information
Mode Tunnel IPv4 Select Tunnel mode
218
Local Network
Local Network LAN subnet Route the local LAN subnet
Remote Network
Type Network Route a remote network
Encryption algorithms AES / 256 For the sample we use AES 256
PFS Key group 2048 bit Not required but enhanced security
219
Save:
General information
Connection method default default is ‘Start on traffic’
220
Remote gateway 172.10.1.1 the public ip address of your remote
OPNsense
221
Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expired
222
Now press the + at the right of this list to add a Phase 2 entry.
General information
Mode Tunnel IPv4 Select Tunnel mode
Local Network
Local Network LAN subnet Route the local LAN subnet
Remote Network
Type Network Route a remote network
Encryption algorithms AES / 256 For the sample we use AES 256
PFS Key group 2048 bit Not required but enhanced security
223
Save your setting by pressing:
Save:
224
Note
If the tunnel did not come up, try to restart the service on both ends.
Sample configuration
For test purposes we used two OPNsense boxes integrated into one unit and a cross-
cable between the WAN ports.
225
[https://www.deciso.com/product-catalog/opn20322r/]
To route traffic the WAN interfaces have been configured to use a /16 segment and they
are each others default gateway. Other than that the sample is equal to this how-to.
Configuration Site A
Config.xml Site A
Configuration Site B
Config.xml Site B
Trouble shooting
Phase 1 won’t come up
That is a difficult one. First check you firewall rules to see if you allow the right ports and
226
protocols (ESP, UDP 500 & UDP 4500) for the WAN interface.
Common issues are unequal settings. Both ends must use the same PSK and
encryption standard.
Common issues are unequal settings. Both ends must use the same encryption
standard.
Note
If you are testing locally with your pc connected to one of the two test boxes as in the
sample configuration, then make sure you have no other network connections (f.i. wifi).
227
Setup SSL VPN Road Warrior
Road Warriors are remote users who need secure access to the companies
infrastructure. OPNsense uses OpenVPN for its SSL VPN Road Warrior setup and offers
OTP (One Time Password) integration with standard tokens and Googles Authenticator.
Tip
Did you know that OPNsense offers two-factor authentication throughout the entire
system? See for more information: Two-factor authentication
The main advantages of using SSL VPN for Road Warriors instead of IPsec are:
228
Easy setup on almost all mobile clients using OPNsense’s Client Configuration Export.
Fine grained access control by using multiple servers or Client Specific Overrides.
With this how-to we’ll show you how to configure OPNsense’s SSL VPN for road
warriors and give you configuration examples for:
Note
For the sample we will use a private ip for our WAN connection. This requires us to
disable the default block rule on wan to allow private traffic. To do so, go to the
Interfaces->[WAN] and uncheck “Block private networks”. (Dont forget to save and
apply)
Sample Setup
For the sample configuration we configure OPNsense
229
Company Network
Hostname fw1
WAN IP 172.18.0.129
LAN IP 192.168.1.0/24
Step 0 - Preparation
For our example we will use two factor authentication (2FA) and multi factor
authentication. So before we start with the SSL VPN configuration we will need an TOTP
server and a valid signing certificate authority.
Tip
230
You can also use the quick-search to jump right into the the Access Server configuration.
Try it by typing Ac… and see for yourself:
Now first change the Type to Local + Timebased One time Password Enter a
Descriptive name such as TOTP VPN Access Server
For our example we leave everything else default as we will be using Google’s
Authenticator and the defaults are correct for that.
When using other tokens you may need to change the Token length.
231
For our example we will use the following setting:
Country Code : NL
State or Province : ZH
City : Middelharnis
Organization : OPNsense
Create a Certificate
After creating the Authority we will also need a certificate. To create a new certificate, go
to System->Trust->Certificates and click add or import certificate in the upper right
corner of the form.
232
Fill in the form with (leave the rest default):
Country Code : NL
State or Province : ZH
City : Middelharnis
Organization : OPNsense
233
Adding a User
To add a new user go to System->Access->Users and click on the plus sign in the
lower right corner of the form.
Creating a user will be done in two steps, the first one is adding a basic user with a
username, password, TOTP seed and user certificate. The second step (after saving)
will be to activate the generated OTP seed with a Google Authenticator compatible app.
Username Donald
Certificate True
Click Save and you will be redirected to create the User Certificate. Fill in the Certificate
form with the following for our example (leave anything not listed on its presented
defaults):
234
Type Client Certificate
Click Save and you will be redirected to the User page. Now we will activate your newly
created seed with your Google Authenticator compatible app. To do so click in the Click
to unhide button in the OTP QR code row and you will get a QR code to scan with your
smartphone. See also: Configure 2FA TOTP & Google Authenticator
Note
The setting Hardware Crypto is not used for new systems equipped with AESNI, when
the aesni module is loaded it will be used automatically.
235
Protocol UDP
Interface WAN
236
Redirect Gateway Leave Unchecked
237
Force DNS cache update Leave Unchecked
Renegotiate time 0
Note
238
Step 2 - Firewall Rules
To allow SSL VPN client connections, we should allow access to the OpenVPN server
port on the WAN interface. When using multiple servers we need to open up each port.
For our configuration we only use one server accessible on udp port 1194.
Next we also need to allow traffic from the VPN clients to our LAN interface. For our
example we will allow client to access anything on our local area network, however you
may decide just to allow traffic to one or more servers.
239
Step 3 - Export Client Configuration
Mac OSX & Windows
For Mac OSX & Windows users we recommend using Viscosity from Sparklabs
(https://www.sparklabs.com/viscosity/). Viscosity is very easy to setup and use and
works well on both platforms.
Go to VPN->OpenVPN->Client Export and select the newly created VPN server from
the list. Leave everything default and Download the Viscosity Bundle from the list of
export options under Client Install Packages.
240
Now on your Mac or Windows PC unpack the bundle and import the Viscosity.visc file.
Double clicking it should be enough to get it imported. When asked for an application to
open the file with search and select Viscosity.
Import Configuration
In the password field enter your TOTP token first followed by your password.
241
Connected
Android
For Android users we recommend using OpenVPN for Android
(https://play.google.com/store/apps/details?id=de.blinkt.openvpn) from Arne Schwabe.
Go to VPN->OpenVPN->Client Export and select the newly created VPN server from
the list. Leave everything default and Download the inline Android configuration from
the list of export options under Client Install Packages.
iOS
For iOS users we recommend using OpenVPN Connect
(https://itunes.apple.com/us/app/openvpn-connect/id590379981) from OpenVPN
Technologies.
Go to VPN->OpenVPN->Client Export and select the newly created VPN server from
the list. Leave everything default and Download the inline OpenVPN Connect
configuration from the list of export options under Client Install Packages.
242
Clicking on the file should be enough to get it imported. When asked for an application to
open the file with, select OpenVPN Connect.
User certificate
Username/Password
Token (TOTP)
Go to VPN->OpenVPN->Servers and click on the pencil icon next to the server we just
created to change the 2FA to multi factor authentication.
Now change Server Mode to Remote Access (SSL/TLS + User Auth) and leave
everything else unchanged. Click Save on the bottom of the form.
Now when you go to the client exporter, you will see that each user is listed separately.
In our case we see Donald listed. Exporting and importing this configuration works
exactly the same as before, the only difference is that each user requires a User
certificate and therefore their own configuration.
243
244
Setup SSL VPN site to site tunnel
Site to site VPN’s connect two locations with static public IP addresses and allow traffic
to be routed between the two networks. This is most commonly used to connect an
organization’s branch offices back to its main office, so branch users can access
network resources in the main office.
Note
For the sample we will use a private ip for our WAN connection. This requires us to
disable the default block rule on wan to allow private traffic. To do so, go to the
Interfaces->[WAN] and uncheck “Block private networks”. (Don’t forget to save and
apply)
Sample Setup
For the sample configuration we use two OPNsense boxes to simulate a site to site
tunnel, with the following configuration:
Network Site A
245
Site A - Server
Hostname fw1
WAN IP 172.10.1.1/16
LAN IP 192.168.1.1/24
Network Site B
Site B - Client
Hostname fw2
WAN IP 172.10.2.1/16
246
Tunnel Network 10.10.0.0/24
For our example will use the following settings (leave everything else on its default):
Note
The setting Hardware Crypto is not used for new systems equipped with AESNI, when
the aesni module is loaded it will be used automatically.
Protocol UDP
247
Device Mode tun
Interface WAN
248
Step 2 - Copy Shared Key
To copy the newly created shared key, click on the pencil icon next to the newly created
SSL VPN server.
You will see the shared key, copy this and keep it safe!
Sample key:
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
0960c87c3aafa8f306fe270c1564380b
7922543563a17b5d2636b4ef9412dd09
9ad44974ca1b293963e0f8ac9cbdd97c
2c31bf35f0df45c9e928ccb033e6d51d
2caaec02d649ad081c68d7bc7d28030e
9182c9597a83024097bea860e52d9c66
1b9e0048fbf951ce8659bc56edb7f9a1
249
14f7740fc9231a3750557e02eb112712
ac4b9980d4c740ec96a4357f3940ed90
d1bbf8eed3de135c886fe2eff8e8b943
ab1f52b59def4c9ebeacc5eb48425189
c43887a6237c29e0724f5f45a0f70635
10680bec8bfb67c21bf2b4866268594c
9ba093668064f9a898e6a6ad103b401d
b2047132f0dc8db2230db38444d689fa
ddba46bf6f892ae90c59415f94b82750
-----END OpenVPN Static key V1-----
For our configuration we only use one server accessible on UDP port 1194.
250
Next we also need to allow traffic from the VPN client network (192.168.2.0/24). For our
example we will allow client to access anything on our local network(s), however you
may decide just to allow traffic to one or more IP’s.
251
You are done configuring Site A.
Now enter the following into the form (and leave everything else default):
Protocol UDP
252
Device Mode tun
Interface WAN
253
Now click on Save to apply your settings.
254
Done
255
Setup FreeRADIUS for accounting
Goal of this tutorial
This tutorial can be used to test your Captive portal setup with radius accounting, it’s not
intended to use for production setups (because we only use simple flat files for
everything). We used Ubuntu linux for this setup, a different operating system might
result in some paths being different.
User limits on the OPNsense firewall are set right after login, the Radius server should
tell the firewall how much resources are left for the user that logged in successfully. A
normal login sequence look like this:
[login] -> [send accounting start] -> [send interim updates while connected] -> [on logout,
send accounting stop]
Setup
To setup freeradius in ubuntu, execute the following command:
client 10.211.55.0/24 {
secret = testing123
256
shortname = test-network
}
append to /etc/freeradius/dictionary
uncomment sradutmp in the accounting section, to be able to use the radwho command.
Make sure the second and third lines are indented by a single tab character.
This should result in a user with a maxim use per day of 1800 seconds.
257
Test radius
For the initial test, it might be practical to debug the traffic going in and out from
Freeradius. The next steps help you start Freeradius in debug mode, without output to
console:
/etc/init.d/freeradius stop
freeradius -X
258
Setup Traffic Shaping
For this how-to we will look into these scenario’s:
Reserve dedicated bandwidth for a realtime traffic such as (hosted) Voice Over IP
(VOIP) server.
259
On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.
mask (Empty) Used for auto queueing, empty for our sample
mask (Empty) Used for auto queueing, empty for our sample
260
enabled Checked Check to enable the pipe
mask (Empty) Used for auto queueing, empty for our sample
mask (Empty) Used for auto queueing, empty for our sample
Create a rule for traffic directed towards the VOIP Server (Upload).
261
sequence 11 Auto generated number, overwrite only when
needed
Create a rule for traffic coming from the VOIP Server (Download).
262
destination any The destination ip to shape, leave on any
263
Create a rule for all other internet download traffic
Note
Be aware of the sequence! It is important to make sure the right traffic is passed to the
right pipe.
Screenshot Rules
264
Share bandwidth evenly
For this example we presume an internet connection of 10Mbps Download and 1Mbps
Upload that we want to share evenly over all users.
265
On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.
266
On the Queues tab click the + button in the lower right corner. An empty Edit queue
screen will popup.
267
On the Rules tab click the + button in the lower right corner. An empty Edit rule screen
will popup.
268
proto ip Select the protocol, ip in our example
Screenshot Rules
269
Limit bandwidth per user
For this example we will divide the internet Download traffic between the connected
users in such manner that each user will receive up to a maximum of 1Mbps.
270
Create Pipe For Download
271
destination 192.168.1.0/24 The destination ip to shape, select LAN network
Note
If you want to limit traffic for a single ip then just enter the ip address in the destination
field instead of the full LAN network range.
Screenshot Rules
272
Prioritize using Queues
By utilizing queues we can influence the bandwidth within a pipe and give certain
applications more bandwidth than others based on a weighted algorithm.
The idea is simple: Let presume we have a pipe of 10Mbps and 2 applications for
instance smtp (email) and http(s). The http(s) traffic will get a weight of 1 and the smtp
traffic a weight of 9, then when all capacity of our pipe is in use the email traffic will get
9x more bandwidth than our http(s) traffic, resulting in 1Mbps for http(s) and 9Mbps for
smtp.
For our example we only look at download traffic, but the exact same can be done for
the upload traffic.
Minimum
Application Weight
Bandwidth
273
SMTP (port 25) 9 9Mbps
HTTPS (443)
274
Create Queue for SMTP
275
Create a rule for smtp download traffic (email)
276
src-port http The source port to shape, http or 80
Adding an extra rule for https traffic is simple as we can use the same http queue if we
like:
277
description ShapeHTTPSDownload Enter a descriptive name
This way http and https traffic will be treated the same (total max of 1Mbps).
Screenshot Rules
278
Multi Interface shaping for a GuestNet
One of the options with OPNsense’s traffic shaper is its ability to add shaping rules
based upon two interfaces. This option allows you to shape traffic differently based on
the direction the traffic is moving between interfaces.
For this example we will use this functionality to share a symmetric 10Mbps internet
connection between a primary LAN network and a Guest Network.
The LAN network will not be limited, traffic from users on our Guest Network will be
limited to a total of 2Mbps Download and 1Mbps Upload.
279
will popup.
280
will popup.
281
Create a rule for the upload traffic
282
283
Using Insight - Netflow Analyzer
OPNsense is equipped with a flexible and fast Netflow Analyzer called Insight. To use
Insight, one needs to configure the Netlfow exporter for local capturing of Netflow data.
To do so take a look at Configure Netflow Exporter.
User Interface
Insight is a fully integrated part of OPNsense. Its User Interface is simple yet powerful.
284
Insight offers a full set of analysis tools, ranging from a graphical overview to a csv
exporter for further analysis with you favorite spreadsheet.
View Type
285
One can show the traffic flows in a stacked manner (default), as a stream or expanded
to compare usage with different interfaces.
Stacked
Stream
Expanded
Interfaces
286
Clicking on an interface disables or enables the graph view, double clicking select only
that interface.
Top Users
The top 25 users are shown for a selected interface, both for ports and ips within the
previously selected date range.
Interface Top
Select the interface to see the top 25 users.
Clicking on a piece of the pie will open a detailed view for further analysis.
287
288
IP Addresses Pie Chart
The IP addresses pie chart works the same as the ports pie chart and shows the
percentage per ip number. One can change the view by clicking or double clicking on
one of the shown ip numbers.
Clicking on a piece of the pie will open a detailed view for further analysis.
Interface Totals
Not shown in the screenshot but latest version also includes a Total for the selected
interface, shown are Packets (In, Out, Total) and Bytes (In, Out, Total).
Details View
One can open the details view by clicking on one of the pieces of a pie chart or click on
the tab Details.
When opening the details view by clicking on the tab one can make a new query.
After selecting a valid date range (form/to) and interface one can further limit the output
289
by filtering on port or ip address. Select the refresh icon to update the detailed output.
Leave Port and Address empty for a full detailed listing.
Export View
The Export view allows you to export the data for further analysis in your favorite
spreadsheet or other data analysis application.
290
To export data, select a Collection :
Then select a date range (from/to) and click the export button.
291
292
293
Configure Netflow Exporter
Select all Interfaces you want to collect/export data from, usually one would select all
available interfaces here.
If you do not want to record traffic originating or going to the firewall itself then add the
interfaces to Egress only to prevent double counting of the same traffic flow (See also
Netflow Export & Analyses for more information).
Depending on the application you would like to use select Version 5 or 9. Remember
that version 5 does not support IPv6.
294
Add your Destinations (ip:port then enter) local ip will be added automatic if Capture
local is selected.
295
Configure 2FA TOTP & Google
Authenticator
This how-to will show you how to setup a One-time Password 2 Factor Authentication
using OPNsense and Google’s Authenticator. All services of OPNsense can be used
with this 2FA solution.
296
Note
297
To use the same feature with any time based one-time password token just enter the
seed into the field in step 3 instead of creating a new seed. The seed needs to be in
base32 format.
298
the plus sign in the lower right corner.
Enter a Username and Password and fill in the other fields just as you would do for any
other user. Then select the Generate new (160bit) secret under OTP seed.
299
Warning
Be very careful with the seed or QR code as this is the only thing you need to calculate
the token. KEEP YOUR SEED/QR CODE SAFE !
Now open your Google Authenticator compatible application and select the option to
start the configuration and then scan the QR code or alternatively enter the seed directly.
300
Pull down to open the application menu and choose the entry to add a new Token.
301
302
In the next step, you have to scan the previously created QR code by clicking on the
screen.
303
When the QR code is scanned, a new view will open where you can see the details of
the result. This view can be used to check if the generated key and OTP settings of the
scan results do match your settings. Confirm if everything is ok by clicking “Add”.
After this step, you will be back on the home screen of the app and will get a Token for
30 Seconds.
Please note that there are many apps to generate the token. Some well known are:
304
Step 5 - Test the token
For testing the user authentication, OPNsense offers a simple tester. Go to System-
>Access->Tester
Select the Authentication server you have configured, and enter the user name. Then
enter the *token + password, remember the order is token and then password in the
same field.
Note
Password field should be used to enter both token and your password, like: Password:
123456PASSWORD when the default configuration is used. The OTP authentication
server can also be configured to have it in the reverse order like PASSWORD123456.
Hit the test button and if all goes well you should see successfully authenticated.
305
Step 6 - Using the token
To use the token in any application/service that you have configured, just open the
Google Authenticator and add the created token/key before your regular password.
Warning
Remember, you need to enter the token before or after you password (depending on
your configuration)! And the password field should be used to enter both token and your
306
password, like: Password: 123456PASSWORD
307
308
Configuring Cellular Modems
OPNsense supports a wide range of USB and miniPCIe cellular modems that can be
used as primary internet (WAN) connection or as failover for a fixed/ethernet connection.
With this guide we show you how to easily add a new modem and configure it to be
used as primary WAN connection.
Note
Fill in the form like this (Example is for Dutch Mobile 4G KPN Subscription):
309
Service Provider Select Country, Provider & Plan for auto configuration
310
311
Step 2 - Assign the WAN interface
To assign the interface go to Interfaces->Assignments in our case we will make this
our primary internet connection and change the WAN assignment accordingly.
To do so just change the Network port for WAN to ppp0 (/dev/cuaU0.0) - 4G Cellular
Network.
If everything went fine then your are all setup and the default gateway will be the one of
you cellular connection.
312
Step 3 - Trouble shooting
Ok, so it doesn’t work as expected. In that case, first look at the log of the cellular
device’s PPP connection, to do so go to: Interfaces->Point-to-Point->Log File. Often
you can see what went wrong directly in the log.
If you can’t figure out what is wrong then a reboot to reinitialize the device can
sometimes help.
Note
Before booting your device it is best to make sure the SIM card is inserted correctly.
When the device seems to work properly then checkout if the interface was assigned an
IP address, go to Interfaces->Overview and click on the WAN interface to see the
details.
You should see an IP address, Gateway IP and ISP DNS server(s). If all is filled in then
either your firewall is blocking the traffic or the network connection is not working well.
313
IPv6 For Zen UK
Original Author: Martin Wasley
Introduction
Zen provide two methods of setting up IPv6.
The first method is a simple DHCP method which should suffice most users, the second
allows you to set up static IPv6 on both WAN and LAN. In either case the addresses and
prefixes are constant and even under DHCP will not change. Currently Zen provide a /64
WAN address and a /48 prefix allocation. These will have been given to you by Zen
when you request IPv6.
WAN Interface
Zen use PPPoE in the initial V4 connection, so enter PPPoE as the V4 connection type
and set the username and password for the PPPoE connection, for IPv6 using DHCP,
select DHCPv6 in the IPv6 connection as shown below.
314
The next step is to configure the parameters required for DHCPv6, these are located in
the DHCPv6 client configuration section of the WAN interface shown below.
315
As stated before, Zen provide a /48 prefix, so select the prefix size accordingly. We
directly send the solicit as in this case we do not wish to wait for an RA from the Zen
gateway.
The only other requirement in this section is to select ‘Use IPv4 connectivity’, this is
because the IPv6 traffic is routed over the PPPoE link.
In the example above, ‘Enable debug’ is selected, this adds extra dhcp6c logging
information to the DHCP logs, this is optional.
316
Click ‘Save’ and then ‘Apply’.
LAN Interface
All that is required now is to set the LAN interface to use assigned IPv6 prefix.
Select Interfaces->LAN and set the IPv6 Configuration Type to ‘Track Interface’
Finally, set the Track IPv6 Interface to WAN, unless there is a special requirement which
this document does not cover, set the IPv6 Prefix ID to 0.
317
Click ‘Save’ and then ‘Apply’.
We can take advantage of the link-local that is automatically set up between our router
and the Zen BNG, we do not need to know specific gateways at the Zen end, it all gets
routed automagically, however we do need to set up all of our static assignments, and
our DHCPv6/RADVD servers.
Create Gateway
Firstly, we do need to set up a gateway, this is for monitoring more than anything else.
Select Gateways->All then click ‘Add Gateway’.
Now, we know that Zen give us a /64 on our WAN interface, for example.
318
2a02:8231:d256:318::/66
Pick an address, we’ll use ‘1’, so our WAN address 2a02:8231:d256:318::1, it’s also
going to be our gateway.
We will also add a target IP for our monitor, the target will be a global WAN address of
something. You can use the Google v6 DNS server address if you wish. If no monitor is
given the gateway address is used, which can check gateway health status but may or
may not indicate access to the Internet.
319
320
Click Save.
WAN Interface
Once we have our gateway in place we can then set up the WAN interface. Select
Interfaces->WAN.
Tip Use the same address as found when setting the system up to use DHCPv6.
Select Use IPv4 connectivity, all IPv6 traffic goes via the PPPoE link.
321
Finally, select the IPv6 Upstream Gateway, this is the gateway you created earlier.
LAN Interface
The LAN interface is very simple to set up, all we need to do is set the IPv6
Configuration Type to Static, and enter our static address.
322
Zen give us a /48 prefix to use on the LAN, so pick an address from that range. For
example our prefix is:
2a02:8242:55AB::
So
323
We want to use a /64 prefix on this interface.
Tip Use the same address as found when setting the system up to use DHCPv6.
DHCPv6 Server
When using DHCPv6 on the WAN, our DHCPv6 LAN server is set automatically,
however when using statics, we need to set it up. Goto Services->DHCPv6[LAN]
324
You will notice that the subnet already has a range, and the subnet mask is the /64 we
set on the LAN. There is also a range we must use, the available range tells us what that
can be.
Enter the lower – start range that the server will use
2a02:8231:d256::eeee:0000:0000:0001
Enter the upper – end range that the server will use.
2a02:8231:d256::eeee:ffff:ffff:ffff
This should cover most LAN subnets, the range given here gives 281,474.976.710,655
addresses.
We can also set up a prefix delegation range, this is used where we have sub routers or
VLAN’s that need their own range. In the case of prefixes, we are only interested in the
upper 64 bits, as in this example we will only be giving out 64 bit prefixes. We know we
have been given a /48 prefix by Zen, so we enter our prefix range like this:
325
Our prefix range is the upper 48 bits, plus some of the next 16 bits, but we must not
cross into the range we have used for our LAN addresses. In the example above I have
allowed for up to 254 /64 subnets.
326
c-icap
Installation
First of all, you have to install the c-icap plugin (os-cicap) from the plugins view.
After a page reload you will get a new menu entry under services for C-ICAP. Select it
and you will get to the following screen:
327
General Settings
Enable c-icap service
Enable the C-ICAP service to handle ICAP requests.
328
Timeout
The time after which the socket will be closed.
Start servers
The count of the server processes which will be spawned.
Max servers
Limit the count of processes
Listen address
The address in which the server should be bound. This address is usually the loopback
address (::1 for IPv6 or 127.0.0.1 for IPv4). The default value is ::1.
Server admin
This field should be set to an email address which acts as a contact for users, who are
having issues with the server. A good idea would be an address, which converts the
mails to your internal ticket system.
Servername
If you want to override the server name (displayed on error pages), you can enter it
here.
Antivirus
329
Enable ClamAV
Enables the virus -scan plugin of c-icap-modules using ClamAV
330
A 204 response has the advantage, that the data don’t have to be sent over the wire
again. In case of a preview, no more data will be sent to the ICAP server and the data
will be forwarded to the client. In case of all data has been received by the ICAP server,
the data does not need to be sent back. Please note, that the ICAP client has to support
204 responses.
Pass on error
In case the scan fails, the file can be passed through. This is less secure but keeps the
business running in case of failure. Keep in mind that this may put your network at risk.
331
ClamAV
Warning
Your machine needs at least 1.5 GB RAM. Otherwise the machine will run out of
memory and crash because of out of memory kills. Using a machine with at least 2 GB
RAM is recommended.
Warning
There are some techniques to avoid detection and scanning using AV software and not
every malware is known by AV products. Signature based AV software can decrease the
risk of getting hit by a known malware but it does never guarantee that your computers
don’t get infected. It is important to teach the users how to handle files from the internet
and untrusted devices safely. Also plan a regular Backup of important files, make sure,
that ACLs are used correctly and apply patches asap to keep the attack surface and
damage as small as possible.
Note
To make ClamAV working, you need to download signatures. Please note that those files
need to be fetched after a reboot again if they are stored on a ram disk.
Installation
First of all, you have to install the ClamAV plugin (os-clamav) from the plugins view.
332
After a page reload you will get a new menu entry under services for ClamAV. Select it
and you will get to the following screen:
333
Configuration Options
334
Enable clamd service
Selecting this checkbox enables clamd so you can use it to scan files.
Idle Timeout
The connection will be dropped if it is inactive for this amount of time. If the other socket
endpoint is a machine, this value can be low but if you plan to use it for develpoment
reasons, you may set it to a higher value.
335
Follow regular file symlinks
If this is checked, clamav will follow symlinks to regular files. This may expose
information about the filesystem, the user should not have access to.
Disable cache
If you check this, the results are not cached. This is only useful in develpoment
environments as it slows down the response time.
Scan OLE2
If this is checked, OLE2 files (for example Microsoft Office files) will be analyzed. Such
files should be analyzed as they may contain macros which have been used to
download and install malware (usually ransomware).
336
If this checkbox is checked, PDF files will be scanned. PDF files can carry other files or
multimedia as well as javascript and fonts. Scanning PDF files is recommended.
Scan SWF
If you check this box, Flash files will be scanned. Flash is used to provide video players
or interactive content. Nowadays it should have been replaced by HTML5.
Scan XMLDOCS
Scan XML Documents
Scan HWP3
HWP seems to be a korean document format. If you don’t use them, it is better to block
them in the proxy than scanning them. If you have them in use, you should scan them.
Scan HTML
Scans HTML files which may have dangerous embedded JavaScript.
Scan archives
Scan files inside archives. This is very important as archives can contain malware.
Please note that archive nesting is used to bypass scans, so scanners detect such
archives as dangerous at a specific recursion level. Also keep in mind that zip bombs
may be possible to DoS a scanner.
337
7z can derive a key from a password given by the creator of the file, which will be used
to encrypt the compressed data. The ClamAV cannot scan this data as it is missing the
key/password. Some malware authors used encrypted archives to avoid scanning and
told the victim in the email text how to unpack it.
338
Dynamic Routing: How To
Note
To keep this tutorial short, a configuration is only added a single time. For example, the
configuration of Site A and Site B are identical beside one octet in the IP addresses.
Also both routers have the same configuration except the Network address of the uplink
and the client network.
Situation
We have two sites (Site A and Site B) which are connected via a layer 2 VPN. Each site
has two additional routers, which are connected to the edge router and with each oder.
On those routers, the clients are attached.
339
Configuration
In this setup, OSPF is used. All routers belong to the area 0.0.0.0 and no prefix lists are
used.
Setting Value
Enable Checked
Networks:
192.168.0.0 30
192.168.1.0 30
192.168.1.4 30
340
General Settings:
Setting Value
Enable Checked
Networks:
10.1.1.0 24
192.168.1.4 30
192.168.1.8 30
341
Dynamic Routing: Configuration:
OSPFv2
General
Warning
Saving the settings will apply them and reload the daemon. This means you may lose
the connection to your firewall for some seconds.
Enable
342
Enables the OSPF routing daemon. If this does not work, please check the settings of
General. Check this checkbox if you want to use OSPFv2 in your network.
Passive Interfaces
Passive Interfaces are interfaces, which exist in OSPFv2 but where no routing updates
should be sent to. These are usually the Interfaces, where your clients are connected to
and no router should exist. You don‘t need to add interfaces here, where no network is
specified.
Route Redistribution
Route Redistribution is used, if you want to send information this router has learned via
another protocol or routes from kernel (OPNsense static routes).
Networks
343
Networks gives you a brief overview of the configured networks. The dialog looks like
this:
Enabled
Enabled means that this Network is going to be used. You should only disable networks
if you plan to do some changes in your topology or some routes get broken.
Network Address
344
The Network Address of a local interface on which OSPFv2 should be enabled.
Network Mask
A CIDR Mask for the Network Address. For example, if your LAN IP is 192.168.0.1/24,
the network address is 192.168.0.0 and Network Mask is 24.
Area
The area describes which routers belong to the same group (autonomous system). This
value is a 32 bit integer, which is entered in dotted decimal notation (like an IPv4
address is usually written).
Interfaces
This tab shows an overview of the configured interfaces:
Note
345
Changes in this view do NOT apply the settings.
Interface
Choose a single interface, where this interface settings apply to.
346
This values can be set, but they are not used as there is no area configuration which
would make use of them. You may want to set the password here if you add a custom
area setting via vtysh.
Cost
A numeric value to set the cost on an interface. The cost is used to calculate the route to
the target. A bigger value here means, the route is less likely used.
Priority
This field specifies the router priority which means a router with a good priority is more
probably the designated router. Network type usually does not need to be set.
347
Dynamic Routing: Configuration: RIP
Note
RIP should not be used in larger networks due to the limited hop count. Cosider using
OSPF in such cases.
Warning
Saving the settings will apply them and reload the daemon. This means you may lose
the connection to your firewall for some seconds.
RIP is a well known distance vector protocol. It may be preferred to be used in smaller
networks, where the topology is not too complex and the possibillity of loops is small.
348
Enable
enables the routing protocol if the support of routing protocols is enabled in general. If
you check this box, RIP will be enabled.
Version
Enter 1 or 2 here. 1 is “classful” which means, that this routing protocol does not support
variable length routing. If you choose version 2, variable length subnet masks are
supported. In most cases, you want to choose version 2 here.
Passive Interfaces
349
Interfaces, which are known by the routing daemon, but no updates are sent. You should
add interfaces with networks here, which do not have any other routers.
Route Redistribution
Also send routes from other sources to neighbors (if desired).
Networks
Add the networks here which should be known by the router and which are subject to be
sent to the neighbors. Passive interfaces will not be used to look for another router.
350
Dynamic Routing: Configuration:
Zebra
Zebra is the core of quagga and needs to be enabled in any case. It can be enabled in
the general view:
Note
If this service is disabled, all other routing protocols are disabled too.
Warning
Saving the settings will apply them and reload the daemon. This means you may lose
the connection to your firewall for some seconds.
Enable
Checking „Enable“ means that zebra and all other enabled routing daemons will be
started. If you disable this checkbox, Quagga will be completely disabled.
351
Create a logfile and Logfile level
If you check this checkbox, messages with a higher or equal severity will be written to a
log file on this device. You can view this log file under diagnostics if you want to debug
errors in your network.
352
Configure Spamhaus (E)DROP
The Spamhaus Don’t Route Or Peer Lists
DROP (Don’t Route Or Peer) and EDROP are advisory “drop all traffic” lists, consisting
of netblocks that are “hijacked” or leased by professional spam or cyber-crime
operations (used for dissemination of malware, trojan downloaders, botnet controllers).
The DROP and EDROP lists are a tiny subset of the SBL, designed for use by firewalls
and routing equipment to filter out the malicious traffic from these netblocks.
Source : https://www.spamhaus.org/drop/
For this how to we will use the Alias feature and a firewall block rule. The lists for this
example are located here:
353
Host(s) https://www.spamhaus.org/drop/drop.txt Don’t Route Or Peer List
Set the update frequency to 1 for each day. Press Save and then Apply changes.
354
Step 2 - Firewall Rules Inbound Traffic
We will block incoming connections and outgoing connections for the drop and edrop
lists. To do so we will start with inbound traffic on the WAN interface. Go to Firewall-
>Rules Select the WAN tab and press the + icon in the lower right corner.
Enter the following configuration and leave all other parameters on default values:
355
Category Spamhaus Freely chosen Category
356
Save
357
Destination spamhaus_drop Our alias for the DROP list
358
DONE
Check pf Tables
To list the ip addresses that are currently in the DROP and EDROP lists go to Firewall-
>Diagnostics->pfTables and select the list you want to see:
359
360
361
FreeRADIUS
Installation
First of all, you have to install the FreeRADIUS plugin (os-freeradius) from the plugins
view.
After a page reload you will get a new menu entry under services for FreeRADIUS.
Select and a submenu will pop up with the entries General, User and Client:
General Settings
362
Enable
To enable the service, you have to check this box.
Users
363
A user is an entity, which is meant to authenticate against the RADIUS server (computer
or human).
Enabled
This user will be written to disk and can be used. You can toggle this value to temporary
disable users.
364
Username
The name which the user will use to authenticate.
Password
The password the user will use to authenticate.
Description
Internal information for you to use to find the user. This setting can be used to add some
infos like a department.
VLAN ID
A layer 2 device like a switch, which supports 802.1X authentication can use this Field to
dynamically assign an VLAN number to a switchport based on the authentication result.
This is especially useful if you are having moving users (for example if an employee can
attach his computer to a docking station at a desk and the switch will assign the VLAN
ID of the employee to the switchport. Be aware that the Layer 2 device has to be able to
read this information, which means that you have to enable corresponding option in
General
Clients
365
A client in RADIUS is a intermediate device / network device like a VPN gateway, a
switch or an access point.
Enabled
This client will be written to disk and can be used. You can toggle this value to temporary
disable clients.
Name
A name used for the client.
366
Secret
The secret is used to provide a trust relationship between the client and the
FreeRADIUS server. This password should be strong as you only have to type it twice
(once in the FreeRADIUS configuration and once in your client configuration) or even
copy it. If the passwords do not match, FreeRADIUS will reject all attempts to
authenticate.
367
Setup a Guest Network
This how to will explain how to setup a guest network using the captive portal. Guest
Networks are widely used to allow guests controlled internet access at hotels, RV Parks
or businesses.
Note
For the example we expect the GUESTNET interface to be connected with your actual
guest network switch or access point. This tutorial does not explain how to setup a
wireless network.
Businesses
Businesses usually want to share internet access with their guest and show them a
landing page with a welcome message and some usage guidelines (policy). At the same
time it is important to make sure guests won’t be able to access the company’s local
network and limit the maximum internet usage.
368
Hotels and RV Parks
Hotels and RV parks usually utilize a captive portal to allow guests (paid) access to
internet for a limited duration. Guests need to login using a voucher they can either buy
or obtain for free at the reception. OPNsense has build-in support for vouchers and can
easily create them on the fly. With this example we will show you how to setup the Guest
Network for this purpose and setup a reception account for creating new vouchers.
Advanced
The Captive portal can also be combined with the category based web filtering of the
proxy. This tutorial will explain how to combine both features.
Prerequisites
We will start configuration with a fresh OPNsense install, updated to the latest patch
level (16.1.5_1 in our example). You will need a system with a minimum of 3 ports
(LAN/WAN/GUESTNET) for this tutorial.
Good to know
As the Hotel/RV Parks setup is almost identical to the business setup we will start with
that and after finishing add/change the specifics to match the Hotel Guest setup.
369
Select Enable Interface and fill in the following data for our example:
IPv4 Configuration Type Static IPv4 Set a static IPv4 address for the example
Speed and duplex Default You may also select the speed when
known
Static IPv4 address 192.168.200.1/24 We will use this segment for our guests
370
Fill in the following to setup the DHCP server for our guest net (leave
everything
else on its default setting):
Click Save.
Allow DNS
Allow the guests access to the DNS forwarder. Rule content (leave all other options
default):
371
Protocol TCP/UDP
Click Save.
Protocol TCP
372
Description Allow Captive Portal
Login
Click Save.
Protocol any
Click Save.
Protocol any
373
Source GUESTNET net
Click Save.
Note
These rules are used to block access to our local LAN network and firewall access from
the Guests. If you have multiple local networks then you need to block each of them with
multiple rules or use a bigger subnet to cover them all.
Protocol any
Destination any
374
Category GuestNet Basic Category used for grouping rules
Rules
375
Step 4 - Create Captive Portal
Go to Services->Captive Portal->Administration
To add a new Zone press the + in the lower right corner of the form.
376
Note
When using multiple interfaces with the captive portal then each interface can have its
own zone or multiple interfaces can share a zone.
For the Business setup we will start with the following settings:
Enabled Checked
377
Step 5 - Create Template
The template feature is one of the most powerful features of OPNsense’s Captive Portal
solution and it’s very easy to work with.
Lets create a custom landing page, to do so click on the tab Templates and click on the
download icon in the lower right corner ( ).
Now download the default template, we will use this to create our own. Unpack the
template zip file, you should have something similar to this:
Most files of the template can be modified, but some are default and may not be
changes. Upon upload any changes to the files listed in exclude.list will be ignored.
Currently these include the bootstrap java scripting and some fonts.
With the captive portal enabled the default screen looks like:
378
Lets change this default with a new logo and a welcome message, to this:
379
To do so use your favourite editor and open the index.html file to make the changes.
<header class="page-head">
<nav class="navbar navbar-default" >
<div class="container-fluid">
<div class="navbar-header">
380
<a class="navbar-brand" href="#">
<img class="brand-logo" src="images/default-logo.png" height="30" width=
</a>
</div>
</div>
</nav>
</header>
<header class="page-head">
<div align="center">
<a href="#">
<img class="brand-logo" src="images/company-logo.png">
</a>
<h1>Welcome to My Company Guest Network.</h1>
<h2>Feel free to use the guest network for profesional usage</h2>
<h3>See our website for more details: <a href="https://www.opnsense.org">My Company
</div>
</header>
Copy the company logo to the image directory. Now zip the template directory and
upload the new template by pressing the + on the Template tab.
Enter a Template Name, for this example we use Company. Hit Upload ( )
To enable the captive portal on the GUESTNET interface just click on Apply.
381
For our example we will reserve 10Mbps down and 1Mbps Up for the Guest Network’s
Internet Access. This bandwidth will be shared evenly between connected clients.
Note
With sharing evenly we mean that if 10 users at the same time try to use as much
bandwidth as possible then everyone gets 1/10th. So in our example that would be
1Mbps down stream (download). It is also possible to limit the traffic per user see also
Setup Traffic Shaping
Create a pipe for the Download by pressing the + in the lower right corner of the form
and enter the following details:
Enabled Checked
bandwidth 10
mask Destination
Description pipe_10Mbps_down
Click on Save changes. And add another pipe for the upload traffic.
Enabled Checked
bandwidth 1
382
bandwidth Metric Mbit/s
mask Destination
Description pipe_1Mbps_up
Create the traffic shaper rules.Click on the tab Rules and press the + to do so.
First toggle the advanced mode (upper left corner of the form) and then fill in the
following details (leave everything not specified on defaults):
interface WAN
interface 2 GUESTNET
direction in
target pipe_10Mbps_down
interface WAN
383
interface 2 GUESTNET
direction out
target pipe_1Mbps_up
To test your traffic shaper go to a speed test site such as http://www.speedtest.net/ After
testing your result should be similar to this (if your internet connection has sufficient
bandwidth).
Note
Keep in mind we have only one connected client in this test, so all reserved bandwidth
will be available for our client.
384
Royal Hotel Example
From this point we will implement the Hotel/RV Park solution. You need to follow step 1-
7 first and choose the template you like to use for your guests.
Fill in:
Type Voucher
Click on Save.
385
Enter the Validity (1 day), the number of Vouchers and a Groupname (Wifi day pass f.i.).
For the example we create 10 vouchers. Click on Generate.
A file will be generated called wifi day pass.csv. The content of this file looks like this:
username,password,vouchergroup,validity
"IgJw@Pqf","MLi+Sb7Ak#","Wifi day pass","86400"
"++?f[@i[","!m*)e(@;F,","Wifi day pass","86400"
"bbtK9mBk","f/jCDL3:)b","Wifi day pass","86400"
"iD%L[jLJ","I#FoZ#g!AY","Wifi day pass","86400"
"+4bA\E[I","CNavt@0ck+","Wifi day pass","86400"
"+,fg/\Sv","#22iIL-iQA","Wifi day pass","86400"
":;Pc\N#s","Y\HuG9vAN$","Wifi day pass","86400"
"00nLb=0Q","0*C_\_Nb_x","Wifi day pass","86400"
"PA$J0YHF","kp!q%9;m)g","Wifi day pass","86400"
"a,mCxbya","LcnCb#g/di","Wifi day pass","86400"
386
password Password the guest needs to login with
Warning
For security reasons the plain text password for the vouchers are NOT stored on the
firewall.
This file can be used for creating nice guest vouchers (on paper) by just merging the cvs
data with word, open office or any other dtp/text editor.
387
You can select a database to and remove it entirely. This way you can create a voucher
388
database for the arrival date of guest per guest group (week, midweek, weekend, etc.)
and delete the full database when the guests have left.
Note
When a voucher is activated the time will be used regardless of the user being logged in
or out. For a “used time” solution use a Radius server look at Setup FreeRADIUS for
accounting
When done click Save changes and the Apply to apply the new settings.
Now users will see the login form as part of your template:
Check Sessions
To check the active sessions go to Services->Captive Portal->Sessions Our current
389
session looks like this:
Note
Notice the selection box at the upper right corner, with this you can select the right zone
when you have configured more than one.
390
Note
In particular we will use the following api call (for zone id 0):
/api/captiveportal/access/status/0/
The response on this api call looks like this (for an active session):
{"userName":"IgJw@Pqf",
"macAddress":"10:dd:b1:bc:75:46",
"acc_session_timeout":14095,
"authenticated_via":"Vouchers",
"packets_out":2834,
"bytes_in":512869,
391
"last_accessed":1457527526,
"zoneid":0,
"sessionId":"npd5bd6SIVQeMfIbWBdong==","
startTime":1457526930.1719,
"bytes_out":1322351,
"ipAddress":"192.168.200.100",
"packets_in":3181,
"clientState":"AUTHORIZED"}
It would go a bit to far to explain standard html and java scripting used for our simple
popup, but a full demo template can be downloaded:
The demo includes a new file called session_popup.html with all the logic to show the
time left on the voucher and a logout button. As well as a simple update to our
index.html page to call the popup on a successful login. The latter looks like this (shown
with a bit of context):
392
Advanced - CLI Session Status
OPNsense has a very powerful CLI that is particularly useful for debugging purposes.
For this example we will use the cli to list the status off all active sessions.
393
394
HAProxy
Installation
First of all, you have to install the HAProxy plugin (os-haproxy) from the plugins view.
395
On the “Servers” page, click + to open a dialog to create a new server. A server consist
of a name, IP and port. Create an entry for every Server you want to load balance.
396
(checked)
397
Note
The “Balancing Algorithm” field is important to care about as many web applications
depend on a state. For example, if your web application stores session data on a local
disk, you may get some trouble when using an algorithm like Round Robin. In such a
398
case, the request of the same client always needs to be sent to the same backend
servers. For example by default PHP stores session data in files while Ruby on Rails
stores session information in a cookie by default. Please look up your web framework
documentation for information how this is handled. Consider writeing files as problematic
as well if there is no shared storage.
To create a new ACL, you have to create one by clicking the + button:
399
In the open modal dialog, the following form will show up:
400
Description Keep it empty or choose one for your
information
A form dialog opens and we can fill it out like the following:
401
Note
You can map using multiple Hostnames to the same Backend by adding multiple ACLs
and choosing the logical operator “OR”.
402
Select ACLs Select the ACLs to be used
The following modal dialog opens and the frontend can be set up:
403
Warning
If you configure a port that is already in use, the configuration test will be successful but
the start of HAProxy will fail silently. Please ensure that the used port is free - especially
if the number conflicts with the web configuration of OPNsense.
404
General Settings
Enabled Checked
Listen Address Enter one or more host:port combinations, use 0.0.0.0:80 for HTTP via
IPv4
Advanced settings
Enbable the X-Forwarded-For-header so the backend will know the real IP of the client.
Actions (ACLs)
Here you have to configure the previously configured actions, so HAProxy knows where
the requests should be sent to.
405
This is the last step - on the General tab, we will enable the service after a config test.
On this screen, check “Enable HAProxy” and click “Apply”. If everything went OK
HAProxy will start. Now you need to configure firewall rules for accessing your HAProxy
instance.
406
HAProxy How-Tos
Redirect Root directory
Create a condition:
name root
Path matches /
Create a Rule:
407
name forward_to_dir
Test type IF
conditions root
408
HTTP Redirect parameter code 301 location http://www.example.net/directory/
Please note that 301 is for a permanent redirect. If you want to do it teporary, you will
have to use another status code.
Under Public Services edit your frontend and add “forward_to_dir” to Select Rules.
409
name choose a name
Add a rule:
410
name a name for your rule
411
Go to your frontend and add the ACL to it.
Go to “Settings” -> “Global Parameters”, enable the advanced mode (top left), and add
your users to configuration via the “Custom options”
userlist admins
412
user test1 insecure-password pw1
user test2 insecure-password pw2
413
Installing OPNsense AWS image
To apply for access to the OPNsense Amazon AWS EC2 cloud image, you need:
414
Step 3 - Configure security group
415
To configure security group, make sure you allow https access from your own network.
416
Step 5 - Review your settings
417
Step 6 - SSH keypair
418
Select ssh keypair or skip, the ssh key isn’t used for OPNsense, ssh is disabled by
default.
419
Step 8 - AWS instances
420
Go to your AWS instances
421
Select the image, go to “image settings” then “get system log” to obtain the initial
password
422
Step 10 - Search current address
423
Login to OPNsense using the address provided.
424
IPSec BINAT
Assume company A has local LAN 10.0.1.0/24 and company B has local LAN
10.0.2.0/24. Also we assume that on both sides the other networks are already in use,
e.g. in company A the network 10.0.2.0/24 is used for Voice and in company B network
10.0.1.0/24 is used for Guest Wifi.
We have to define new networks for the Phase 2 with unused ones and create NAT
entries to reach the final systems.
Finally we have to create NAT entries since a client in LAN A (10.0.1.10) tries to reach
192.168.2.10, but this address has to be rewritten to 10.0.2.10 on Firewall B.
Create the rule like in the screenshot and vice versa on Firewall A:
425
426
Configure IPv6 Tunnel Broker
Original Author: Shawn Webb
Introduction
OPNsense supports native IPv6 as well as tunneled IPv6. This article shows how to set
up TunnelBroker, Hurricane Electric’s IPv6-in-IPv4 tunnel, with OPNsense. If you’re
based in the US and you use Netflix, you might not want to follow these instructions.
Netflix now blocks TunnelBroker.
If you use IRC or need access to SMTP over the TunnelBroker connection, Hurricane
Electric requires you to go through their free IPv6 certification process. Their “sage” level
is the highest level and will allow you to enable IRC and SMTP. Note that your
OPNsense firewall must be directly connected to the Internet. Being behind a NAT will
not work.
The rest of this article assumes you already have a TunnelBroker account. If not, sign up
and go through the free IPv6 certification process. Screenshots are provided throughout
this article.
Background
Enable ICMP on the WAN side of your OPNsense firewall. TunnelBroker’s UI will tell you
an IP to use when you’re setting up your tunnel on their end.
Now add a tunnel. Make sure to add a routed /48 as we will need that to dish out
individual /64 slices to each network. Once configured, your tunnel settings should look
like this:
427
428
Step 1 - Add GIF tunnel
To configure OPNsense start with adding a new gif interface. Go to Interfaces->Other
Types->GIF and click on Add in the upper tight corner of the form.
Use the following settings and copy in the IPv4&6 addresses from your TunnelBroker’s
UI.
Note
429
Step 2 - Configure the GIF tunnel as a new
interface
The newly created GIF tunnel must now be assigned as a new interface. Go to
Interfaces->Assignments, select the GIF tunnel for New interface and click the + sign
next to it.
Then under Interfaces->[OPTX] check Enable Interface and change the description to
e.g. TUNNELBROKER before hitting Save.
The newly created interface must now be set as the default IPv6 gateway under
430
System->Gateways->All by editing the new gateway entry
TUNNELBROKER_TUNNELV6 and checking Default Gateway before saving.
431
Step 4 - Configure LAN interface
Now configure your LAN interface. The static IPv6 address we’ll give it is a /64 address
from your assigned /48. I won’t show the WLAN settings simply because it’s the very
same. You’ll repeat the same process for further networks, but assigning the next
interface a separate /64 address.
432
Step 5 - Configure DHCPv6 SLAAC
We’ll next configure OPNsense for Stateless Address Auto Configuration (SLAAC).
433
We’re going to set up the DHCPv6 service. Go to Services->DHCPv6->Server.
Simply choose a range for clients to use. Save your settings. Next go to the Router
Advertisements sub tab on that same page. Set the Router Advertisements setting to
Assisted and the Router Priority setting to Normal.
434
Step 6 - Test your Configuration
You should now be set up for IPv6. To test your configuration, bring online an IPv6
machine, use your favorite tool to determine you have an IPv6 address. If you’re using
SLAAC, it may take up to 30 seconds or more to get an IPv6 address. If you see that
your interface has an IPv6 address, you can try going to an IPv6 only test site, such as
http://6.ifconfig.pro/
435
How To: Setting Up A Mail Gateway
Warning
A mail gateway under high load may need a lot of memory and CPU power. Keep in
mind that the components have some hardware requirements like the ClamAV- and the
Redis plugin. It is not recommended to run this software on weak hardware.
Installation
First of all, you have to install the required plugins from the plugins view.
ClamAV
Postfix
Redis
436
Rspamd
After a page reload you will get some new menu entry under services for all installed
plugins.
Warning
If you don’t set up a Redis instance, some components of rspamd will automatically
disable themself silently and it will not be visible in the GUI.
437
For a basic Redis instance, you can just check Enable Redis and click Apply to start the
servers.
3. Rspamd
First of all, you will need to activate the plugin by checking the Enable rspamd checkbox.
If you have installed and configured the Redis plugin, you should check the second
checkbox as well.
438
Note
The ClamAV component does enable or disable itself automatically if it has been
configured depending on the ClamAV (clamd) configuration.
For example, if the MX should be checked, the menu for the Spam Protection:
In this case the configuration is quite simple: Check Enabled, add a cache expiration
time (in Seconds) as well as clicking at the Apply button.
Postfix
439
First of all, you need to configure the domains you want to forward in the Domains
menu. .. Image:: images/postfix_add_new_domain.png
Enter the values for your mail server in the dialog after clicking +:
After saving usually the apply button needs to be hit but the server is not running
anyway as it needs to be configured first. If you add new domains, you have to hit this
button to apply changes.
440
In the General tab, the Postfix service must be enabled. If your system settings differ
from your system settings, you may override them here. For example overriding the
hostname makes sense because you may want to use the hostname which has been
configured as the MX host in the DNS.
You shhould keep the checkboxes at the bottom enabled as they enable restrictions,
which provide an additional layer of security.
441
Enable the Checkbox and click Save.
Follow Up Tasks
In the next step, you should go to the Firewall menu. Create a new rule to pass port
TCP/25 traffic from Any to This Firewall.
442
Multicast DNS Proxy
If you want to connect multicast DNS of multiple networks, you will need to proxy
between them.
Installation
First of all, you have to install the mdns-repeater plugin (os-mdns-repeater) from the
plugins view.
After a page reload you will get a new menu entry under services for MDNS Repeater.
Select it and you will get to the following screen:
443
Configuration
Warning
The configuration is fairly simple. Just enable the service and add the interfaces. For
example:
Property Value
Enabled checked
444
445
Setup Multi WAN
Multi WAN scenario’s are commonly used for failover or load balancing, but
combinations are also possible with OPNsense.
Configure Failover
To setup Failover the following step will be taken:
Add a firewall rule for DNS traffic that is intended for the firewall itself
Tip
Did you know you can browse quick and easy to the right page by using the search box
in the top right corner of your screen? Like this:
446
Example configuration
Our example utilized two previous configured WAN gateways that both are confirmed to
function separately. As DNS’s and monitor ip’s we will utilize google’s DNS services
8.8.8.8 and 8.8.4.4, of course you can use your own ‘known good’ setting.
We defined WAN and WAN2, where WAN will be our primary (default) gateway.
447
Monitor IP 8.8.8.8 We use Google’s DNS
Then click on the second pencil symbol to edit the second gateway.
Gateway Priority WANGW / Tier 1 Select the first gateway and Tier 1
Trigger Level Packet Loss Select the trigger you want to use
448
Tip
Member Down
Triggers when the gateway has 100% packet loss.
Packet Loss
Triggers when the packet loss to a gateway is higher then the defined threshold.
High Latency
Triggers when the latency to a gateway higher than its defined threshold.
DNS servers
8.8.8.8 WANGW
8.8.4.4 WAN2GW
449
For our example we will update the default LAN pass rule. Click on the pencil next to this
rule (Default allow LAN to any rule).
Note
This rule will utilize the gateway group for all traffic coming from our LAN network. This
also means that traffic intended for the firewall itself will be routed in this (wrong)
direction. That is why Step 5 is needed for our DNS traffic going to and coming from our
DNS forwarder on the firewall itself.
Interface LAN
450
Source any
Advanced Options
For each gateway there are several advanced options you can use to change the default
behavior/thresholds. These option can be changed under System->Gateways->All,
press the pencil icon next to the Gateway you want to update.
Probe Interval
How often that an ICMP probe will be sent in seconds.
Down
451
The number of seconds of failed probes before the alarm will fire.
This will change the behavior from failover to equal balancing between the two
gateways.
Sticky Connection
Some web sites don’t like changing request ip’s for the same session, this may lead to
unexpected behavior. To solve this you can use the option Sticky Connections, this will
make sure each subsequent request from the same user to the same website is send
through the same gateway.
452
If you have a non symmetric setup with one IPS having a much higher bandwidth that
the other then you can set a weight on each gateway to change the load balance. For
instance if you have one line of 10Mbps and one of 20Mbps then set the weight of the
first one to 1 and the second one to 2. This way the second gateway will get twice as
many traffic to handle than the first.
To do so, go to System->Gateways->All and press the pencil icon next to the Gateway
you want to update. The weight is defined under the advanced section.
453
Setup Anti Virus Protection using
OPNsense Plugins
OPNsense can offer http and https protection by utilizing its highly flexible proxy and the
industry standard ICAP. An external engine from one of the known vendors is used to
offer maximum protection against malware, such as ransomware, trojans and viruses.
This protection can be further enhanced by the build-in Intrusion Prevention System and
Category Based Web filtering.
Note
The Anti Virus Engine can protect you against malicious websites and infected file
downloads, it does not protect the local clients. Therefore it is always a good idea to
install a client based solution as well to protect against other forms of infection such as
through emails or usb stick if they are not analyzed as well.
Note
Note that there is still another attack vector called social engineering. Most attacks
would fail without the help of an internal human whose trust is exploited. An active
scanner is only a part of the security concept.
454
To setup the transparent mode, see: Setup Transparent Proxy.
The defaults from c-icap and ClamAV (vendor defaults) are used. Please keep in mind
that changing may affect security or performance. If you don’t know how a setting is
affecting your network, you should keep it at the default.
ClamAV
c-icap
Select enable ICAP and filling the Request and Response URL’s. For the C-ICAP plugin,
the default URLs will be:
455
Step 5 - Test using EICAR
To test if the engine is operational and functional go to http://www.eicar.org/85-0-
Download.html on this page you will find several files you can test.
First test the http protocol version and if that works the https version if you have also
configured the transparent ssl proxy mode.
Warning
DONE
456
Tor Configuration
Note
Saving changes in modal dialogs does not apply the settings. To apply them, you have
to click the “Reload Service” button.
Installation
First of all, install the tor plugin (os-tor) from the plugins view.
After a page reload you will get a new menu entry under services for Tor. Open the
menu and choose “Configuration” to configure the plugin.
General Settings
This section controls how Tor behaves in general as well as forward proxying.
Global Settings
457
Tor Service Settings
Enable
Controls if the service should be running. If it is enabled, it will also be enabled at boot
time.
Control Port
The control port is used for control communication with the Tor daemon. This Port
requires a password, which will not be disclosed to the GUI but can be queried via the
API. This setting is available for you to handle Port conflicts, so you can change this
port.
458
Create a logfile, Send log messges to syslog
Enable this checkbox if you want some logging. Please note that a detailed log may lead
to privacy issues.
Fascist Mode
If internet access is filtered, you can try this option. Please note that this is not
compatible with other features like “Hidden Services”.
Forward Proxy
Note
The SOCKS proxy is only useable from localhost (127.0.0.1 and ::1) unless an ACL is
added in the “SOCKS Proxy ACL” section.
Listen Interfaces
Add one or multiple interfaces, on which Tor should listen additionally to the loopback
interface. This is required if you want to use Tor from other computers than the appliance
itself. Tor will bind on the statically configured IP address from your interface
configuration. If the interface has no static IP configured, it will be ignored.
459
Transparent Forward Proxy
Transparent Port
This port is the target for your NAT rule. Please create a rule for this port in the “Port
Forward” section of the firewall.
Transparent IP Pool
This is used to provide an IP pool to Tor, which can be used for host mapping. This
needs to be a /16 network at minimum.
SOCKS ACL
Warning
If untrusted devices have access to the SOCKS proxy, private information may be
leaked. Please be careful with the networks you allow here.
460
In this example, you can see that all Hosts of the 192.168.0.0/16 network have access to
the Tor Proxy. By default, connections are forbidden.
Creating a new entry is quite easy. Just click the + and fill out the form:
Enable
The entry will be added to the configuration file. If this checkbox is unckecked, the entry
is ignored.
461
Protocol
Select the protocol in use for this ACL. You can choose between IPv4 and IPv6. By
default, IPv6 is selected.
Network
In this field, you have to add the network, on which this ACL should be applied in CIDR
notation.
Action
Select if the traffic should be accepted or rejected.
Hidden Services
A hidden service is an open TCP port, which is hosted in the Tor network and therefore
the origin of the service is hard to trace. For example, you can host a website in Tor by
running a webserver in your network and forwarding a hidden service port to this
webserver.
Warning
This does not work with every protocol as there are protocols which open arbitrary ports.
An example for that is FTP. You may work around this issue by limiting the usable ports
of such services (for example 10 ports) and forward those to the server.
If you want to host a hidden service, you need to open the hidden service tab and click
the + button.
462
The following dialog will open and you can enter a name.
You are allowed to add any alphanumeric name here. For example, you can call your
service sampleservice.
Click “Save changes” and your service is saved to the configuration file but not saved to
the Tor configuration file.
463
Switch to the “Hidden Service Routing” tab:
For any port you want to forward, you have to click + and fill out the form:
Hidden Service
The service on which the port forward applies. The entries in this list are the services
created in the previous step.
464
Port
The virtual Port in the Tor network.
Target Host
The host, on which the real service is running.
Target Port
The real port of the service. Please note that this does not need to match the Port field
but some services may act strange on mismatch.
The sample in the screenshot would forward traffic from the virtual host in the Tor
network it gets on port 80 to 127.0.0.1:8080
Warning
When using local connections like 127.0.0.1 or ::1, your application may think this
connection is trusted (localhost is not from the internet). Be careful when forwarding
traffic to localhost.
In addition to regular onion services, the services can be protected even more by
requireing the client to know a secret cookie.
This setting needs to be configured on both ends. On the server hosting the onion
service, you need to configure it on the configuration tab for the onion service.
For example, if you want to have a stealth service (undetectable without knowing the
key), you can configure it like the following:
465
Authorization Type
Can be Stealth or Basic. Basic means that multiple clients can use the entry point and it
is still visible but unauthorized hosts can not connect.
Authorized Clients
You can choose some names for your clients. Each client gets a authorization cookie
assigned so they can connect to it. If you set this value, this onion service will not be
available to the public anymore.
Now as this service will need to be configured to the client side as well, you will need to
add the secret to the configuration page. To configure a authorization cookie for a
service, you can open the Onion Service Authentication tab and fill out the form like on
the screenshot:
You need to configure the hostname and the authorization cookie you will get.
Host Name
Enter the .onion address of the onion service.
466
Authentication Cookie
This is the authentication code you will get from the maintainer of the onion service.
Enter it into this field.
When you are done, save the settings and reload the service. After that, you should be
able to reach the service.
Relays
A Tor relay is a host which forwards traffic for other Tor nodes. A relay, which allows to
pass traffic outside of the Tor network, is called an “Exit Node”. If the relay is configured
only for you (not for public access), it is called a bridge. Bridges are used to circumvent
filtering of public entry nodes based on IP/Port basis as the existence of bridges is
usually unknown.
467
Note
To be a relay, your host must have a public available port. With relaying, you will
increase the anonymity of Tor and it is less risky than an exit node.
Enable
Enable this checkbox if you want to relay traffic (forward foreign traffic).
Host
This is the host to bind the relay port to. This can be the public IP address. This setting
is optional and may be omitted.
Port
This is the public port used. Do not forget to add a firewall rule to pass traffic to this port.
Otherwise it will not work.
Address
468
You can enter the FQDN or the WAN IP of this Firewall.
Nickname
A nickname can be used to identify your network but it must only consist of
alphanumeric characters.
Bandwith Rate
You can limit the bandwith Tor will use. By default, Tor will use the maximum amount of
bandwith available. The value must be at least 72 kilobits per second.
Bandwith Burst
See Bandwith Rate.
Directory Port
If you have a lot of bandwith, you can also configure a directory port. You should not
enable this port if your bandwith is small.
Bridge
Enable this setting, if you want to be a bridge.
Exit Nodes
Warning
469
Providing an exit node can lead to legal issues. It may be a good idea to consult a
lawyer before setting up one as you might be made responsible for traffic, which
originates from a malicious Tor user.
If you have relaying enabled, you can also become an exit node. To allow outgoing
connections, you have to open to the “Exit Node ACL” tab.
470
Enable
If it is checked, the ACL will be used by Tor, otherwise the line is ignored.
Protocol
Select the protocol, on which this ACL applies. You can select IPv4 and IPv6 here. IPv6
is the default.
Network
You can enter a target network in CIDR notation or an IP address here. If no IP is given,
any IP will match.
Action
If you select “Reject”, no exit node traffic will be sent to this host and it will not be
forwarded. If you choose “Accept”, your host may be choosen as an exit node in a
circuit.
471
Configuring LDAP
LDAP is the light weight directory access protocol used by Microsoft Active Directory,
OpenLDAP and Novell eDirectory, to name a few.
OPNsense can use a LDAP server for authentication purposes and for authorization to
access (parts) of the graphical user interface (web configurator). When using LDAP for
the GUI the privileges have to be defined with the local user manager, to do so an import
of the users from the LDAP source is required.
In this how-to we will show you how to configure both using Microsoft Active Directory
Server. If you only need LDAP for services like vpn, then you can skip step 3-5.
Prerequisites
A functional LDAP server (example is based on MS AD) is required. You OPNsense
firewall need to be fully configured and able to access the LDAP server.
472
address
Search scope
Authentication Select Click & Select the containers from the list
containers
473
User naming samAccountName Auto filled in based upon Initial Template
attribute
Note
When clicking on the Select button right next to Authentication containers, something
similar to will show up:
Tip
The Extended Query can be used to select users who are member of a specific group.
One can use something like this: &
(memberOf=CN=myGroup,CN=Users,DC=opnsense,DC=local) to select only
members of the group “myGroup”. To add a user to a specific group under Windows just
edit the groups properties and select Add… to add the user under the tab Members.
474
Step 2 - Test
To test if the server is configured correctly, go to System->Access->Tester and select
your LDAP server and enter a valid username + password. Click on Test and if
everything is setup correctly it will show:
475
Note
When limited to just one group, the group name will not be shown in the listing.
A new form will be show with the individual users, select the ones you like to import.
When opening a ldap user (edit) via the pecil icon right next to the name, you will notice
476
the difference as the User Distinguished name will be shown from the LDAP server,
just like this:
Tip
See Creating Users & Groups for more information on User, Groups and privileges.
477
478
Creating Users & Groups
With the local user manager of OPNsense one can add users and groups and define the
privileges for granting access to certain parts of the GUI (Web Configurator).
Adding Users
To add a new user go to System->Access->Users and click on the + sign at the bottom
right corner of the form.
479
Password secret A strong password
Authorized keys Optional, paste ssh key for ssh console access
Creating Groups
Go to System->Access->Groups and click on the + sign in the lower right corner of the
form.
Enter a Group name* and a Description and add users to the group.
480
To assign privileges, just click on the pencil icon on the right of Assigned Privileges a
form will be shown where each page can be either selected or deselected; here it’s also
possible to allow a user shell account access (console).
The search bottom at the top of this form can be used to quickly find the right page.
481
After making the right selection click on Save to store the new settings.
482
483
Configuring Radius
Configuring a Radius server for user authentication in services like vpn or captive portal
is easy just go to System->Access->Servers and click on Add server in the top right
corner.
Authentication port 1812 Port number, 1812 is default for accounting it’s
value 1813
If you want to use the FreeRADIUS plugin set up the server as 127.0.0.1 and don’t
forget to add a Client in the FreeRADIUS configuration.
484
485
Zerotier Configuration
Note
It is strongly recommended that the reader familiarise themselves with the Zerotier
Manual [https://www.zerotier.com/manual.shtml], in order to further understand the
concepts behind this plugin.
Prerequisites
Firstly, it is important that you have signed up to Zerotier at the Zerotier Portal
[https://my.zerotier.com]. Second, you will need to create at least one network on the
portal in order to obtain a Network Id that this plugin uses to join this node to the created
Zerotier network. This network will become your private network that by default is visible
only to your nodes - in other words, other nodes that are on that network can talk to
each other, but nothing else can talk to them - they are completely transparent to the
internet in general. In effect you are layering a private network over the public internet
and all intra-node communication is encrypted and private between them. This is further
hinted at by the fact that the assigned IP addresses are normally RFC1918 addresses,
i.e., non-routable across the internet.
Finally, in order to have a fully functioning private VPN between Zerotier nodes, a
combination of this plugin plus some configuration on the portal [https://my.zerotier.com]
will be required.
Installation
From the Plugins view under System...Firmware , install the os-zerotier package. Once
the new plugin has been installed, perform a page reload and a new menu item should
appear under VPN called Zerotier.
486
Clicking on the Zerotier menu item will reveal two further sub-menu items - namely
Settings and Overview. Clicking on “Settings” will present a new view with two named
tabs. The first tab is called Settings and the second tab is called Networks. These are
further described below.
Settings
This tab controls the overall operation of Zerotier. Anything changed here is applied
globally to all defined networks and to the Zerotier service itself.
487
Enabled
Controls if the service should be running. If it is disabled, then access to the Networks
tab will be disabled. If it is enabled, access to the Networks tab will be enabled and the
service will also start at boot time.
Networks
This table allows for the creation, modification and deletion of Zerotier networks. Adding
a Network here will join your OPNsense installation to the specified Zerotier network.
Note
Remember, you will have to log into the Zerotier portal [https://my.zerotier.com], select
the network and authorise the node before it can be assigned an IP address (or indeed,
talk to other nodes on that network).
488
Adding a network is quite straight-forward. Simply click on the + symbol key in the
following:
Network Id
This is the 64-bit (16 character hex) address that is generated on the portal when
creating a Zerotier network.
Adding a network does not automatically cause your OPNsense installation to join that
network. In order to join that network it must be Enabled first. Likewise, to remove your
OPNsense node from the configured network simply deselect Enabled , thus disabling
the network.
Once a network has been added and enabled the node must be authorised to join the
network on the portal. Simply enabling the network on your OPNsense installation marks
that node as a member of that network. It now has to request permission to talk to the
other nodes on that network. To achieve this, you log into the portal, select the network,
find the node address (this can found on the OPNsense Zerotier Overview menu item,
under the Information tab) and authorise it by clicking on the “Auth?” check box beside
489
the node. It should go from “red” to “green” to indicate that it has been authorised.
If you wish to completely remove the network, simply select the network and click on the
Bin icon.
To “clone” the network entry, click on the Copy icon. Please ensure you change the
Network Id, as having two networks with the same id is an invalid configuration.
For a very quick overview of the Zerotier network information, click on the Information
icon. A more detailed view of the network can be found under the Overview...Networks
menu item.
Overview
The following 3 tabs reveal Global, Network and Peer information. They can only be
viewed if the Zerotier plugin is enabled, so please ensure that the service is enabled
first. For information on the terminology used, please refer to the Zerotier Manual
[https://www.zerotier.com/manual.shtml].
490
Information Overview
This tab shows “Global” information concerning the overall health of the Zerotier service.
Networks Overview
This tab shows each configured and enabled network that this OPNsense installation
has joined. If no networks are enabled, no information is shown.
Peers Overview
This tab shows the peers (leaf, planets and moons - Zerotier terminology) known by this
node.
Interface Assignment
Warning
491
It is highly recommended that the interface have auto-assignment of IP addresses
turned off for this particular node only. You want to give the interface a statically
assigned, stable IP address (from the Zerotier network IP range) and not have the
Zerotier service auto-assign an IP address. Auto-assignment of IP addresses for nodes
is controlled on the Zerotier Portal [https://my.zerotier.com]
After joining a Zerotier network (and authorising it on the portal) you may now wish to
assign the Zerotier virtual interface on OPNsense in order to avail of OPNsense
functionality such as firewalling and routing (using OSPF for example).
To achieve this:
Click on the Interfaces menu item, then click on Assignments . There you should
discover a new interface currently unassigned that begins with the letters zt . Next,
click on the + symbol to assign it. In this example it creates a new interface called
OPT1 . Clicking on OPT1 shows the Enable and Lock options. Check both options.
Warning
It is very important that Lock (i.e., Prevent interface removal) is enabled. This is
because Zerotier is a software interface and not guaranteed to be brought “up” whilst the
system is booting. It could happen shortly afterwards, hence locking the interface tells
492
OPNsense not to remove it, thinking it’s gone bad.
Once the new interface has been enabled, it is recommended to change the Description
away from OPT1 to something more descriptive for your needs.
For IPv4 Configuration Type , choose Static IPv4 then in the appropriate input boxes,
key in the IPv4 address that you have assigned to this node via the Zerotier portal.
Keep the IPv4 Upstream Gateway set to None.
Once the interface has been assigned with an IP, it show now also show up on
Firewall Rules etc…plus any other operations that be done on a interfaces can also be
493
Development Manual
The OPNsense® project invites developers to start developing with OPNsense: “For
your own purpose or even better to join us in creating the best FreeBSD based open
source firewall available!” The development workflow & build process has been
redesigned to make it more straightforward and easy for developers to build OPNsense.
Being able to get the sources and build it yourself is one of the key factors of open
source software. One reason that for starting the OPNsense project is that the team
believes sources and build tools should be freely available and as easy to use as
possible.
Development Workflow
494
Coding Guidelines
Basics and Future
PSR-1 Basic Coding Standard
PSR-2 Coding Style Guide
Python PEPs
Architecture
Backend
Bootup / autorun options
Using configd
Using legacy plugins
Using Templates
Frontend
Creating Models
Routing
Using controllers and views
Components
Menu System
Access Control List
Examples
Hello world module & plugin
How to’s
Use the API
Sources
Just looking for the sources? See: OPNsense repository [https://github.com/opnsense]
495
Development Workflow
It’s pretty hard to approach a larger repository you have never worked with. The biggest
issue is that few projects have defined development (as in actual coding) workflow laid
out for new contributors, so one is just going to be stabbing in the dark for a few days or
weeks until things start making sense. Speaking of sense, let’s explain how we’ve
designed the development experience for OPNsense [https://opnsense.org/developers-
invitation/] and how you can start contributing code in no time.
Structure
Source, Ports, Core, Tools
Note
496
As of 16.1 there is also plugin support, the source repository is plugins tree
[https://github.com/opnsense/plugins] . Plugins are a modular way of easily extending
the existing system.
The first thing that’s interesting is that the core is not part of the source repository,
because it depends on third party software found in the ports. We can’t stick core into
source, because ports are things that don’t fit into the base system. It also helps to keep
source repository changes to the minimum to make major FreeBSD upgrades easier in
the future.
Why is the core repository not in the ports? Well, we have a couple of custom ports in
the ports tree, but these are small. The core repository as well as the ports tree itself are
so big that it made sense to keep them separate. Another reason is that the core
repository only contains scripts in Shell, Python and PHP. So the tools repository
actually treats the core repository as a package that depends on all the ports it needs.
This way, on the images, it looks like the core code is just another package. That makes
upgrading the core code very easy and fast without modifying base. We can even
upgrade to newer ports pages and add and remove them as we go forward.
Building
Not Clobbering the Build System
The tools repository is designed to run on a stock FreeBSD using chroot mechanics
[http://en.wikipedia.org/wiki/Chroot] to keep the build contained and consistent. There’s
nothing worse than a build system that modifies the build system and at some point
starts to dash out working images–only to stop working some time in the future. No, no,
497
no.
You can also “cross-build” between FreeBSD versions. We’ve successfully built images
on FreeBSD 10.1 when OPNsense was still running on FreeBSD 10.0. (version 16.1
now runs on FreeBSD 10.2) That’s not a huge gap and the ABI
[https://en.wikipedia.org/wiki/Application_binary_interface] is the same, but we expect
this to work with FreeBSD 11 and beyond as well so that if you have a FreeBSD box you
will always be able to produce your own images if you desire–without spinning up extra
machines, jails or virtual machines.
Tip
As of November 2015 OPNsense is equipped with a tool that can completely reinstall a
running system in place for a thorough factory reset or to restore consistency of all the
OPNsense files. It can also wipe the configuration directory, but won’t do that by default.
The opnsense-bootstrap [https://github.com/opnsense/update] script is particularly
useful if you want to convert a hosted FreeBSD system to OPNsense.
It’s just easier and less tedious if the kernel crashes, to revert to a previous state, or
isolate and test different features. A VM can be set up easily using the ISO images. Also
very good for testing installation and upgrades. Of course, at some point you will want to
bring OPNsense to your actual target device—just make sure you know the system well
enough before you attempt this.
498
VirtualBox [https://www.virtualbox.org/] is a solid tool for the job, but be sure to check out
FreeBSD’s Bhyve [http://bhyve.org/] as well (it was added in FreeBSD 10.0). However, If
you are only interested in GUI coding, you can skip all the build parts and directly
download an image and spin it up. Because…
Packages
It Gets Even Better
Once you have a running instance, how to produce and push code? Well, there’s a
couple optional of packages that help you to be productive:
The most important one is git for obtaining the code, the rest is optional if you need it—
mostly editors and terminal wrappers. It is also possible to mount sshfs or do sftp to sync
files from the repo if you would like to use a graphical editor from your own system. As
the root user do the following:
# cd
# git clone https://github.com/opnsense/core
# cd core
# make mount
Yes, the changes that you make in the repository will show up directly in the GUI now!
Unfortunately, this will mount the repo over /usr/local so if you modify packages the
499
changes will light up in git. Be careful. To prevent that from happening you can
temporarily unmount using:
# make umount
To finish that off the boot sequence will mount the core repository set up in /root/core as
early as possible (if it’s available) and will use its modifications for booting up (with the
exception of /usr/local/etc/rc itself). This makes it possible to work on the backend
configuration and boot sequence improvements without having out of sync system files
and repositories.
Summary
Easy Access is Key to Collaboration
Although this is just a peek into OPNsense development workflow it brings to attention a
key aspect: moving barriers out of the way to enable as many people as possible to
produce quick results. Yes,there are barriers like git [http://git-scm.com/book/en/v2/Git-
Basics-Getting-a-Git-Repository] and GitHub
[https://guides.github.com/activities/contributing-to-open-source/] to deal with, maybe
even learning FreeBSD intricacies, but once you have your code in the GUI and working
fine, you’ll feel proud enough to endure the hardships of making sure your patch will
have a place in our upstream repositories so the community as a whole can benefit from
your dedication.
The OPNsense core team looks forward to your feedback; “We are seeking for more
improvements in the build system and eagerly await your pull requests.” Take care and
code responsibly. :)
500
501
Coding Guidelines
502
Basics and Future
This article explains the basic coding guidelines that apply and put the development
effort into perspective by explaining the difficulties of legacy code and the
interaction/migration to new MVC-based
[https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller] code. It
also explains guideline differences between new and legacy code.
PHP code
For PHP code the PSR-1 [https://www.php-fig.org/psr/psr-1/] and PSR-2
[https://www.php-fig.org/psr/psr-2/] Coding Standard apply.
Python
For Python code the Python Enhancement Proposals (PEPs) apply. See the Python
Developer’s Guide [https://www.python.org/dev/] for detailed information.
Architecture
Documentation is available about our architecture and used components.
Ideal Development
Our ideal OPNsense system looks like a standard FreeBSD system using our pluggable
user interface for management, which supports both real users as “machine” users
(REST).
When developing we want the code to be clean and coded as DRY (Don’t Repeat
503
Yourself) as possible and do not want to invent the wheel when not needed.
The user interface should to be able to run as non-root user instead of root by
restructuring the way commands are passed to the system (configd).
One of the first things (on the programming part of the system) we did was build
components around an existing framework (Phalcon [https://phalconphp.com/]) to create
new modules, which could use validated configuration data (from the config.xml), supply
a RESTful API and generate html output using standard templates (Volt).
We created the configd system, which can generate system configuration and execute
system calls using predefined templates. And then we started using those new
components for our first newly designed modules (like the proxy and the traffic shaper).
More information about the “to-be” architecture can be found in our architecture
documentation.
Strategy
Knowing we can’t change the world in a single day and having a lot of legacy to drag
around with us, our strategy consists of three parts:
1) Cleanup and maintenance Restructure old (legacy) code, basically all code in the
src/www, src/etc/inc to make it better readable, easier to use and remove unused /
unnecessary parts. By doing so we want to extend the lifetime of the old code a bit and
make the transition in new code easier eventually.
504
2) Detach Move system configuration calls to configd where possible, which gives the
administrator the advantage of running those commands from the command line and
helps removing the need for root user access in the future. The ipsec VICI
implementation is one example of this stage.
3) Moving on (re)build new parts, using our new modules, which provide a layered
development system to automatically support api calls from other systems and xml
based model templates to describe configuration data.
See also:
Our guidelines somewhat depend of the stage the code is in, when writing new code, all
actions should use the api system for actually changing configuration and performing
configuration tasks. They should, of course, use the normal PSR coding standards for
PHP code and follow the Python PEPs.
When moving to the legacy part of the system, our goal is to stick as close to PSR1/2 as
possible, knowing it will never be perfect.
505
PSR-1 Basic Coding Standard
Note
The PSR1 and PSR2 Coding Standards are provided by FIG under a
MIT license.
See license details: http://www.php-fig.org/bylaws/licensing-policies/
The original content of this page can be found at php-fig
[http://www.php-fig.org/psr/psr-1/]
This section of the standard comprises what should be considered the standard coding
elements that are required to ensure a high level of technical interoperability between
shared PHP code.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
document are to be interpreted as described in RFC 2119
[http://www.ietf.org/rfc/rfc2119.txt].
1. Overview
Files MUST use only <?php and <?= tags.
Files MUST use only UTF-8 without BOM for PHP code.
Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause
side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.
506
Class names MUST be declared in StudlyCaps .
Class constants MUST be declared in all upper case with underscore separators.
2. Files
2.1. PHP Tags
PHP code MUST use the long <?php ?> tags or the short-echo <?= ?> tags; it MUST
NOT use the other tag variations.
The phrase “side effects” means execution of logic not directly related to declaring
classes, functions, constants, etc., merely from including the file.
“Side effects” include but are not limited to: generating output, explicit use of require or
include , connecting to external services, modifying ini settings, emitting errors or
exceptions, modifying global or static variables, reading from or writing to a file, and so
on.
507
The following is an example of a file with both declarations and side effects; i.e, an
example of what to avoid:
<?php
// side effect: change ini settings
ini_set('error_reporting', E_ALL);
// declaration
function foo()
{
// function body
}
The following example is of a file that contains declarations without side effects; i.e., an
example of what to emulate:
<?php
// declaration
function foo()
{
// function body
}
508
3. Namespace and Class Names
Namespaces and classes MUST follow an “autoloading” PSR: [PSR-0
[https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md], PSR-4
[https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md]].
This means each class is in a file by itself, and is in a namespace of at least one level: a
top-level vendor name.
Code written for PHP 5.3 and after MUST use formal namespaces.
For example:
<?php
// PHP 5.3 and later:
namespace Vendor\Model;
class Foo
{
}
Code written for 5.2.x and before SHOULD use the pseudo-namespacing convention of
Vendor_ prefixes on class names.
<?php
// PHP 5.2.x and earlier:
class Vendor_Model_Foo
{
}
509
4. Class Constants, Properties, and
Methods
The term “class” refers to all classes, interfaces, and traits.
4.1. Constants
Class constants MUST be declared in all upper case with underscore separators. For
example:
<?php
namespace Vendor\Model;
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
4.2. Properties
This guide intentionally avoids any recommendation regarding the use of $StudlyCaps ,
$camelCase , or $under_score property names.
4.3. Methods
Method names MUST be declared in camelCase() .
510
511
PSR-2 Coding Style Guide
Note
The PSR1 and PSR2 Coding Standards are provided by FIG under a
MIT license.
See license details: http://www.php-fig.org/bylaws/licensing-policies/
The original content of this page can be found at php-fig
[http://www.php-fig.org/psr/psr-2/]
This guide extends and expands on PSR-1 [https://github.com/php-fig/fig-
standards/blob/master/accepted/PSR-1-basic-coding-standard.md], the basic coding
standard.
The intent of this guide is to reduce cognitive friction when scanning code from different
authors. It does so by enumerating a shared set of rules and expectations about how to
format PHP code.
The style rules herein are derived from commonalities among the various member
projects. When various authors collaborate across multiple projects, it helps to have one
set of guidelines to be used among all those projects. Thus, the benefit of this guide is
not in the rules themselves, but in the sharing of those rules.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
document are to be interpreted as described in RFC 2119
[http://www.ietf.org/rfc/rfc2119.txt].
1. Overview
Code MUST follow a “coding style guide” PSR [PSR-1 [https://github.com/php-fig/fig-
standards/blob/master/accepted/PSR-1-basic-coding-standard.md]].
512
Code MUST use 4 spaces for indenting, not tabs.
There MUST NOT be a hard limit on line length; the soft limit MUST be 120 characters;
lines SHOULD be 80 characters or less.
There MUST be one blank line after the namespace declaration, and there MUST be one
blank line after the block of use declarations.
Opening braces for classes MUST go on the next line, and closing braces MUST go on
the next line after the body.
Opening braces for methods MUST go on the next line, and closing braces MUST go on
the next line after the body.
Visibility MUST be declared on all properties and methods; abstract and final MUST
be declared before the visibility; static MUST be declared after the visibility.
Control structure keywords MUST have one space after them; method and function calls
MUST NOT.
Opening braces for control structures MUST go on the same line, and closing braces
MUST go on the next line after the body.
Opening parentheses for control structures MUST NOT have a space after them, and
closing parentheses for control structures MUST NOT have a space before.
1.1. Example
This example encompasses some of the rules below as a quick overview:
<?php
513
namespace Vendor\Package;
use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
2. General
2.1 Basic Coding Standard
Code MUST follow all rules outlined in PSR-1 [https://github.com/php-fig/fig-
standards/blob/master/accepted/PSR-1-basic-coding-standard.md].
2.2 Files
All PHP files MUST use the Unix LF (linefeed) line ending. All PHP files MUST end with
a single blank line.
514
The closing ?> tag MUST be omitted from files containing only PHP.
2.3. Lines
There MUST NOT be a hard limit on line length.
The soft limit on line length MUST be 120 characters; automated style checkers MUST
warn but MUST NOT error at the soft limit.
Lines SHOULD NOT be longer than 80 characters; lines longer than that SHOULD be
split into multiple subsequent lines of no more than 80 characters each.
Blank lines MAY be added to improve readability and to indicate related blocks of code.
2.4. Indenting
Code MUST use an indent of 4 spaces, and MUST NOT use tabs for indenting.
Note
N.b.: Using only spaces, and not mixing spaces with tabs, helps to avoid problems with
diffs, patches, history, and annotations. The use of spaces also makes it easy to insert
fine-grained sub-indentation for inter-line alignment.
515
case.
The PHP constants true , false , and null MUST be in lower case.
When present, all use declarations MUST go after the namespace declaration.
For example:
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
516
The extends and implements keywords MUST be declared on the same line as the
class name.
The opening brace for the class MUST go on its own line; the closing brace for the class
MUST go on the next line after the body.
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
Lists of implements MAY be split across multiple lines, where each subsequent line is
indented once. When doing so, the first item in the list MUST be on the next line, and
there MUST be only one interface per line.
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
517
4.2. Properties
Visibility MUST be declared on all properties.
There MUST NOT be more than one property declared per statement.
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
}
4.3. Methods
Visibility MUST be declared on all methods.
Method names SHOULD NOT be prefixed with a single underscore to indicate protected
or private visibility.
Method names MUST NOT be declared with a space after the method name. The
opening brace MUST go on its own line, and the closing brace MUST go on the next line
following the body. There MUST NOT be a space after the opening parenthesis, and
there MUST NOT be a space before the closing parenthesis.
518
A method declaration looks like the following. Note the placement of parentheses,
commas, spaces, and braces:
<?php
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// method body
}
}
Method arguments with default values MUST go at the end of the argument list.
<?php
namespace Vendor\Package;
class ClassName
{
public function foo($arg1, &$arg2, $arg3 = [])
{
// method body
}
}
Argument lists MAY be split across multiple lines, where each subsequent line is
indented once. When doing so, the first item in the list MUST be on the next line, and
519
there MUST be only one argument per line.
When the argument list is split across multiple lines, the closing parenthesis and opening
brace MUST be placed together on their own line with one space between them.
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// method body
}
}
When present, the abstract and final declarations MUST precede the visibility
declaration.
When present, the static declaration MUST come after the visibility declaration.
<?php
namespace Vendor\Package;
520
final public static function bar()
{
// method body
}
}
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
Argument lists MAY be split across multiple lines, where each subsequent line is
indented once. When doing so, the first item in the list MUST be on the next line, and
there MUST be only one argument per line.
<?php
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
5. Control Structures
521
The general style rules for control structures are as follows:
There MUST be one space between the closing parenthesis and the opening brace
The closing brace MUST be on the next line after the body
The body of each structure MUST be enclosed by braces. This standardizes how the
structures look, and reduces the likelihood of introducing errors as new lines get added
to the body.
An if structure looks like the following. Note the placement of parentheses, spaces,
and braces; and that else and elseif are on the same line as the closing brace from
the earlier body.
<?php
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
522
The keyword elseif SHOULD be used instead of else if so that all control keywords
look like single words.
A switch structure looks like the following. Note the placement of parentheses, spaces,
and braces. The case statement MUST be indented once from switch , and the break
keyword (or other terminating keyword) MUST be indented at the same level as the
case body. There MUST be a comment such as // no break when fall-through is
<?php
switch ($expr) {
case 0:
echo 'First case, with a break';
break;
case 1:
echo 'Second case, which falls through';
// no break
case 2:
case 3:
case 4:
echo 'Third case, return instead of break';
return;
default:
echo 'Default case';
break;
}
A while statement looks like the following. Note the placement of parentheses, spaces,
and braces.
523
<?php
while ($expr) {
// structure body
}
Similarly, a do while statement looks like the following. Note the placement of
parentheses, spaces, and braces.
<?php
do {
// structure body;
} while ($expr);
5.4. for
A for statement looks like the following. Note the placement of parentheses, spaces,
and braces.
<?php
for ($i = 0; $i < 10; $i++) {
// for body
}
5.5. foreach
A foreach statement looks like the following. Note the placement of parentheses,
spaces, and braces.
<?php
foreach ($iterable as $key => $value) {
// foreach body
}
524
5.6. try , catch
A try catch block looks like the following. Note the placement of parentheses, spaces,
and braces.
<?php
try {
// try body
} catch (FirstExceptionType $e) {
// catch body
} catch (OtherExceptionType $e) {
// catch body
}
6. Closures
Closures MUST be declared with a space after the function keyword, and a space
before and after the use keyword.
The opening brace MUST go on the same line, and the closing brace MUST go on the
next line following the body.
There MUST NOT be a space after the opening parenthesis of the argument list or
variable list, and there MUST NOT be a space before the closing parenthesis of the
argument list or variable list.
In the argument list and variable list, there MUST NOT be a space before each comma,
and there MUST be one space after each comma.
Closure arguments with default values MUST go at the end of the argument list.
525
A closure declaration looks like the following. Note the placement of parentheses,
commas, spaces, and braces:
<?php
$closureWithArgs = function ($arg1, $arg2) {
// body
};
Argument lists and variable lists MAY be split across multiple lines, where each
subsequent line is indented once. When doing so, the first item in the list MUST be on
the next line, and there MUST be only one argument or variable per line.
When the ending list (whether or arguments or variables) is split across multiple lines,
the closing parenthesis and opening brace MUST be placed together on their own line
with one space between them.
The following are examples of closures with and without argument lists and variable lists
split across multiple lines.
<?php
$longArgs_noVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) {
// body
};
526
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_shortVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use ($var1) {
// body
};
Note that the formatting rules also apply when the closure is used directly in a function
or method call as an argument.
<?php
$foo->bar(
$arg1,
function ($arg2) use ($var1) {
527
// body
},
$arg3
);
7. Conclusion
There are many elements of style and practice intentionally omitted by this guide. These
include but are not limited to:
Declaration of functions
Inter-line alignment
Best practices
Future recommendations MAY revise and extend this guide to address those or other
elements of style and practice.
528
Python PEPs
For Python code the Python Enhancement Proposals (PEPs) apply. See the Python
Developer’s Guide [https://www.python.org/dev/] for detailed information. The most basic
one is PEP8: Style Guide for Python Code [https://www.python.org/dev/peps/pep-0008/].
Compliance with PEP8 can be checked using the Python style guide checker
[https://pypi.python.org/pypi/pycodestyle/].
529
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.
High-level architecture
530
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
531
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.
Backend Architecture
532
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”).
533
script : execute external (rc) scripts
inline : perform inline actions which are part of configd, currently only template
generation.
534
Routing
The OPNsense framework uses components from Phalcon where possible; the first
layer initializes Phalcon’s routing, which handles requests and delivers them to the
controller based on its url. User content is generated using Volt templates, which are
picked by the controller. Because Phalcon’s default Models function with (relational)
databases and we are using xml data, our model implementation is custom. But
wherever possible we use components from Phalcon (for example, validation is handled
using Phalcon’s classes). For a detailed description on the routing principles used in
OPNsense, visit Frontend Routing.
Models
All models are defined by a combination of a class and an xml containing a (nested)
definition. More information on defining models can be found at the frontend model page
Creating Models.
Communication
Communication to the backend service is handled via a unix domain socket.
Core system
535
The core of OPNsense is powered by an almost standard FreeBSD ® system extended
with packages using the pkg system. GIT is used for version control and the repositories
are split into 4 parts:
Tip
536
Backend
The OPNsense backend consists of several components (see Architecture for a full
stack description).
Because some of the codebase still integrates with our legacy codebase, we provide
additional plugin options for the following components:
Service configuration (legacy service configuration, new style uses configd templates)
Services which need to be executed at system startup can use rc(8) or our syshook
system.
537
538
Bootup / autorun options
syshook
OPNsense offers an easy method to plugin shell scripts during (early) boot stage.
/usr/local/etc/rc.syshook.d/
They can contain regular shell scripts using the following extensions:
start
start script after normal system startup
early
start script before normal system startup.
#!/bin/sh
export vmware_guest_vmblock_enable="YES"
export vmware_guest_vmhgfs_enable="YES"
export vmware_guest_vmmemctl_enable="YES"
export vmware_guest_vmxnet_enable="YES"
/usr/local/etc/rc.d/vmware-kmod start
rc(8)
539
Part of the bootup process of OPNsense is probing the available rc(8) configuration files
in /etc/rc.conf.d/, when a daemon is enabled, the system will call the regular rc(8) start
command.
In case the daemon needs some extra preparation, an additional “bootup” script can be
provided, which will be run before executing normal “start”.
squid_enable=YES
squid_opnsense_bootup_run="/usr/local/opnsense/scripts/proxy/setup.sh"
The configd template system can be used to generate the necessary configuration
file(s).
540
Using configd
General
To add new services and system calls, which can be used from the frontend system or
command line, you can create configd actions.
All available templates should be installed at the following location on the OPNsense
system:
/usr/local/opnsense/service/conf/actions.d/
Please note that all actions which should be accessible from the frontend should have a
registered configd action, if possible use standard rc(8) scripts for service start/stop.
Naming convention
Service templates should use distinctive names to identify your service and contain
simple / clear actions.
For example, we will describe the template for ssh, which is installed by default.
File name:
/usr/local/opnsense/service/conf/actions.d/actions_sshd.conf
541
restart
starts / restarts ssh service
stop
stops / kills all ssh daemons
[restart]
command:/usr/local/etc/rc.sshd
parameters:
type:script
message:starting sshd
[stop]
command:/bin/pkill -TERM sshd || exit 0
parameters:
type:script
message:stop sshd
Between brackets [] you find the name of the action, the definition of the actual call is
defined in the following parameter:value pairs. When a service or module provides a lot
of actions, it sometimes is practical to add another level of operation.
For example, the restart service call for this service will translate to: sshd restart
In case we have an action like filter diag info, you can create an actions_filter.conf
which contains a section [diag.info].
Action properties
Property Syntax Description
542
parameters %s for every list of parameters to use, example : /i %s
parameter
Test action
To test a new configd action, please restart the configd service first using:
543
Using legacy plugins
General
Legacy type plugins are located in the following location:
/usr/local/etc/inc/plugins.inc.d/
All automatically registered functions start with the name of the file (without the
extension), followed by the purpose. For example vpn_configure would be the configure
handle in a plugin file name vpn.inc.
Services
To register services, the <plugin>_services() function should return a structure
containing its name, description and operating properties.
function myplugin_services()
{
$service = array();
$service['name'] = 'myservice';
$service['description'] = gettext('My service');
$service['configd']['restart'] = array('myservice restart');
$service['configd']['start'] = array('myservice start');
$service['configd']['stop'] = array('myservice stop');
$services[] = $pconfig;
return $services;
}
544
For a full list of supported service methods, please inspect services.inc
Syslog
To register syslog targets, the <plugin>_syslog() function should return a structure
containing targets and definitions.
function myplugin_syslog()
{
$logfacilities = array();
$logfacilities['myplugin'] = array(
'facility' => array('myplugin'),
'remote' => 'myplugin',
);
return $logfacilities;
}
Interface
To register new (virtual) interfaces, create a function called <plugin>_interfaces(), which
should return a named array containing the unique interface name as key (enc0 for
ipsec for example).
545
networks array, [network, list of named arrays containing remote networks
mask]
Example:
function myplugin_interfaces()
{
global $config;
$interfaces = array();
if (isset($config['myplugin']['enable'])) {
$oic = array("enable" => true);
$oic['if'] = 'tun0';
$oic['descr'] = 'myplugin';
$oic['type'] = "none";
$oic['virtual'] = true;
$oic['networks'] = array();
$interfaces['tun0'] = $oic;
}
return $interfaces;
}
Configure
When your plugin needs configuration after boot, you can create a function called
<plugin>_configure() which will be called upon boot.
546
547
Using Templates
General
For config file generation, we provide a backend service which can bind config.xml data
to templates written in Jinja2 (http://jinja.pocoo.org/docs/dev/).
All available templates should be installed at the following location on the OPNsense
system:
/usr/local/opnsense/service/templates/
Naming convention
All templates should be put into a directory structure containing the vendor and
package/application name, our sample application is placed inside the directory:
/usr/local/opnsense/service/templates/OPNsense/Sample
Targets
548
The +TARGETS file contains the source template name inside the template directory
and the (dynamic) target filename divided by a colon (:) multiple lines may be inserted
per file.
For example :
example_simple_page.txt:/tmp/template_sample/simple_page.txt
Note
Optionally you can specify which file or files to remove on call of “template cleanup”,
which can be specified by using an extra tag next to the target, such as:
example_simple_page.txt:/tmp/template_sample/simple_page.txt:/tmp/template_sample/simple_page.*
If you want to use information from within the config.xml file as output filename, you can
use tags to address the content, like [version] to input the tag version from the xml file.
When generating multiple files from 1 template, you can use one wildcard (%) to
address a section of the config file, for example [interfaces.%.if] loops over the interfaces
and outputs the value of if.
Target overwrites
Every template package can specify overwrites, which can be used by vendors who
implement and maintain their own templates for features in OPNsense.
549
Simply add files using the target definition in the +TARGETS.D directory of the
templates folder using as extension .TARGET.
For example an overwrite for OPNsense/Sample can use the following name and
location
/usr/local/opnsense/service/templates/OPNsense/Sample/+TARGETS.D/custom.TARGET
Note
Be vey careful using this feature, you need to maintain these templates yourself and
features may break after upgrades of OPNsense.
Templates
For more information of the template language itself, please look at
http://jinja.pocoo.org/docs/dev/ and the examples installed in
/usr/local/opnsense/service/templates/OPNsense/Sample.
There’s one special case when using the template engine, every wildcard used for the
output file generation is also provided to the template, so you are able to determine
which filter let to this output.
{% if TARGET_FILTERS['interfaces.wan'] %}
{% endif %}
Test usage
The templates can be rendered via the backend service (configd), to test this
550
functionality on a running OPNsense system, use:
# print results
for filename in generated_filenames:
print ('.. generated : %s'%filename)
551
Frontend
The OPNsense frontend is implemented with PHP/Phalcon
[https://en.wikipedia.org/wiki/Phalcon_(framework)].
Creating Models
Routing
Using controllers and views
552
Creating Models
A model represents the data which the application will use and takes care of the
interaction to that data. In OPNsense most of the relevant data is physically stored in an
xml structure (config.xml). The primary goal for OPNsense models is to structure the use
of configuration data, by creating a clear abstraction layer.
In this chapter we will explain how models are designed and build.
A php class describing the actions on our data (also acts as a wrapper to our data),
The definition of the data and the rules it should apply to.
<?php
namespace myVendorName\myModule;
use OPNsense\Base\BaseModel;
This class should be placed inside the model directory of our project, in this case the full
path for our class file would be
553
/usr/local/opnsense/mvc/app/models/myVendorName/myModule/myModel.php
When you design a model, the next thing to do is to figure out what data is relevant for
your application or module and think of the rules it should comply to (for example, if you
need an email address you might want to validate the input). Designing the actual model
is as simple as creating an xml file and putting in your structure, the name of our xml file
should be the same as the base name of our model suffixed by .xml.
/usr/local/opnsense/mvc/app/models/myVendorName/myModule/myModel.xml
<model>
<mount>//myManufacturer/myModule</mount>
<description>A description of this model (metadata)</description>
<items>
<exampleNumber type="TextField">
<Mask>/^([0-9]){0,1}$/</Mask>
<Default>5</Default>
<ValidationMessage>you should input a number from 0 to 9</ValidationMessage>
</exampleNumber>
<contacts>
<entity type="ArrayField">
<email type="EmailField">
<ValidationMessage>you should input a valid email address!</ValidationMessage>
</email>
<name type="TextField"/>
</entity>
<someText type="TextField"/>
</contacts>
</items>
</model>
554
Now let’s explain what’s happing here one tag at a time.
the <model> tag is used for identification of the file. (this is a model file)
Next in line is the <mount> tag, this tells the system where this information lives in the
configuration file, in this case ROOT_tag/myManufacturer/myModule
If desired, there is some space reserved to explain the usage of the model, the
<description> tag
Last item on the top of our list is the <items> tag, this is where the magic begins.
The content of a items tag describes the full tree based structure which holds our data,
in theory this could be as large as you want it to be, but keep in mind that the content for
your model should be logical and understandable. Every node in the tree could have a
type, which defines it’s behavior, nodes without a type are just containers.
Mask, validation can be performed by a regex expression, this sets the expression
555
when validation fails, the ValidationMessage is returned
someText, not part of the entity tag and also defined as text without validation
The fieldtypes are easily extendable in the base system and they all live in their own
namespace at OPNsense\Base\FieldTypes deriving from BaseField.
Usage example
Now let’s test our model using a small php script (in /usr/local/opnsense/mvc/script/ ):
<?php
// initialize phalcon components for our script
require_once("load_phalcon.php");
// create a new model, reading the model definition and the current data from our config.xml
$myMdl = new myModel();
$myMdl->exampleNumber =1;
$myMdl->contacts->someText = "just a test";
556
// if validation succeeded, write data back to config
if ($validationMessages->count() == 0) {
// serialize our model to the config file (config.xml)
// (this raises an error on validation failures)
$myMdl->serializeToConfig();
$cnf = Config::getInstance();
$cnf->save();
}
If you fill in an invalid value to one of the validated fields, you can easily try the
validation. Try to input the text “X” into the field exampleNumber to try out.
When inspecting our config.xml file, you will notice the following content has been added
to the root:
<myManufacturer>
<myModule>
<exampleNumber>1</exampleNumber>
<contacts>
<entity>
<email>test@test.com</email>
<name>my test user</name>
</entity>
<someText>just a test</someText>
</contacts>
</myModule>
</myManufacturer>
Guidelines
Some (simple) guidelines developing models
One model should always be completely responsible for the its mount point, so if there’s
a model at mount point /A/B there can’t be a model at /A/B/C
557
Try to keep models logical and understandable, it’s better to build two models for you
application if the content of two parts aren’t related to each other. It’s no issue to create
models at deeper levels of the structure.
When using more models in a application/module, you might want to consider the
following naming convention: /Vendor/Module/Model
Try to avoid more disc i/o actions than necessary, only call save() if you actually want to
save content, serializeToConfig just keeps the data in memory.
558
Routing
General
To retain backward compatibility with legacy code, we try to keep the old pages at their
original location. For the new code, we define two root folders in the url:
This part of the routing is handled by lighthttpd using mod_alias and mod_rewrite.
At the first level we use the vendor of the app, in our case that will always be OPNsense.
The next level is used to name the topic (or app), for example we use Sample for our
example application.
Finally you may place your standard Phalcon classes for controllers in that directory, so
if you want to create a page helloworld, that should come with a controller
helloworldController.php (and a indexAction to define the index action for that page).
559
/usr/local/opnsense/mvc/app/controllers/OPNsense/Sample/helloworldController.php
When publishing the page, the vendor part of the controller is not used in the mapping,
so in this example the helloworld index page will be at:
https://{url}/ui/sample/helloworld/
All the parts of the url are automatically converted to lower-case, so Sample will be
mapped to sample.
This routing is setup via the index page of our new code base and uses
API routing
Routing for api functions is quite similar to routing UI components, just create a Api
directory under the app path and place a controller class to handle the request. The only
major difference is that it’s handled by a separate php file (called api.php) in stead of the
index.php file used to configure the ui part, details of the routing can be found in
/usr/local/opnsense/mvc/app/config/services_api.php .
If our sample app needs an api to echo something back via a controller called tools it
could be put into a file called:
/usr/local/opnsense/mvc/app/controllers/OPNsense/Sample/Api/toolsController.api
560
https://{host}}/api/sample/tools/echo
561
Using controllers and views
General
After routing is performed, the controller takes care of the actual code to execute for the
request. Because we want to implement some basics for every request that gets
processed you should inherit from our base classes to ensure basic functionality such as
authorisation and csrf protection.
For a detailed description of how Controllers work in Phalcon, please look at the Phalcon
documentation at http://docs.phalconphp.com/en/latest/reference/controllers.html
The wireframe for implementing a single action should look like this:
<?php
public function indexAction()
{
// address some variables to pass through the view
$this->view->my_variable1 = 'test 1';
562
$this->view->my_variable2 = 'test 2';
// pick a template
$this->view->pick('SampleVendor/Sample/index');
}
563
$message = " " ;
}
When placed inside the api directory of Vendor/Sample can be called by sending a post
request to /api/sample/test/echo, using jquery:
$.ajax({
type: "POST",
url: "/api/sample/test/echo",
success: function(data){
alert(data.message) ;
},
data:{message:"test message"}
});
564
Components
OPNsense® components are not directly related to the front and backend.
For the OPNsense framework we’ve developed some shared components for common
tasks, this page indexes those components which aren’t directly related to the Model
View Controller
[https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller] (MVC)
framework itself.
Menu System
Access Control List
565
Menu System
OPNsense Menu System
Overview
One of the shared components of the OPNsense framework is the menu system, which
is wrapped in a single class and part of the base model.
The only responsibility of the menu system is to create a tree like structure to represent
the menu and being able to keep track of the mapping between a location and the
566
hierarchy of the menu system. To keep things clean and understandable, the menu
system doesn’t know anything about users or authorisation.
Currently the main focus for the menu system is to support the legacy code, so we will
be able to reimplement the menu in both legacy and new code.
The current version only implements a static menu defined by one xml file
(models/OPNsense/Base/Menu/Menu.xml), but extending with additional xml files is
already supported in the component for future use.
Menu.xml
The menu xml is defined as follows:
<menu>
<MainItem order="0" VisibleName="System" cssClass="glyphicon glyphicon-dashboard">
<SubItem1 url="/ui/test.php"/>
<SubItem2 url="/ui/test2.php"/>
</MainItem>
</menu>
567
The top level should be named “menu” to let the system know this is a menu structure,
the next layers will be used for the structure of itself. To map the attributes to the menu
objects created there are setters in OPNsense\Base\Menu\MenuItem, in this version the
next attributes are supported:
568
Access Control List
Access Control List
Overview
The current ACL system is targeted at delivering backwards compatibility for legacy
code and being able to extend this a little to add new features without having to
reimplement the whole system.
In the legacy system the access control is using the following steps to determine if a
page can be accessed by a user:
569
The user, stored in the config.xml file at system/user (one item per user)
One or more groups for that user, stored in system/group which contains priv sections.
A php file binding the priv section content to a page mask (including wildcards)
Our temporary solution is to keep the user and the group in place and replace the php
file with a simple config in the model which uses the same mask construction there was
in the old codebase. To bind priv to pages, edit
models/OPNsense/Core/ACL_Legacy_Page_Map.txt
{% if acl.isPageAccessible(session.get('Username'),subMenuItem.Url) %}
this page is accessible
{% endif %}
570
571
Examples
Hello world module & plugin
572
Hello world module & plugin
Creating the hello world module
Goal
Goal for this sample
The goal of the “Hello world” module we’re creating in the example is to control a
program on our system named “testConnection.py”, which is part of the example
package available on GitHub. It will try to send an email using plain smtp and will
respond with a json text message about the result of that attempt.
Our application will need some settings to operate correctly, like an ip address and an
email address and we need to be able to run that application. Because this application
returns some valuable data for our users, we need to be able to fetch the response data
back.
573
Guidelines
Guidelines and coding style
574
For all OPNsense modules and applications there are some basic style and coding
guides which you should use.
Naming
When creating modules for OPNsense, always name your components like this:
VendorName/ModuleName
PHP code
Please use PSR-2 style (http://www.php-fig.org/psr/psr-2/) for all new code.
Architecture
Always make sure there’s a clear separation of concerns, back-end calls (like shell
scripts) should be implemented using the configd system, all communication to the client
should be handled from an api endpoint. (the example provides more insights on how
this works).
Back-end programs should not access the config.xml directly, if data is needed let the
template system handle the desired output (most applications, daemons and tools
deliver their own desired configuration format). There’s generally no good reason to
avoid the standards that are already there.
If you follow this basic rules, you’re automatically building a command structure for the
system administrators and provide a connector to third party tools to the API of your
component (as of version 16.1).
575
Skeleton
Setup a skeleton for the frontend / middleware
First step for our project is to build a skeleton which holds the structure for our
frontend/middleware.
Model
For our sample application we want to setup some configuration data, which for all new
style projects should live in it’s own model.
The first one is the boilerplate for the model class, which should contain model specific
methods and (by deriving it from BaseModel) automatically understands the second file.
<?php
namespace OPNsense\HelloWorld;
use OPNsense\Base\BaseModel;
(/usr/local/opnsense/mvc/app/models/OPNsense/HelloWorld/HelloWorld.php)
Not all modules contain additional code in the php class, sometimes all the standard
behaviour is already sufficient for your modules/application.
Which is the model xml template, our skeleton starts with something like this:
576
<model>
<mount>//OPNsense/helloworld</mount>
<description>
the OPNsense "Hello World" application
</description>
<items>
</items>
</model>
(/usr/local/opnsense/mvc/app/models/OPNsense/HelloWorld/HelloWorld.xml)
The content of the mount tag is very important, this is the location within the config.xml
file where this model is responsible. Other models cannot write data into the same area.
You should name this location with your vendor and module name to make sure others
could easily identify it.
Use the description tag to identify your model, the last tag in place is the items tag,
where the actual definition will live. We leave it empty for now as we proceed with the
next step of creating our skeleton.
View
Page template (View)
We should add a (Volt) template to use for the index page of our module; we will use the
same naming convention here.
<h1>Hello World!</h1>
577
(/usr/local/opnsense/mvc/app/views/OPNsense/HelloWorld/index.volt)
Controller
Next step is to add controllers, which will be automatically picked up by the system
routing. A controller connects the user interaction to logic and presentation.
Every OPNsense module should separate presentation from logic, that’s why there
should always be multiple controllers per module.
Our first controller handles the template rendering to the user and connects the user
view we just created. We start by creating a php file in
controllers/OPNsense/HelloWorld/ with the following name IndexController.php and
contents:
<?php
namespace OPNsense\HelloWorld;
class IndexController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
// pick the template to serve to our users.
$this->view->pick('OPNsense/HelloWorld/index');
}
}
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/IndexController.php)
At this point you should be able to test if your work so far was successful, by going to the
following location (after being logged in to the firewall as root user):
http[s]://<your ip>/ui/helloworld/
578
Which should serve you the “Hello World!” text you’ve added in the template.
Next two controllers we are going to create are to be used for the api to the system, they
should take care of service actions and the retrieval/changing of configuration data.
They should live in a subdirectory of the controller called Api and extend the
579
corresponding class.
For our modules we create two api controllers, one for controlling settings and one for
performing service actions. (Named SettingsController.php and ServiceController.php)
Both should look like this (replace Settings with Service for the other one):
<?php
namespace OPNsense\HelloWorld\Api;
use \OPNsense\Base\ApiControllerBase;
class SettingsController extends ApiControllerBase
{
}
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/SettingsController.php)
The first step in building forms is to determine what information we should collect.
Our simple application will send an email using data in our configuration xml. For this
very module we want to collect the following:
580
General.ToEmail <empty> Email address to send our test email to
Adding Fields
Adding fields to your model
When building the skeleton, we have created an empty model (xml), which we are going
to fill with some attributes now. The items section of the model xml should contain the
structure you want to use for your application, you can create trees to hold data in here.
All leaves should contain a field type to identify and validate it’s content. The list of
attributes for our application can be translated to this:
………
<items>
<!-- container -->
<general>
<!-- fields -->
<Enabled type="BooleanField">
<default>1</default>
<Required>Y</Required>
</Enabled>
<SMTPHost type="NetworkField">
<Required>Y</Required>
</SMTPHost>
<FromEmail type="EmailField">
<default>sample@example.com</default>
<Required>Y</Required>
</FromEmail>
<ToEmail type="EmailField">
<Required>Y</Required>
</ToEmail>
<Description type="TextField">
<Required>Y</Required>
581
</Description>
</general>
</items>
………
Presentation XML
Create a presentation xml to feed your template
Because creating forms is one of the key assets of the system, we have build some
easy to use wrappers to guide you through the process. First we create an xml file for
the presentation, which defines fields to use and adds some information for your
template to render. Create a file in your controller directory using the sub directory forms
and name it general.xml. Next copy in the following content:
<form>
<field>
<id>helloworld.general.Enabled</id>
<label>enabled</label>
<type>checkbox</type>
<help>Enable this feature</help>
</field>
<field>
<id>helloworld.general.SMTPHost</id>
<label>SMTPHost</label>
<type>text</type>
<help><![CDATA[ip address of the mail host]]></help>
<hint>choose a valid IPv4/v6 address</hint>
</field>
<field>
<id>helloworld.general.FromEmail</id>
<label>Email (from)</label>
582
<type>text</type>
</field>
<field>
<id>helloworld.general.ToEmail</id>
<label>Email (to)</label>
<type>text</type>
</field>
<field>
<id>helloworld.general.Description</id>
<label>Description</label>
<type>text</type>
</field>
</form>
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/forms/general.xml)
All items should contain at least an id (where to map data from/to), a type (how to
display) and a label, which identifies it to the user. Optional you may add additional fields
like help or mark features as being only for advanced users. (The Volt template defines
which attributes are usable.)
Now we need to tell the controller to use this information and pass it to your template, so
change the IndexController.php and add this line:
$this->view->generalForm = $this->getForm("general");
And we are ready to update the (Volt) template with this information. Let’s remove the
“<h1>Hello World!</h1>” line and replace it with something like this:
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings'
This tells the template system to add a form using the contents of generalForm and
583
name it frm_GeneralSettings in the html page. Based on a standard template part which
is already part of the standard system, named base_form.volt.
584
The framework provides some helpful utilities to get and set data from and to the
configuration xml by using your defined model. First step in binding your model to the
system is to add a method to the SettingsController to fetch the data from our
configuration (or provide the defaults if there is no content).
We start by adding the model to our SettingsController, by adding this in the “use”
section:
use \OPNsense\HelloWorld\HelloWorld;
Which includes our model into the controller. Next we create an action to get data from
our system, and put it into a json object for the client (browser) to parse, by using the
wrappers already in our model.
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/SettingsController.php)
You will probably notice the return value of the action, it’s a standard array which uses
“helloworld” for all attributes from getNodes() which will automatically be converted by
the framework to a json object for the client. The getNodes method itself returns a tree a
585
values, as defined by your model.
You can test the result (while logged in as root), by going to this address:
http[s]://<your ip>/api/helloworld/settings/get
For saving the data back, we need a similar kind of call, let’s name it “set” and add this
to the same php file:
/**
* update HelloWorld settings
* @return array status
*/
public function setAction()
{
$result = array("result"=>"failed");
if ($this->request->isPost()) {
// load model and update with provided data
$mdlHelloWorld = new HelloWorld();
$mdlHelloWorld->setNodes($this->request->getPost("helloworld"));
// perform validation
$valMsgs = $mdlHelloWorld->performValidation();
foreach ($valMsgs as $field => $msg) {
if (!array_key_exists("validations", $result)) {
$result["validations"] = array();
}
$result["validations"]["general.".$msg->getField()] = $msg->getMessage();
}
586
}
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/SettingsController.php)
And include the Config class from our base system by adding this to the “use” section:
use \OPNsense\Core\Config;
Now we need to link the events to the backend code to be able to load and save our
form, by using the OPNsense libraries you can validate your data automatically.
<script type="text/javascript">
$( document ).ready(function() {
var data_get_map = {'frm_GeneralSettings':"/api/helloworld/settings/get"};
mapDataToFormUI(data_get_map).done(function(data){
// place actions to run after load, for example update form styles.
});
});
587
</script>
<div class="col-md-12">
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}
</div>
The first piece of javascript code handles the loading of data when opening the form,
then a button is linked to the save event.
Let’s give it a try and save our data, without modifying it first.
588
Next correct the errors and save again, on successful save the data should be stored in
the config.xml. If you want to change validation messages, just edit the model xml and
add your message in the ValidationMessage tag. For example:
<ToEmail type="EmailField">
<Required>Y</Required>
<ValidationMessage>please specify a valid email address</ValidationMessage>
</ToEmail>
589
Changes the “email address invalid” into “please specify a valid email address”
Add actions
Add some activity to the module
Our basic module provides a way to read and modify configuration data using the web
interface (and in time also other consumers using the api). Next step is to add some
activity to our system, all backend applications should use their own configuration, which
in real life we would keep as standard as possible.
For our example we will follow the same process as for any other service and start
writing some configuration data for our sample application. Which means, creating a
template and hooking it into our save action.
The configd system is responsible for updating the contents of that file when requested,
it does so by using a definition found in its template folder. This sample will use the
following path to store the backend templates:
/usr/local/opnsense/service/templates/OPNsense/HelloWorld/
First we add a content definition, by creating a file named +TARGETS, which should
hold the following information:
helloworld.conf:/usr/local/etc/helloworld/helloworld.conf
This basically tells the engine that there will be a file in the same folder named
590
“helloworld.conf” which provides, together with config.xml, data for the file in
/usr/local/etc/helloworld/helloworld.conf
Next thing to do is create that helloworld.conf file in the templates directory. We will keep
things very simple for this one and just copy in our data into an ini file structured
configuration, when the module is enabled.
Now we need to be able to reload this module (or in real life, this would probably be a
service) by adding a service action into our ServiceController. Edit
controllers/OPNsense/HelloWorld/Api/ServiceController.php and add the backend
module to the use section, like this:
use \OPNsense\Core\Backend;
By doing this we can use the backend communication in this class. Next add a new
action to the class called “reloadAction” using this piece of code:
591
$status = "ok";
}
}
return array("status" => $status);
}
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/ServiceController.php)
This validates the type of action (it should always be POST to enable csrf protection)
and adds a backend action for reloading the template. When successful the action will
return “status”:”ok” as json object back to the client.
Now we are able to refresh the template content, but the user interface doesn’t know
about it yet. To hook loading of the template into the save action, we will go back to the
index.volt view and add the following jQuery / framework code between the braces of
“saveFormToEndPoint”.
ajaxCall(url="/api/helloworld/service/reload", sendData={},callback=function(data,status
// action to run after reload
});
If you save the form now (when enabled), you should see a new file in
helloworld.conf:/usr/local/etc/helloworld/helloworld.conf
[general]
SMTPHost=127.0.0.1
FromEmail=sample@example.com
ToEmail=sample@example.com
592
Subject=test
What have we accomplished now, we can input data, validate it and save it to the
corresponding format of the actual service or application, which uses this data. So if you
have a third party application, which you want to integrate into the user interface. You
should be able to generate what it needs now. (there’s more to learn, but these are the
basics).
But how do should we control that third part program now? That’s the next step.
Another advantage of this approach is that all commands defined here, can also be ran
from the command line of the firewall providing easier serviceability. For example, the
command to refresh the helloworld configuration can be run from the command line by
running:
First thing to do when registering new actions to the system for a new application is to
create a config template.
/usr/local/opnsense/service/conf/actions.d/actions_helloworld.conf
593
And add a command to the template like this:
[test]
command:/usr/local/opnsense/scripts/OPNsense/HelloWorld/testConnection.py
parameters:
type:script_output
message:hello world module test
Let’s test our new command by restarting configd from the command line:
Next step is to use this command in our controller (middleware), just like we did with the
template action. For consistency we call our action testAction and let it pass json data to
our clients when using a POST type request.
594
return array("message" => "unable to run config action");
}
(/usr/local/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/ServiceController.php)
And now we can make our user interface aware of the action, place a button and link an
action in the index.volt. Using the following elements:
</div>
<button class="btn btn-primary" id="testAct" type="button"><b>{{ lang._('Test') }}</b></button>
(/usr/local/opnsense/mvc/app/views/OPNsense/HelloWorld/index.volt)
Now go back to the page and save some data using the save button, next press test to
see some results.
595
Multi language / Translations
OPNsense is available in may different languages like english, german or japanese. This
works because we are using the gettext library which is available to all GUI components.
596
While the XML based user interfaces are supporting it automatically, there may still the
need to call it manually (buttons, tabs etc.).
If you have a static string, you should add it like this into a classic php page:
If your string is not only plaintext because it contains non-static words, HTML tags and
other dynamic content, you need to use a format string. This way, you can use
placeholders for such elements which should not land in the translation file.
Note
You should NEVER split strings which should belong together like a sentence. This
makes plugins hard to translate and will decrease the quality of OPNsense in other
languages.
597
Plugin to the menu system
Most modules and applications need a place in the menu system, you could easily
arrange that by creating a Menu.xml definition for your module in the model directory
under Menu/Menu.xml.
Now let’s register our “hello world” in the user section of our menu, by adding this
content into the menu.xml:
<menu>
<!-- Plugin HelloWorld menu -->
<User order="999">
<HelloWorld VisibleName="Hello World!" url="/ui/helloworld/"/>
</User>
</menu>
When you refresh your page now, you should notice the menu system automatically
picks up this new information.
598
Plugin to access control (ACL)
If we want to authorize users to access this module, we can add an acl to this module.
Without it, only admin users can access it. Create an xml file in the model directory
599
name ACL/ACL.xml and place the following content in it:
<acl>
<!-- unique acl key, must be globally unique for all acl's -->
<page-user-helloworld>
<name>WebCfg - Users: Hello World! </name>
<description>Allow access to the Hello World! module</description>
<patterns>
<pattern>ui/helloworld/*</pattern>
<pattern>api/helloworld/*</pattern>
</patterns>
</page-user-helloworld>
</acl>
This creates an acl key named “page-user-helloworld” which authorizes access to both
the ui and api urls of this application. You can now grant access to this module from the
system user manager.
When everything is in place, we will create a new plugin directory. For this example we
will use the following:
/usr/plugins/devel/helloworld/
600
PLUGIN_NAME= helloworld
PLUGIN_VERSION= 1.0
PLUGIN_COMMENT= A sample framework application
#PLUGIN_DEPENDS=
PLUGIN_MAINTAINER= user@domain
.include "../../Mk/plugins.mk"
Next copy all files created and located in /usr/local/ into this new src directory, which
results in the following file listing:
src/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/ServiceController.php
src/opnsense/mvc/app/controllers/OPNsense/HelloWorld/Api/SettingsController.php
src/opnsense/mvc/app/controllers/OPNsense/HelloWorld/IndexController.php
src/opnsense/mvc/app/controllers/OPNsense/HelloWorld/forms/general.xml
src/opnsense/mvc/app/models/OPNsense/HelloWorld/ACL/ACL.xml
src/opnsense/mvc/app/models/OPNsense/HelloWorld/HelloWorld.php
src/opnsense/mvc/app/models/OPNsense/HelloWorld/HelloWorld.xml
src/opnsense/mvc/app/models/OPNsense/HelloWorld/Menu/Menu.xml
src/opnsense/mvc/app/views/OPNsense/HelloWorld/index.volt
src/opnsense/scripts/OPNsense/HelloWorld/testConnection.py
src/opnsense/service/templates/OPNsense/HelloWorld/+TARGETS
src/opnsense/service/templates/OPNsense/HelloWorld/helloworld.conf
src/opnsense/service/conf/actions.d/actions_helloworld.conf
Next add a +POST_INSTALL file in the plugin directory, to reload the configd process
after installation. This is needed for the new “test” command to register.
601
fi
With everything in place, you could build the plugin package using the “make plugins”
command in the /usr/tools directory. The result of this will be a standard pkg package,
which you can install on any OPNsense system and will be usable right after installing.
All plugins are prefixed with os-, our new package file will be called:
os-helloworld-1.0.txz
Reference
602
603
How to’s
Use the API
604
Use the API
Overview
All components that are using the full architecture of OPNsense automatically receive
API capabilities, for this simple tutorial we use the firmware module but others will
function in the same way. API access is part of the local user authentication system, but
uses key/secret pairs to separate account information from machine to machine
communication. Secrets are not stored on OPNsense and can be downloaded only
once, if lost, a new key has to be generated for your application.
A user can have multiple keys, our advice is to create a unique key for every application
in use.
Creating keys
API keys are managed in the user manager (system_usermanager.php), go to the user
manager page and select a user. Somewhere down the page you will find the api section
for this user.
Click on the + sign to add a new key. When the key is created, you will receive a (single
download) with the credentials in one text file (ini formatted). The contents of this file
look like this:
key=w86XNZob/8Oq8aC5r0kbNarNtdpoQU781fyoeaOBQsBwkXUt
605
secret=XeD26XVrJ5ilAc/EmglCRC+0j2e57tRsjHwFepOseySWLM53pJASeTA3
Before you can start, make sure your OPNsense has a valid SSL certificate (or choose
to ignore it for testing purposes by setting verify=False), don’t forget to verify that the
selected user may access the firmware page.
The web interface uses the same logic that will be available for the api, in this example
we will collect some status information from the firmware module and print it out for the
user.
It all starts with creating the request and waiting for the response, all data interaction is
using json format, both for the responses as for the request data (when sending POST
data).
First step of the example is importing the required libraries, then define the endpoint url
and credentials to use and finally fire the (get type) request. As soon as we receive the
response, we parse the json string back to a dictionary and print some data depending
on the response.
# import libraries
import json
import requests
606
# request data
r = requests.get(url,
verify='OPNsense.pem',
auth=(api_key, api_secret))
if r.status_code == 200:
response = json.loads(r.text)
Using curl
Simple testing with curl is also possible, the sample below uses the same credentials,
but ignores the ssl certificate check (-k) for testing.
curl -k -u "w86XNZob/8Oq8aC5hxh2he+vLN00r0kbNarNtdpoQU781fyoeaOBQsBwkXUt":"puOyw0Ega3xZXeD26XVrJ5WY
607
608
Project Relations
The OPNsense® development team believes that sharing knowledge makes better
products. The team is proud on it relations with other projects & organizations and likes
to mention them and their hard work. More details may be found on these pages.
FreeBSD®
Deciso B.V.
HardenedBSD
M0n0wall
Open Source Initiative
609
FreeBSD®
FreeBSD is a registered trademark of The FreeBSD Foundation. The FreeBSD logo and
The Power to Serve are trademarks of The FreeBSD Foundation.
About FreeBSD
FreeBSD is an operating system for a variety of platforms which focuses on features,
speed, and stability. It is derived from BSD, the version of UNIX® developed at the
University of California, Berkeley. It is developed and maintained by a large community.
See also
610
To convert your FreeBSD hosted installation to OPNsense, see the OPNsense bootstrap
script on OPNsense’s update tools @ github [https://github.com/opnsense/update/]
611
Deciso B.V.
About
Deciso [https://www.deciso.com] is a globally operating manufacturer of network
equipment and a highly innovative company that develops network appliances and
middleware software.
Our field of expertise ranges from open source firewall & utm technology to
telecommunications and business intelligence. The company was founded in 2000 with
a strong focus on open source technology.
Open source software makes development easier, faster, it makes you less depended
on the supplier and results in lower cost of ownership. As a true believer Deciso use
open source software all around from our back-end systems to the turn-key appliances
that you can acquire from our resellers. Deciso is an active sponsor of the Open Source
Initiative (OSI) and founder of the open source OPNsense firewall software.
612
Deciso founded OPNsense and offers the project a stable environment. The company
has a long history in providing networking solutions using open source software and has
supported many OSS projects in the past.
In its effort to create the most widely used open source security platform, Deciso has
been joined by multiple partners who share the same views on open and transparent
software.
613
HardenedBSD
Introduction
Founded in 2014 by Oliver Pinter and Shawn Webb, HardenedBSD is a security-
enhanced fork of FreeBSD. The HardenedBSD Project is implementing many exploit
mitigation and security technologies on top of FreeBSD. The project started with
Address Space Layout Randomization (ASLR) as an initial focal point and is now
implementing further exploit mitigation techniques.
HardenedBSD’s Goals
HardenedBSD aims to implement innovative exploit mitigation and security solutions for
FreeBSD. We will work with FreeBSD and any other FreeBSD-based project to include
our innovations.
Who is HardenedBSD?
614
HardenedBSD’s core team consists of Oliver Pinter and Shawn Webb.
615
M0n0wall
Background
Manuel Kasper
Ever since I started playing with packet filters on embedded PCs, I wanted to
have a nice web-based GUI to control all aspects of my firewall without having
to type a single shell command.
There are numerous efforts to create nice firewall packages with web
interfaces on the Internet (most of them Linux based), but none met all my
requirements (free, fast, simple, clean and with all the features I need).
So, I eventually started writing my own web GUI. But soon I figured out that
I didn't want to create another incarnation of webmin – I wanted to create a
complete, new embedded firewall software package.
It all evolved to the point where one could plug in the box, set the LAN IP
address via the serial console, log into the web interface and set it up.
Then I decided that I didn't like the usual bootup system configuration with
shell scripts (I already had to write a C program to generate the filter rules
since that's almost impossible in a shell script), and since my web interface
was based on PHP, it didn't take me long to figure out that I might use PHP
for the system configuration as well.
That way, the configuration data would no longer have to be stored in text
files that can be parsed in a shell script – it could now be stored in an XML
file. So I completely rewrote the whole system again, not changing much in the
look-and-feel, but quite a lot "under the hood".
616
End of the m0n0wall project
The active development of m0n0wall ended in 2015.
on this day 12 years ago, I have released the first version of m0n0wall to
the public. In theory, one could still run that version - pb1 it was called -
on a suitably old PC and use it to control the Internet access of a small LAN
(not that it would be recommended security-wise). However, the world keeps
turning, and while m0n0wall has made an effort to keep up, there are now better
solutions available and under active development.
Therefore, today I announce that the m0n0wall project has officially ended.
No development will be done anymore, and there will be no further releases.
The forums and the mailing list will be frozen at the end of this month.
All the contents of the website, repository, downloads, mailing list and forum
will be archived in a permanent location on the web so that they remain
accessible indefinitely to anyone who might be interested in them.
m0n0wall has served as the seed for several other well known open source
projects, like pfSense, FreeNAS and AskoziaPBX.
The newest offspring, OPNsense (https://opnsense.org), aims to continue the open source
m0n0wall while updating the technology to be ready for the future. In my view,
it is the perfect way to bring the m0n0wall idea into 2015, and I encourage all
current m0n0wall users to check out OPNsense and contribute if they can.
Finally, I would like to take this opportunity to thank everyone who has been
involved in the m0n0wall project and helped in some way or another -
by contributing code, documentation, answering questions on the mailing
list or the forum, donating or just spreading the word. It has been a great
journey for me, and I'm convinced that even now that it has come to an end,
the m0n0wall spirit will live on in the various projects it has spawned.
617
Relations with OPNsense
Deciso B.V. the founder of OPNsense has taken over the m0n0wall websites from
Manuel Kasper and continues to offer all the sources, website & forum content both as a
historical reference as well as to preserve knowledge gained.
The OPNsense core team want to thank Manuel for all this effort as for him OPNsense
would not have been possible.
618
Open Source Initiative
About OSI
“We are the stewards of the Open Source Definition (OSD) and the community-
recognized body for reviewing and approving licenses as OSD-conformant.”
Relations OPNsense
OPNsense is licensed under an Open Source Initiative approved license
[http://opensource.org/licenses]. OPNsense is and will be available with the simple 2-
clause BSD license. We believe an open source project should provide the sources and
the tools to build it.
Deciso B.V.
619
As founder, trademark owner and largest sponsor of OPNsense, Deciso is an active
sponsor of the Open Source Initiative. see OSI Corporate Sponsors & Support
[http://opensource.org/sponsors]
620
Legal notices
The OPNsense project wants to be a project that is friendly for users, developers and
partners. In this world with trademarks and copyright it is best to “keep things as simple
as possible, but not simpler”. Below we pointed out the Licensing and Trademark rules
we use.
621
OPNsense is licensed under an Open Source Initiative approved license
[http://opensource.org/licenses].
622
We like the BSD license, a simple two clause license that gives freedom to the audience
we want to serve. It basically gives you the right to do whatever you want to do with the
code, even fork it and take it from there.
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
623
OPNsense is a fork of pfSense® [https://www.pfsense.org] (Copyright © 2004-2014
Electric Sheep Fencing, LLC. All rights reserved.) a fork from m0n0wall
[http://m0n0.ch/wall/] (Copyright © 2002-2013 Manuel Kasper).
The authors of OPNsense would like to thank all contributors for their efforts.
Documentation Copyright
The documentation is provided under a 2-clause BSD license:
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
624
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE OPNSENSE DOCUMENTATION PROJECT
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pictures Copyright
Some pictures are licensed under the Creative Commons Zero (CC0) license:
https://creativecommons.org/publicdomain/zero/1.0/
Logo’s Copyright
Logo’s may be subject to additional copyrights, property rights, trademarks etc. and may
require the consent of a third party or the license of these rights. Deciso B.V. does not
represent or make any warranties that it owns or licenses any of the mentioned, nor
does it grant them.
Trademark policy
OPNsense is a trademark. If you wish to use the name or logo in any way, you must
comply with this policy.
The name and logo may be used to promote OPNsense based products or services.
625
The name and logo may be used to promote or serve OPNsense or related projects and
their communities.
When using the logo on online media like websites, social media and apps the logo
should link to https://opnsense.org
You must request our permission to use derivatives of the name and/or logo at project
@ opnsense.org prior to any use of the derivative name and/or logo, and we may grant
or withhold permission to use the derivative name and/or logo in our sole discretion.
You may not state or otherwise lead people to believe, that you represent the OPNsense
project in any way other than as an individual or corporate contributor to the project.
If you have any questions about this policy, its interpretation, or want to ask for
permission please email project @ opnsense.org.
626
Support Options
Commercial
Extended professional support services are available for an annual fee. For the
commercial support options see the OPNsense website [https://opnsense.org/support-
overview/commercial-support/]
Community
If you need help with OPNsense you can always try the community options first. When
resorting to community support it is important to understand that anyone helping you is
doing so for free and at their own time. Even tough your issue or question might not be
answered fully it would be nice to thank the people who helped you.
627
Start searching this documentation & wiki
Functionality problems such as ‘known issues’ or might still going into releases,
Features require user to install the plugin / functionality not installed by default.
628
When accepting a Tier 3 feature into the code base, it will come with a number of limits
and conditions:
make sure code compiles and correctly functions after OPNsense and/or external (e.g.
library) changes,
support users when they encounter problems (forum / git issue tracker – all related
issues will be assigned to the maintainer).
The code is offered as plugin and will not be part of the default OPNsense installation.
The OPNsense core team will not be responsible for QA,
If the feature get lots of traction, and/or if the team just considers it very useful, it may
get ‘promoted’ to being officially supported (Tier 2),
The feature will be removed if the submitter stops maintaining it and no-one steps up to
take over.
629
Contribute
OPNsense is an open source community project that depends on your contributions for
its continuing development & success.
There are plenty of opportunities to contribute and help OPNsense reach its goal of
becoming the most widely used open source security & firewall platform. Financial
contributions are always welcome and will allow us to develop parts of the system that
may otherwise stay untouched.
The OPNsense core team wants to thank everyone who contributed already.
Financially
“An open source project can only thrive by the community around it.” We are grateful of
all the kind words and support the users of OPNsense are giving us.
Frequently users ask us how they can contribute to the project. To make the software
better we need your involvement in testing and providing feedback and if you can spare
a few bucks that would be great.
Donations
To enable us to continue development and keep on improving the project you can
contribute by donating to the project, this a simple non recurring - no strings attached -
way of supporting the project. Any amount will be gratefully accepted!
630
Partner program
The OPNsense project offers a partner program where businesses receive project
benefits while supporting the project financially.
Support Contract
with a support contract we support you and you support us as OPNsense is fully
supported by Deciso.
Development
Contributing to the ongoing development of OPNsense can be done by:
631
Testing a development version and
Note
Before you send in your pull request, please read our Coding Guidelines and see the
community support levels in the Support Options. It is important for plugin developers to
maintain their plugin and interact with users for QA.
Testing
Contribute by testing the latest development version to make the next release even
better than the last. If you like to test a development version then the easiest way is to
login to the console and type:
That is all there is to it to test the latest development release. Development releases are
632
usually built at the same day the latest production release comes available.
Reporting an issue
Issues can be easily reported on github, please consider carefully if the issue could be a
configuration or user error before reporting it. If you are unsure, report you issue on the
Forum [https://forum.opnsense.org] or on IRC/Freenode (#opnsense).
Fixing issues
If you are a programmer or just know how to fix a certain issue then you can help by
either sharing your ideas on or send in a pull request on github.
find one of us on IRC/Freenode (#opnsense) and see if we are available to discuss your
idea.
633
Translations
OPNsense has an active translation project [https://translate.opnsense.org/projects/],
currently supporting:
Czech
English
French
German
Japanese
Portuguese
Russian
Simplified Chinese
Working on translations is time consuming, but if you feel up to it and would like to help
adding another language, then please contact us via email (contact @ opnsense.org).
634
markup with ./images/directory including the used images(in any)
Your content does not include copyrighted material if you do not own the copyright
yourself
State that we may use the content under our Documentation Copyright as listed in the
Legal notices section.
Social media
Contribute to the success of the project by letting others know how OPNsense helped
solving your network or security challenges. Let others know about OPNsense and/or
follow us & retweet our messages on twitter [https://twitter.com/opnsense].
Anything you can do to spread the word about OPNsense will help to reach our goal to
become the most widely used open source security & firewall platform.
635
Closing Words
If you have suggestions on how others can contribute to OPNsense and it is not yet
listed on this page, then let us know. You can reach us at contact @ opnsense.org.
636
Index
Table of Contents
Welcome to OPNsense’s documentation! 1
About the Fork 4
About the Fork 4
Debunking the Myths 4
So why did we fork? 5
So why did we fork? 5
Technical 6
Security 6
Quality 6
Community 6
Transparency 7
Restore a firm open source project 7
First Release 7
Future Development & Focus 8
Future Development & Focus 8
Deciso’s involvement 8
Closing thoughts 8
Introduction 10
Introduction 10
Welcome to OPNsense’s documentation! 10
Mission Statement 10
Feature set 11
OPNsense Core Features 12
User Manual 15
User Manual 15
Hardware sizing & setup 18
Hardware sizing & setup 18
Supported hardware architectures 18
Hardware requirements 19
Impact of Feature set 21
Throughput 21
Initial Installation & Configuration 24
Initial Installation & Configuration 24
638
Architecture 24
Embedded vs Full 24
Download 25
Installation Media 26
Media Filename Composition 26
OpenSSL & LibreSSL 27
Installation Method 28
Initial configuration 32
Virtual & Cloud based Installation 36
Virtual & Cloud based Installation 36
Local/Server 36
Hosted 38
Amazon AWS EC2 Cloud 38
Common Issues 39
The OPNsense User Interface 41
The OPNsense User Interface 41
User Login 41
GUI Layout & Main Components 41
Form View 45
User Management 49
User Management 49
Authentication 50
Authorization 50
Users, Groups & Privileges 50
Services 51
Configuration 51
Local User Manager 51
LDAP 52
Radius 52
Using IPv6 53
Using IPv6 53
Configuring 54
Two-factor authentication 55
Two-factor authentication 55
GUI Fallback Configuration 57
Time-based One-time Password 58
639
Google Authenticator 58
Other TOTP tokens 58
Configuration & Setup 59
System Health & Round Robin Data 60
System Health & Round Robin Data 60
Data collectors 60
GUI Features Overview 61
Netflow Export & Analyses 72
Netflow Export & Analyses 72
Supported Versions 74
Netflow Basics 74
Netflow Exporter 75
Netflow Analyzer - Insight 76
Configuration 78
Using Aliases 79
Using Aliases 79
Alias Types 79
Hosts 79
Networks 81
Ports 81
URL Tables 82
GeoIP 82
Import Feature 83
Using Aliases in pf Firewall Rules 84
Advanced 86
GeoIP’s 86
Configure DROP and EDROP lists 87
Virtual Private Networking 88
Virtual Private Networking 88
Supported VPN technologies 90
Configuration 92
Inline Intrusion Prevention System 94
Inline Intrusion Prevention System 94
Emerging Threats ETOpen Ruleset 94
Abuse.ch 94
640
Maxmind GeoLite2 Country 95
Finger Printing 96
How-to’s 96
Caching Proxy 115
Caching Proxy 115
Authenticators 116
Access Control 116
Traffic Management 117
Category Based Web Filter 117
Transparent Mode 118
Configuration / HOW-TO’s 118
Anti Virus Engine 120
Anti Virus Engine 120
Setup ICAP Anti Virus Engine 121
Traffic Shaping 122
Traffic Shaping 122
Introduction 123
Dummynet & ipfw 123
Configuration 124
Multi WAN 125
Multi WAN 125
WAN Failover 125
WAN Load Balancing 125
Combining Balancing & Failover 125
Configuration 125
Mobile Networking 127
Mobile Networking 127
Supported Devices 128
Configure Cellular modems 128
3G - 4G Cellular Failover 128
High Availability & Hardware Failover 129
High Availability & Hardware Failover 129
Automatic failover 129
Synchronized state tables 130
Configuration synchronization 130
Configure HA CARP 130
641
Captive portal & GuestNET 131
Captive portal & GuestNET 131
Typical Applications 131
Template Management 132
Zone Management 132
Authentication 132
Voucher Manager 133
Timeouts & Welcome Back 133
Bandwidth Management 133
Portal bypass 134
Real Time Reporting 134
Category based Web Filtering 134
Platform Integration 134
Configure the Portal 134
Dynamic Routing 136
Dynamic Routing 136
Installation 137
Configuration 137
How To 138
OPNsense Tools 139
OPNsense Tools 139
opnsense-update 139
opnsense-revert 140
opnsense-patch 141
How to’s 143
How to’s 143
Configuration Cloud Backup 145
Organize PF Rules by Category 152
Transparent Filtering Bridge 157
IPS SSLBlacklists & Feodo Tracker 97
IPS GeoIP Blocking 104
IPS Block SSL certificates 109
Setup Caching Proxy 165
Setup Transparent Proxy 174
Setup Web Filtering 182
Setup Anti Virus Protection 188
642
Configure CARP 194
Setup IPsec Road-Warrior 201
Setup IPsec site to site tunnel 213
Setup SSL VPN Road Warrior 228
Setup SSL VPN site to site tunnel 245
Setup FreeRADIUS for accounting 256
Setup Traffic Shaping 259
Using Insight - Netflow Analyzer 284
Configure Netflow Exporter 294
Configure 2FA TOTP & Google Authenticator 296
Configuring Cellular Modems 309
IPv6 For Zen UK 314
c-icap 327
ClamAV 332
Dynamic Routing: How To 339
Dynamic Routing: Configuration: OSPFv2 342
Dynamic Routing: Configuration: RIP 348
Dynamic Routing: Configuration: Zebra 351
Configure Spamhaus (E)DROP 353
FreeRADIUS 362
Setup a Guest Network 368
HAProxy 395
HAProxy How-Tos 407
Installing OPNsense AWS image 414
IPSec BINAT 425
Configure IPv6 Tunnel Broker 427
How To: Setting Up A Mail Gateway 436
Multicast DNS Proxy 443
Setup Multi WAN 446
Setup Anti Virus Protection using OPNsense Plugins 454
Tor Configuration 457
Configuring LDAP 472
Creating Users & Groups 479
Configuring Radius 484
Zerotier Configuration 486
Overview 490
643
Interface Assignment 492
Development Manual 494
Development Manual 494
Development Workflow 496
Development Workflow 496
Structure 496
Building 497
Virtual Machine for Development 498
Packages 499
Summary 500
Coding Guidelines 502
Coding Guidelines 502
Basics and Future 503
PSR-1 Basic Coding Standard 506
PSR-2 Coding Style Guide 512
Python PEPs 529
Architecture 530
Architecture 530
High-level architecture 530
Backend Architecture 532
Frontend Architecture 534
Backend 537
Backend 537
Bootup / autorun options 539
Using configd 541
Using legacy plugins 544
Using Templates 548
Frontend 552
Frontend 552
Creating Models 553
Routing 559
Using controllers and views 562
Components 565
Components 565
Menu System 566
644
Access Control List 569
Examples 572
Examples 572
Hello world module & plugin 573
How to’s 604
How to’s 604
Use the API 605
Sources 495
Project Relations 609
Project Relations 609
FreeBSD® 610
FreeBSD® 610
About FreeBSD 610
Relations with OPNsense 610
Deciso B.V. 612
Deciso B.V. 612
About 612
Relations with OPNsense 613
HardenedBSD 614
HardenedBSD 614
Introduction 614
Why Fork FreeBSD? 614
HardenedBSD’s Goals 614
Who is HardenedBSD? 614
Cooperation with OPNsense 615
M0n0wall 616
M0n0wall 616
Background 616
End of the m0n0wall project 617
Relations with OPNsense 618
Open Source Initiative 619
Open Source Initiative 619
About OSI 619
Relations OPNsense 619
Deciso B.V. 620
645
Legal notices 621
Legal notices 621
OPNsense License & Copyright 621
Packages and ports 624
Documentation Copyright 624
Pictures Copyright 625
Logo’s Copyright 625
Trademark policy 626
Support Options 627
Support Options 627
Commercial 627
Community 627
Community Support Levels 628
Community Support Levels 628
Tier 1 – Core (Critical) 628
Tier 2 – Plugins (Non-Critical) 628
Tier 3 – Plugins (Community) 629
Contribute 630
Contribute 630
Financially 630
Financially 630
Donations 630
Partner program 631
Support Contract 631
Development 632
Development 632
Testing 632
Reporting an issue 633
Fixing issues 633
Designing new features 633
Translations 634
Documentation & wiki articles 635
Forum & IRC 635
Social media 635
Closing Words 636
646
647