OPNsense

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 647

Welcome to OPNsense’s

documentation!
OPNsense® [https://opnsense.org] is an open source, easy-to-use and easy-to-build
FreeBSD based firewall and routing platform.

OPNsense includes most of the features available in expensive commercial firewalls,


and more in many cases. It brings the rich feature set of commercial offerings with the
benefits of open and verifiable sources.

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.

Debunking the Myths


There are some myths surrounding our project offered mostly by pfSense enthusiasts, if
you have read their comments on us then we’d recommend to just ignore them and
install OPNsense, if you have not already done so.

Lets fork and lift the project!

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…

Restore a firm open source project


With OPNsense we have restored a stable project with clear goals and a very simple
license that is suitable for forking and making OEM versions. We think a community
project is there for all to use and work with.

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),

The firmware upgrade process is now done with pkgng,

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,

The check_reload_status functionality, effectively the backend daemon starting and


stopping components, has been fully rewritten in Python (configd),

Fully reworked the GUI to a modern Bootstrap based one that is also easier to
customize if you want to.

Future Development & Focus


Moving forward the focus will remain on code quality and security.

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.

Welcome to OPNsense’s documentation!


OPNsense® [https://opnsense.org] is an open source, easy-to-use and easy-to-build
FreeBSD based firewall and routing platform.

OPNsense includes most of the features available in expensive commercial firewalls,


and more in many cases. It brings the rich feature set of commercial offerings with the
benefits of open and verifiable sources.

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.

OPNsense Core Features


Traffic Shaper

Captive portal

Voucher support

Template manager

Multi zone support

Forward Caching Proxy

Transparent mode supported

Blacklist support

Virtual Private Network

Site to site

Road warrior

IPsec

OpenVPN

12
High Availability & Hardware Failover

Includes configuration synchronization & synchronized state tables

Can be combined with Traffic Shaping

Intrusion Detection and Inline Prevention

Build-in support for Emerging Treats rules

Simple setup by use of rule categories

Scheduler for period automatic updates

Build-in reporting and monitoring tools

System Health, the modern take on RRD Graphs

Packet Capture

Support for plugins

DNS Server & DNS Forwarder

DHCP Server and Relay

Dynamic DNS

Backup & Restore

Encrypted cloud backup to Google Drive

13
Configuration history with colored diff support

Local drive backup & restore

Stateful inspection firewall

Granular control over state table

802.1Q VLAN support

and more..

14
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

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

Supported hardware architectures


OPNsense® is available for x86-32 [https://en.wikipedia.org/wiki/X86-32] (i386) and x86-
64 [https://en.wikipedia.org/wiki/X86-64] (amd64) bit microprocessor architectures. Full
installs 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] are intended for OPNsense.

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).

Processor 500MHz single core cpu

RAM 512 MB

Install method Serial console or video (vga)

Install target SD or CF card with a minimum of 4GB, use nano images for
installation.

Table: Minimum hardware requirements

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.

Processor 1 GHz dual core cpu

RAM 1 GB

Install method Serial console or video (vga)

19
Install target 40 GB SSD, a minimum of 1GB memory is needed for the installer to
run.

Table: Reasonable hardware requirements

Recommended

The recommended specification to run all OPNsense standard features, means every
feature is functional and fits most use cases.

Processor 1.5 GHz multi core cpu

RAM 4 GB

Install method Serial console or video


(vga)

Install target 120 GB SSD

Table: Recommended hardware requirements

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.

Impact of Feature set


While most features do not effect hardware dimensioning, a few features have massive
impact on it. The candidates are:

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.

Captive portal [https://en.wikipedia.org/wiki/Captive_portal]


settings with hundreds of simultaneously served captive portal users will require more
CPU power in all the hardware specifications displayed below.

State transition tables


[https://en.wikipedia.org/wiki/State_transition_table]
it is a known fact, that each state table entry requires about 1KB (kilo bytes) of RAM.
The average state table, filled with 1000 entries will occupy about ~10MB (mega bytes)
of RAM [https://en.wikipedia.org/wiki/Random-access_memory]. OPNsense usage
settings with hundred of thousands of connections will require memory accordingly.

Throughput
The main hardware-factors of the OPNsense setup involved are CPU, RAM, mass
storage (disc), the number and quality of network interfaces.

Throughput (Mbps) Hardware requirements Feature set Users / Networks

1-10 Basic spec. narrowed few (1-10)

11-150 Minimum spec. reduced adjusted (10-30)

151-350 Reasonable spec. all substantial (30-50)

350-750+ Recommended spec. all substantial+ (50-150+)

21
Mbps (Mbit/s or Mb/s) - Megabit per second - 1,000,000 bits per second

Network interface cards


As the FreeBSD hardware-lists and -recommendations say, Intel® network interface
cards (NIC) for LAN [https://en.wikipedia.org/wiki/Local_area_network] connections are
reliable, fast and not error-prone. Intel chipset NICs deliver higher throughput at a
reduced CPU load [https://en.wikipedia.org/wiki/Load_(computing)].

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.

For further help and support, see

FreeBSD 11.1-RELEASE Hardware Compatibility List


[https://www.freebsd.org/releases/11.1R/hardware.html]

OPNsense Forum [https://forum.opnsense.org/]

List of references

Schellevis, Jos; Hardware requirements; OPNsense > Get started


[https://opnsense.org/users/get-started/] (2015)

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

Uses NanoBSD Uses FreeBSD

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.

To enable for non embedded versions: Enable


System⇒Settings⇒Miscellaneous⇒RAM Disk Settings; afterwards reboot. Consider
to enable an external syslog server as well.

Media Filename Composition

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]

OpenSSL & LibreSSL


OPNsense images are provided based upon OpenSSL [https://www.openssl.org]. The
LibreSSL [http://www.libressl.org] flavor can be selected from within the GUI (
System⇒Firmware⇒Settings ). In order to apply your choice an update must be
performed after save, which can include a reboot of the system.

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

dd if=OPNsense-##.#.##-[Type]-[Architecture].img of=/dev/daX bs=16k

Where X = the device number of your USB flash drive (check dmesg )

Linux

dd if=OPNsense-##.#.##-[Type]-[Architecture].img of=/dev/sdX bs=16k

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

dd if=OPNsense-##.#.##-[Type]-[Architecture].img of=/dev/rsd6c bs=16k

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

sudo dd if=OPNsense-##.#.##-[Type]-[Architecture].img of=/dev/rdiskX bs=64k

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

(use v0.3 or later!)

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.

By default you have to log in to enter the console.

Welcome message

* * * Welcome to OPNsense [OPNsense 15.7.25 (amd64/OpenSSL) on OPNsense * * *

WAN (em1) -> v4/DHCP4: 192.168.2.100/24


LAN (em0) -> v4: 192.168.1.1/24

FreeBSD/10.1 (OPNsense.localdomain) (ttyv0)

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”.

VLANs and assigning interfaces


If choose to do manual interface assignment or when no config file can be found then
you are asked to assign Interfaces and VLANs. VLANs are optional. If you do not need
VLAN’s then choose no. You can always configure VLAN’s at a later time.

LAN, WAN and optional interfaces

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.

Minimum installation actions


In case of a minimum install setup (i.e. on CF cards), OPNsense can be run with all
standard features, expect for the ones that require disk writes, e.g. a caching proxy like
Squid. Do not create a swap slice, but a RAM Disk instead. In the GUI enable
System⇒Settings⇒Miscellaneous⇒RAM Disk Settings and set the size to 100-128
MB or more, depending on your available RAM. Afterwards reboot.

Enable RAM disk manually

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.

0) Logout 7) Ping host


1) Assign interfaces 8) Shell
2) Set interface(s) IP address 9) pfTop
3) Reset the root password 10) Filter logs
4) Reset to factory defaults 11) Restart web interface
5) Reboot system 12) Upgrade from console
6) Halt system 13) Restore a configuration

Table: The console menu

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.

For help type opnsense-update -help and [Enter]

Upgrade from console

The other method to upgrade the system is via console option 12) Upgrade from
console

GUI

An update can be done through the GUI via System⇒Firmware⇒Updates.

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:

Minimum required RAM is 1 GB

Minimum recommended virtual disk size of 8GB

Disable all off-loading settings in Interfaces->Settings

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.

opnsense bootstrap is available for our github source repository


[https://github.com/opnsense/update/tree/master/bootstrap]

Amazon AWS EC2 Cloud

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).

See also our how-to for Installing OPNsense AWS image.

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.

File copy failed during installation


This issue is most likely caused by low memory setting. Make sure your virtual
OPNsense installation has a minimum of 1GB of RAM.

Disk Errors on VMware


This issue can be caused by a defective drive. Changing drive mode to IDE has been
reported to help for certain ESXi versions.

Installation failure on KVM


If you are using virtio for the root disk then try switching to sata mode.

39
NAT issues on XenServer
This issue has been reported to be solved by disabling cheksum offloading on both
OPNsense domU and Vifs.

Traffic Shaper does not work on VMware


If you are using vmxnet3 drivers try to switch to E1000.

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.

GUI Layout & Main Components


The GUI consists out of the following main components:

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.

In the Lobby you can:

Look at the dashboard with widgets

View the 2 clause BSD license

Change your password

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

Configuration level (may not exist if the function is simple)

In the following sample you see a screenshot of the Category System, with:

Function: Settings

Selected Configuration item: General

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

General forms of data output graphical and text based

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.

A sample can be seen here:

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.

External service currently supported are:

LDAP (OpenLDAP, MS Active Directory, Novell eDirectory)

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.

Users, Groups & Privileges


When using the local user manager, either stand alone or on combination with an
external authentication server one can define groups to combine a set of privileges for a
specific user group. A user should be an individual, a group needs to be specific in such
a way that anyone of that group can be granted the same access rights, called

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.

Below an overview of the settings, which are available:

Session Timeout Session timeout if other then our default.

Authentication Server Primary authentication method to use.

Authentication Server Fallback option if primary service fails.


(fallback)

Policy Enable password policy constraints.

Duration [Policy] Password duration, optionally define how often the user
should change his or her password.

Length [Policy] Minimum password length to require.

Complexity [Policy] Enforce password complexity checks.

Configuration

Local User Manager

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:

Native IPv6 only

Dual Stack IPv4 + IPv6

IPv6 <-> IP4v Tunnel broker

Warning

NAT64, IPv4 <-> IPv6 Network address translations, is currently not supported by
FreeBSD.

Configuring

53
IPv6 For Zen UK

Configure IPv6 Tunnel Broker

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.

Supported services are:

OPNsense Graphical User Interface

Captive Portal

Virtual Private Networking - OpenVPN & IPsec

Caching Proxy

GUI Fallback Configuration


To prevent GUI lockout due to unavailable remote authentication server, the system has
a default fallback to the local database. In case of 2FA for the GUI one needs to disable
the fallback option to make sure no local user can gain access without 2FA.

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.

Other TOTP tokens


The 2FA feature can be used with any time based one-time password token, although it
may be necessary to convert the tokens seed to the used format (base32).

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.

GUI Features Overview


Please see the screenshot below for all element of the system health module. Each
element will be explained in the next chapters.

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.

Select primary dataset


Select the RRD dataset you want to use. The more to the left the lower the maximum
resolution. By default the graphs are opened with the highest available RRD resolution.

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.

Hide/show table data


By default the table data is hidden, you can show it by toggling the Show Tables to On.

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.

Current Detail Level


Since the data is dynamically rendered it will automatically calculate the averages and
show you the current detail level in this area.

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:

And the result:

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:

Captures 5 detail levels

Last 2 hours, 30 second average

Last 8 hours, 5 minute averagae

Last week, 1 hour average

76
Last month, 24 hour average

Last year, 24 hour average

Graphical representation of flows (stacked, stream and expanded)

Top usage per interface, both ips and ports.

Full in/out traffic in packets and bytes

Detailed view with date selection and port/ip filter (up to 2 months)

Data export to csv for offline analysis

Selectable Detail Level

Selectable Resolution

Selectable Dat range

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 Single hosts by IP or Fully Qualified Domain Name

Networks Entire network p.e. 192.168.1.1/24

Ports Port numbers or a port range like 20:30

URL Tables A table of ip addresses that can be fetched

GeoIP Select countries or whole regions

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]

EDROP list [https://www.spamhaus.org/drop/edrop.txt]

Using Aliases in pf Firewall Rules


Aliases can be used in the firewall rules to make administration of large lists easy. For
instance we could have a list of remote ip’s that should have access to certain services,
when anything changes we only need to update the list.

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:

critical_servers {10.0.1.1 , 10.0.1.2}

other_servers {10.0.1.100 , 10.0.1.200}

Then concatenate both by defining a new list:

servers { critical_servers , other_servers}.

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

Configure DROP and EDROP lists


To setup the DROP and EDROP lists in combination with the firewall rules, read:
Configure Spamhaus (E)DROP

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.

Supported VPN technologies


OPNsense offers a wide range of VPN technologies ranging from modern SSL VPN’s to
well known IPsec as well as older (now considered insecure) legacy options such as
L2TP and PPTP.

90
Note

VPN technologies displayed with an open lock are considered to be insecure.

Integrated VPN options


Integrated solutions are those that are available within the GUI without installing any
additional package or plugin. These include:

IPsec

OpenVPN (SSL VPN)

Plugin VPN options


Via plugins additional VPN technologies are offered, including:

Legacy L2TP & PPTP

Tinc - Automatic Full Mesh Routing

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 Road Warrior


Setup IPsec Road-Warrior

IPsec Site-to-Site
Setup IPsec site to site tunnel

IPsec Site-to-Site with BINAT


IPSec BINAT

OpenVPN/SSL Road Warrior


Setup SSL VPN Road Warrior

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.

Emerging Threats ETOpen Ruleset


The ETOpen Ruleset is an excellent anti-malware IDS/IPS ruleset that enables users
with cost constraints to significantly enhance their existing network-based malware
detection. The ETOpen Ruleset is not a full coverage ruleset, and may not be sufficient
for many regulated environments and should not be used as a standalone ruleset.

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.

See fore details: https://sslbl.abuse.ch/

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 A Hosted on compromised webservers running an nginx proxy on port 8080


TCP forwarding all botnet traffic to a tier 2 proxy node. Botnet traffic usually directly hits
these hosts on port 8080 TCP without using a domain name.

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.

Version D Successor of Cridex. This version is also known as Dridex

See for details: https://feodotracker.abuse.ch/

Maxmind GeoLite2 Country


GeoLite2 databases are free IP geolocation databases comparable to, but less accurate
than, MaxMind’s GeoIP2 databases. GeoLite2 databases are updated on the first
Tuesday of each month.

95
For more details see: http://dev.maxmind.com/geoip/geoip2/geolite2/

OPNsense has integrated GeoLite2 Country database support.

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).

Disable all Hardware Offloading Under Interface-Settings

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.

Setup Intrusion Detection & Prevention


To enable IDS/IPS just go to Services->Intrusion Detection and select enabled & IPS
mode. Make sure you have selected the right interface for the intrusion detection system
too run on. For our example we will use the WAN interface, as that will most likely be
you connection with the public Internet.

98
Apply configuration
First apply the configuration by pressing the Apply button at the bottom of the form.

Fetch Rule sets


For this example we will only fetch the abuse.ch SSL & Dodo Tracker rulesets. To do so:
select Enabled after each one.

To download the rule sets press Download & Update Rules.

99
Change default behavior
Now click on the info button right after each rule and change Input Filter from none to
drop actions.

When done it should like this:

Apply fraud 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.

Click on schedule, a popup window will appear:

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).

Disable all Hardware Offloading Under Interface-Settings

Warning

104
After applying you need to reboot OPNsense otherwise offloading may not completely
be disabled and IPS mode will not function.

To start go to Services->Intrusion Detection

User defined
Select the tab User defined.

Create a new Rule


Select to add a new rule.

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.

Select the Action (Alert or Drop):

Add a description:

106
And click Save changes

Enable Intrusion Detection & Prevention


To enable IDS/IPS just go to Services->Intrusion Detection and select enabled & IPS
mode. Make sure you have selected the right interface for the intrusion detection system
too run on. For our example we will use the WAN interface, as that will most likely be
you connection with the public Internet.

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).

Disable all Hardware Offloading Under Interface-Settings

Warning

After applying you need to reboot OPNsense otherwise offloading may not completely

109
be disabled and IPS mode will not function.

To start go to Services->Intrusion Detection

User defined
Select the tab User defined.

Create a new Rule


Select to add a new rule.

Get fingerprint of website


It is relatively easy to find out the SSL fingerprint of a website. For demonstration we will
block facebook and use Firefox to determine the fingerprint.

Open your browser and go to https://facebook.com when loaded click on the lock next to
the address : .

Now you will see something similar to:

Click on the arrow ( > ) and then Select More Information Now open the certificate

110
details and you will see something that looks like this:

Copy the SHA1 certificate fingerprint


(A0:4E:AF:B3:48:C2:6B:15:A8:C1:AA:87:A3:33:CA:A3:CD:EE:C9:C9).

Paste this into the new rule:

111
Select the Action (Alert or Drop):

Add a description:

112
And click Save changes

Enable Intrusion Detection & Prevention


To enable IDS/IPS just go to Services->Intrusion Detection and select enabled & IPS
mode. Make sure you have selected the right interface for the intrusion detection system
too run on. For our example we will use the WAN interface, as that will most likely be
you connection with the public Internet.

Apply configuration
First apply the configuration by pressing the Apply button at the bottom of the form.

Clear Browser Cache and test


Since your browser has cached the ssl certificate you will need to clear your cache first.
After that you can test and will see the following in Alerts:

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

OPNsense is equipped with a fully featured forward caching (transparent) proxy. A


caching proxy reduces bandwidth and improves response times by caching and reusing
frequently-requested web pages. The Access Control Lists can be utilized for user
authentication and or as (category based) web filter.

Features include:

Multi Interface Support

Transparent Mode (including SSL/HTTPS)

ICAP Support for Anti Virus/Malware Engine

HTTP Proxy

FTP Proxy

User Authentication

Access Control Lists (valid for both http(s) and ftp)

(Compressed) Blacklist

115
Category Based Web Filtering

Can be combined with traffic shaper

Authenticators
User authentication can be done using OPNsense standard and build-in authenticators.
Currently these include:

LDAP (incl. Microsoft Active Directory)

Radius

Local user manager

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:

Maximum download size

Maximum upload size

Overall bandwidth throttling

Per host bandwidth throttling

Category Based Web Filter


No need for additional plugins, such as squidGuard - as OPNsense has build-in
category based web filter support. Main features include:

Fetch from a remote URL

Supports flat file list and category based compressed lists

Automatically convert category based blacklists to squid ACL’s

Keep up to date with the build-in scheduler

Compatible with most popular blacklist

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:

Proxy Basic Setup


Setup Caching Proxy

Setup Web Filtering


Setup Web Filtering

Setup Transparent Mode (including SSL)

118
Setup Transparent Proxy

Setup ICAP Anti Virus/Malware Engine


Setup Anti Virus Protection

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.

Setup ICAP Anti Virus Engine


Setup Anti Virus Protection

Setup Anti Virus Protection using OPNsense Plugins

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.

Dummynet & ipfw


Dummynet operates by first using the firewall to classify packets and divide them into
flows, using any match pattern that can be used in ipfw rules. Depending on local
policies, a flow can contain packets for a single TCP connection, or from/to a given host,
or entire subnet, or a protocol type, etc.

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.

WAN Load Balancing


Load balancing can be used to split the load between two (or more) ISP’s. This
enhances the total available bandwidth and/or lowers the load on each ISP.

The principle is simple: Each WAN connection (gateway) gets a portion of the traffic. The
traffic can be divided equally or weighted.

Combining Balancing & Failover


It is also possible to combine Load Balancing with Failover in such scenario’s you will
have 2 or more WAN connections for Balancing purposes and 1 or more for Failover.
OPNsense offers 5 tiers (Failover groups) each tier can hold multiple ISP’s/WAN
gateways.

Configuration

125
For a how to configure read: Setup Multi WAN

126
Mobile Networking

OPNsense supports 3G and 4G (LTE) cellular modems as failsafe or primary WAN


interface. Both USB and (mini)PCIe cards are supported.

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.

Tested devices by the OPNsense team include:

127
Huawei ME909u-521 (device cuaUx.0)

Huawei E220 (device cuaUx.0)

Sierra Wireless MC7304 (device cuaUx.2) [as of OPNsense 16.7]

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.

Configure Cellular modems


Setting up and configuring a cellular modem is easy, see: Configuring Cellular Modems

3G - 4G Cellular Failover
To setup Cellular Failover, just follow these two how-tos:

Configuring Cellular Modems

Setup Multi WAN

Note

Treat the cellular connection the same as a normal WAN connection.

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

Hotel & Camping Wifi Access

Bring Your Own Device (BOYD)

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

Option for your own Pop-up

Custom Splash page

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:

LDAP [Microsoft Active Directory]

Radius

Local user manager

132
Vouchers / Tickets

No authentication (Splash Screen Only)

Multiple (a combination of above)

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.

Timeouts & Welcome Back


Connection can be terminated after the user has been idle for a certain amount of time
(idle timeout) and/or force a disconnect when a number of minutes have passed even if
the user is still active (hard timeout). In case a user reconnect within the idle timeout
and/or hard timeout no login is required and the user can resume its active session.

Bandwidth Management
The Build-in traffic shaper can be utilized to:

Share bandwidth evenly

Give priority to protocols port numbers and/or ip addresses

See also: Traffic Shaping

133
Portal bypass
MAC and IP addresses can be white listed to bypass the portal.

Real Time Reporting


Basic Real Time Reporting is Integrated

Live top IP bandwidth usage (Traffic Graph)

Active Sessions

Time left on Vouchers

Category based Web Filtering


By combining the Captive Portal with the caching proxy it is possible to utilize category
web filtering and block certain content for the users and by enabling the cache reduce
bandwidth and improve response times. See also: Caching Proxy

Platform Integration
Through the integrated REST API the captive portal application can be integrated with
other services. See: Use the API

Configure the Portal


To setup a hotspot controller for business or hotel usage see: Setup a Guest Network

134
135
Dynamic Routing
Warning

Disabling a running routing daemon can be dangerous as it can lead to an inaccessible


machine. If you want to disable a running routing daemon, make sure, you don’t lose
routes which are required by your connection to this machine (for example when using
SSH)

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.

Routing protocols are used to

improve fault tolerance (if a connection breaks, a new route will be found if possible)

simplify administration (You have to add less routes manually)

You should not use routing protocols if

your network is small (so it would be better to use static routes)

you are working in a highly isolated environment, where you have to be in control of
everything happening in your network

Routing Protocols supported by the plugin include:

OSPFv2 and v3

RIPv1 and RIPv2

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

Dynamic Routing: Configuration: OSPFv2

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:

# opnsense-update -kr 18.1

# /usr/local/etc/rc.reboot

Where -k only touches the kernel and -r takes the version number.

To switch back to the current kernel just use

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

# opnsense-revert -r 18.1.4 strongswan

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:

# opnsense-revert -r 18.1.4 opnsense

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

# opnsense-patch -c plugins 699f1f2

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.

Free online storage


Because Google officially offers a free storage of 15 GB and nearly unlimited traffic, a
remote backup of an OPNsense configuration file is free of charge, the only thing you
need is an account at Google (Google Drive Signup
[https://accounts.google.com/signup?hl=en]) .

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.

Setup Google API usage


First we need to have a project in the google developer console:

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.

Enable the Drive API

In the left menu APIs -> “Drive API” -> Enable

Open the project and start to create an api key

In the left menu : APIs & auth -> Credentials

Click on the button “Create new Client ID”

146
Choose “Service account”, followed by “Create Client ID”

Download the key and save it (for your own use)

Click “Generate new P12 key” and download the key (for your own use, you need this
one later)

Copy Email Address, you need it later.

Create a Google Drive folder

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).

right click the newly created folder and choose share

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)

Setup the account in OPNsense

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.

Setup Nextcloud API usage


1. Step Create a new user

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.

2. Step Create an Access Token


Close the modal dialog and remove the default files. Then open the Settings menu (also
in the menu top right). Switch to security and generate a App password.

Copy and store the generated password.

3. Step Connect OPNsense with Nextcloud

149
Scroll to the Nextcloud Section in System -> Config -> Backup and enter the following
values:

Enable checked

URL Base URL of your Nextcloud installation like https://cloud.example.com

User your choosen username

Password paste your app password from step 2

Backup a name consisting of alphanumeric characters (keep default)


Directory

4. Step Verify the Configuration Upload


When everything worked, you will see the newly created directory after saving the
settings:

150
If you open it, you will see at lease a single backed up configuration file:

References

Official website of Google Drive [https://www.google.com/drive/]

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.

Adding a category to a rule


To add a category to a rule, open or create a new rule and scroll to Category. Then just
add you category, if this is the first rule with a category no selection options will be
visible.

Firewall Rules Filter by category


Only when there are rules with a defined category, the Filter by category becomes
visible at the bottom of the table.

If you click it is will look like this:

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.

For more information on Filtering Bridged on FreeBSD, see filtering-bridges


[https://www.freebsd.org/doc/en/articles/filtering-bridges/article.html]

Requirements
For this howto we need a basic installation of OPNsense with factory defaults as a
starting point.

And an appliance with 2 physical interfaces.

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.

Configuration in 10 easy steps


1. Disable Outbound NAT rule generation

2. Change system tuneables

3. Create the bridge

4. Assign a management IP/Interface

5. Disable Block private networks & bogon

6. Disable the DHCP server on LAN

7. Add Allow rules

8. Disable Default Anti Lockout Rule

9. Set LAN and WAN interface type to ‘none’

10. Now apply the changes

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.

1. Disable Outbound NAT rule generation


To disable outbound NAT, go to Firewall -> NAT -> Outbound: Disable Outbound NAT
rule generation

2. Change system tuneables


Enable filtering bridge by changing net.link.bridge.pfil_bridge from default to 1 in
System -> Settings -> System Tuneables

159
And disable filtering on member interfaces by changing net.link.bridge.pfil_member
from default to 0 in System -> Settings -> System Tuneables

3. Create the bridge

160
Create a bridge of LAN and WAN, go to Interfaces -> Other Types -> Bridge :Add
Select LAN and WAN.

4. Assign a management IP/Interface


To be able to configure and manage the filtering bridge (OPNsense) afterwards, we will
need to assign a new interface to the bridge and setup an IP address.

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.

6. Disable the DHCP server on LAN


To disable the DCP server on LAN goto Services -> DHCP Server -> LAN and unselect
enable.

7. Add Allow rules


After configuring the bridge the rules on member interfaces (WAN/LAN) will be ignored.
So you can skip this step.

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.

8. Disable Default Anti Lockout Rule


After configuring the bridge the rules on member interfaces (WAN/LAN) will be ignored.
So you can skip this step.

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

9. Set LAN and WAN interface type to ‘none’


Now remove the IP subnets in use for LAN and WAN by changing the interface type to
none. Goto Interfaces -> LAN & Interfaces -> WAN to do so.

10. Now apply the changes


If you followed each step, then you can now apply the changes. The Firewall is now
converted to a filtering bridge.

Done.. ready to set your own filtering rules

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.

Change Proxy Interfaces


If you want to change the interfaces (subnets) the proxy will bind to then click on the tab
Forward Proxy. Now add/remove the interfaces in the Proxy interfaces field. When
adding make sure it is applied and a tag is visible (use , Enter or select from the list).

Change Proxy Listening Port


By default the proxy will listen at port 3128, you can change this by clicking on the tab
Forward Proxy and fill in the port in the Proxy port feild. Don’t forget to Apply your

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.

Check the Enable local cache and click Apply.

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.

Change Authentication Method


Click on the arrow next to the Forward Proxy tab to show the drop down menu. Now
select Authentication Settings and select the desired Authenticator(s) in the field
Authentication method. Click on Clear All if you do not want to use any authentication.

166
Depending on the Authentication Servers you have setup under System->Access-
>Servers You can select one or more of the following:

No Authentication (leave field blank)

Local User Database

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.

Access Control List


You can setup ACL’s by clicking on the arrow next to Forward Proxy and select Access
Control List. Here you can:

Setup Allowed Subnets (By default the proxy interfaces will be allowed)

Add Unrestricted IP addresses (Unrestricted means just that, no authentication and no


blacklisting for those IP’s)

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:

Remote Black List / Ad Blocking


Use simple flat files to block ads. For this sample we will use the ad list found here:

http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml

This list is a simple flat list that looks like this:

101com.com
101order.com
123found.com
180hits.de
180searchassistant.com
1x1rank.com
207.net
247media.com

Go to Services->Proxy Server->Administration and click on the tab Remote Access

168
Control Lists

Now click on the + at the bottom right corner of the form to add a new list.

Fill in:

Enabled Checked Enable/Disable

Filename yoyoads Choose a unique filename

URL (copy/paste the URL) The URL of the blacklist

categories (Leave blank) Used for Category based web filtering

Description Yoyo Ads Blacklist Your description

Looks like (screenshots of version 16.1.4):

169
Save changes

Now click on Download ACLSs & Apply to enable the blacklist/ad blocker.

Firewall Rule No Proxy Bypass


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

170
Protocol TCP/UDP

Source LAN net

Destination Port Range HTTP

Category Block Proxy


Bypass

Description Block http bypass

Save

And one more rule to block HTTPS access:

Action Block

Interface LAN

Protocol TCP/UDP

Source LAN net

Destination Port Range HTTPS

Category Block Proxy


Bypass

Description Block https bypass

Save & Apply changes

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.

Step 1 - Basic Proxy Setup


To setup the transparent mode(s) a functional basic proxy setup is required. For basic
configuration please refer to Setup Caching Proxy.

Step 2 - Transparent HTTP


Go to Services->Proxy->Administration

Then select General Forward Settings under the Forward Proxy Tab.

174
Select Enable Transparent HTTP proxy And Click Apply.

Step 3 - NAT/Firewall Rule


A simple way to add the NAT/Firewall Rule is to click on the (i) icon on the left of the
Enable Transparent HTTP proxy option and click on add a new firewall rule.

For reference, these are the default settings:

Interface LAN

Protocol TCP

Source LAN net

Source port range any - any

Destination any

Destination port range HTTP - HTTP

Redirect target IP 127.0.0.1

Redirect target port other/3128

Description redirect traffic to proxy

175
NAT reflection Enable

Filter rule association Add associated filter rule

The defaults should be alright, just press Save and Apply Changes.

Step 4 - CA for Transparent SSL


Before we can setup transparent SSL/HTTPS proxy we need to create a Certificate
Authority. Go to System->Trust->Authorities or use the search box to get there fast.

Click on add or import ca in the upper right corner of the screen to create a new CA.

For our example we use the following data:

Descriptive name OPNsense-SSL

Method Create an internal Certificate


Authority

Key length (bits) 2048

Digest Algorithm SHA256

Lifetime (days) 356

Country Code NL (Netherlands)

176
State or Province Zuid Holland

City Middelharnis

Organization OPNsense

Email Address spam@opnsense.org

Common Name opnsense-ssl-ca

Save

Step 5 - Transparent SSL


Go to Services->Proxy->Administration Then select General Forward Settings
under the Forward Proxy Tab.

Select Enable SSL mode and set CA to use to the CA you have just created. Then
Click Apply.

Step 6 - Configure No SSL Bump


This step is very important and requires careful consideration! To make sure that known
sites are not bumped and keep their original security layer intact, one needs to add
those including all subdomain to the SSL no bump sites field.

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!

Step 7 - SSL NAT/Firewall Rule


A simple way to add the NAT/Firewall Rule is to click on the (i) icon on the left of the
Enable SSL mode option and click on add a new firewall rule.

For reference, these are the default settings:

Interface LAN

Protocol TCP

Source LAN net

Source port range any - any

Destination any

Destination port range HTTPS - HTTPS

Redirect target IP 127.0.0.1

Redirect target port other/3129

178
Description redirect traffic to proxy

NAT reflection Enable

Filter rule association Add associated filter rule

The defaults should be alright, just press Save and Apply Changes.

Step 8 - Configure OS/Browser


Since the CA is not trusted by your browser, you will get a message about this for each
page you visit. To solve this you can import the Key into your OS and set as trusted. To
export the Key go to System->Trust->Authorities and click on the icon to export the CA
certificate. Of course one may choose to accept the certificate for each page manually,
but for some pages that may not work well unless not bumped.

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

For this tutorial we will assume:

Proxy has his default settings / is not configured

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.

Step 2 - Configure Blacklist


Click on the tab Remote Access Control Lists. Now click on the + in the lower right
corner of the from to add a new list.

A screen will popup, enter the following details:

Enabled Checked Enable/Disable

Filename UT1 Choose a unique filename

URL (copy/paste the The URL of the blacklist


URL)

categories (Leave blank) If left blank the full list will be fetched

Description UT1 web filter Your description

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.

Step 3 - Download the Categories


Now press Download ACL’s, please note that this will take a while (can be several
minutes) as the full list (>19MB) will be converted to squid acl’s.

Step 4 - Setup Categories


Now we can select the categories we want to use by clicking on the pencil icon next to
the description of the list. This will open the edit window again, but now you will see all
available categories extracted from the list.

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.

Step 5 - Enable Proxy


To enable the proxy just go to Services->Proxy Server->Administration and check
Enable proxy en click on Apply. The proxy will bind to LAN and port 3128.

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).

Step 6 - Disable Proxy Bypass

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

Source LAN net

Destination Port Range HTTP

Category Block Proxy


Bypass

Description Block http bypass

Save

And one more rule to block HTTPS access:

Action Block

Interface LAN

Protocol TCP/UDP

Source LAN net

186
Destination Port Range HTTPS

Category Block Proxy


Bypass

Description Block https bypass

Save & Apply changes

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.

Step 3 - Configure the Engine


For this example we have used Symantecs Protection Engine. The installation is straight
forward, please refer to Symantecs documentation for full installation and configuration
instructions.

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:

Request Modify URL icap://192.168.2.1:1344/avscanreq

Response Modify URL icap://191.168.2.1:1344/avscan

Now click on Apply

Step 6 - 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

IMPORTANT NOTE : YOU DOWNLOAD THESE FILES AT YOUR OWN RISK!

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.

When using CARP ( FreeBSD handbook on CARP


[https://www.freebsd.org/doc/handbook/carp.html] ), all fail-safe interfaces should have a
dedicated ip address which will be combined with one shared virtual ip address to
communicate to both networks. In the picture above the dashed lines are used to mark
the virtual addresses.

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.

Setup interfaces & basic firewall rules


Our example uses three interfaces, which all have a rather basic setup.

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.

Setup Virtual IPs

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

Virtual password opnsense (the example uses


this)

VHID Group 1

Advertising Frequency Base 1 / Skew 0

Description VIP WAN

And another using the following:

Type Carp

Interface LAN

IP addresses 192.168.1.1 / 24

Virtual password opnsense (the example uses


this)

VHID Group 3

197
Advertising Frequency Base 1 / Skew 0

Description VIP LAN

Setup outbound NAT


When traffic is going out of the firewall it should also use the virtual IP address to make a
seamless migration possible. The default for OPNsense is to use the interfaces IP
address, which is in our case the wrong one.

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).

(optional) Setup DHCP server


When using dhcp for the local area network, there are some things to consider. All
clients should use the virtual address in stead of the physical address it’s normally
propagating. Next thing to consider is there will be two servers active at the same time,
which should know of each others pools. If dns requests are also forwarded by
OPNsense, make sure the dhcp server sends the right ip address. These are settings
used in our example (on the master server):

DNS servers 192.168.1.1

Gateway 192.168.1.1

Failover peer IP 192.168.1.20

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

Synchronize Virtual IPs

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 )

Configuration for backup server ( Carp_example_backup.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

LAN DHCP Range 192.168.1.100-


192.168.1.200

IPsec Clients 10.10.0.0/24

Firewall Rules Mobile Users


To allow IPsec Tunnel Connections, the following should be allowed on WAN.

Protocol ESP

UDP Traffic on Port 500 (ISAKMP)

UDP Traffic on Port 4500 (NAT-T)

202
To allow traffic passing to your LAN subnet you need to add a rule to the IPsec interface.

Step 1 - Mobile Clients


First we will need to setup the mobile clients network and authentication methods. Go to
VPN->IPsec->Mobile Clients

For our example will use the following settings:

IKE Extensions
Enable checked check to enable mobile clients

User Authentication Local For the example we use the Local Database
Database

Group Authentication none Leave on none

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.

Step 2 - Phase 1 Mobile Clients


Phase 1 General information
Connection method default default is ‘Start on traffic’

Key Exchange version V1 only V1 is supported for mobile clients

Internet Protocol IPv4

Interface WAN choose the interface connected to the internet

Description MobileIPsec freely chosen description

Phase 1 proposal (Authentication)


Authentication method Mutual PSK +Xauth Using a Pre-shared Key and
Login

Negotiation mode Agressive Select Aggressive

My identifier My IP address Simple identification for fixed ip

Peer identifier User distinguished Identification for peer

Peer identifier vpnuser@example.com Our freely chosen identifier

204
Pre-Shared Key At4aDMOAOub2NwT6gMHA Random key. CREATE YOUR
OWN!

Phase 1 proposal (Algorithms)


Encryption algorithm AES For our sample we will Use AES/256 bits

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

Lifetime 28800 sec lifetime before renegotiation

Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expire

Disable Reauth Unchecked For IKEv2 only re-authenticate peer on rekeying

NAT Traversal Enabled Enable for IKEv1

Dead Peer Detection Unchecked

Save your setting by pressing:

Now you should see the following screen:

205
Step 3 - Phase 2 Mobile Clients
Press the button that says ‘+ Show 0 Phase-2 entries’

You will see an empty list:

Now press the + at the right of this list to add a Phase 2 entry.

General information
Mode Tunnel IPv4 Select Tunnel mode

Description MobileIPsecP2 Freely chosen


description

Local Network
Local Network LAN subnet Route the local LAN subnet

Phase 2 proposal (SA/Key Exchange)

206
Protocol ESP Choose ESP for encryption

Encryption algorithms AES / 256 For the sample we use AES 256

Hash algorithms SHA1 You may also try stronger SHA512

PFS Key group off Enable a group fro stronger security

Lifetime 3600 sec

Save your setting by pressing:

Enable IPsec, Select:

Save:

And Apply changes:

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.

Enter the following into the form:

User Name expert

Password &test!9T

Save this user and reopen in edit mode to add privileges.

Add privilege User - VPN - IPsec xauth Dialin by pressing the + under Effective
Privileges.

Save to apply.

Step 5 - Configure Client


To illustrate the client setup we will look at the configuration under OSX, including some
screenshots. The configurations for Android and iOS will be settings only.

208
Note

Configuration samples listed here where created using latest OSX, iOS and Android
devices on time of publication in February 2016.

Configure OSX Client


Start with opening your network settings (System Preferences -> Network) and Add a
new network by pressing the + in the lower left corner.

Now select VPN and Cisco IPSec, give your connection a name and press Create.

Now enter the details for our connection:

209
Next press Authentication Settings to add the group name and pre-shared key.

Press OK to save these settings and then Apply to apply them.

Now test the connection by selecting it from the list and hit Connect.

210
Done

Configure iOS Client


To add a VPN connection on an iOS device go to Setting->General->VPN. Select Add
VPN Configuration chose IPsec and use the Following Settings:

Description IPsec OPNsense Freely chosen description

Server 172.18.0.164 Our server address

Account expert Username of the remote account

Password &test!9T Leave blank to be prompted every


time

IPsec-id vpnuser@example.com The peer identity we chose

Preshared IPsec-key At4aDMOAOub2NwT6gMHA Our PSK

Configure Android Client


To add a VPN connection on an Android device go to Settings -> Connections -> more
networks , select VPN. Press the + in the top right corner to add a new vpn connection.

Use the Following Settings:

211
Name IPsec OPNsense Freely chosen name

Type IPSec Xauth PSK As configured in OPNsense

Server address 172.18.0.164 Our server address

IPsec-id vpnuser@example.com The peer identity we chose

Preshared IPsec-key At4aDMOAOub2NwT6gMHA Our PSK

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.

Before you start


Before starting with the configuration of an IPsec tunnel you need to have a working
OPNsense installation wit a unique LAN IP subnet for each side of your connection (you
local network need to different than that of the remote network).

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

LAN DHCP Range 192.168.1.100-


192.168.1.200

Network Site B

Site B
Hostname fw2

WAN IP 172.10.2.1/24

LAN Net 192.168.2.0/24

LAN DHCP Range 192.168.2.100-


192.168.2.200

214
Full Network Diagram Including IPsec Tunnel
IPsec Site-to-Site tunnel network

Firewall Rules Site A & Site B


To allow IPsec Tunnel Connections, the following should be allowed on WAN for on
sites:

Protocol ESP

UDP Traffic on Port 500 (ISAKMP)

UDP Traffic on Port 4500 (NAT-T)

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.

Step 1 - Phase 1 Site A


(Under VPN->IPsec->Tunnel Settings Press +) We will use the following settings:

General information
Connection method default default is ‘Start on traffic’

Key Exchange version V2 both V1 and V2 are supported

Internet Protocol IPv4

Interface WAN choose the interface connected to the internet

Remote gateway 172.10.2.1 the public ip address of your remote


OPNsense

Description Site B freely chosen description

Phase 1 proposal (Authentication)


Authentication method Mutual PSK Using a Pre-shared Key

Negotiation mode Main Use Main. Aggressive is insecure

My identifier My IP address Simple identification for fixed ip

216
Peer identifier Peer IP address Simple identification for fixed ip

Pre-Shared Key At4aDMOAOub2NwT6gMHA Random key. CREATE YOUR


OWN!

Phase 1 proposal (Algorithms)


Encryption algorithm AES For our sample we will Use AES/256
bits

Hash algoritm SHA512 Use a strong hash like SHA512

DH key group 2048 bit 2048 bit should be sufficient

Lifetime 28800 sec lifetime before renegotiation

Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expire

Disable Reauth Unchecked For IKEv2 only re-authenticate peer on rekeying

NAT Traversal Disabled For IKEv2 NAT traversal is always enabled

Dead Peer Detection Unchecked

Save your setting by pressing:

217
Now you should see the following screen:

Step 2 - Phase 2 Site A


Press the button that says ‘+ Show 0 Phase-2 entries’

You will see an empty list:

Now press the + at the right of this list to add a Phase 2 entry.

General information
Mode Tunnel IPv4 Select Tunnel mode

Description Local LAN Site B Freely chosen description

218
Local Network
Local Network LAN subnet Route the local LAN subnet

Remote Network
Type Network Route a remote network

Address 192.168.2.1/24 The remote LAN subnet

Phase 2 proposal (SA/Key Exchange)


Protocol ESP Choose ESP for encryption

Encryption algorithms AES / 256 For the sample we use AES 256

Hash algortihms SHA512 Choose a strong hash like SHA512

PFS Key group 2048 bit Not required but enhanced security

Lifetime 3600 sec

Save your setting by pressing:

Enable IPsec for Site A, Select:

219
Save:

And Apply changes:

You are done configuring Site A.

Step 3 - Phase 1 Site B


(Under VPN->IPsec->Tunnel Settings Press +) We will use the following settings:

General information
Connection method default default is ‘Start on traffic’

Key Exchange version V2 both V1 and V2 are supported

Internet Protocol IPv4

Interface WAN choose the interface connected to the internet

220
Remote gateway 172.10.1.1 the public ip address of your remote
OPNsense

Description Site A freely chosen description

Phase 1 proposal (Authentication)


Authentication method Mutual PSK Using a Pre-shared Key

Negotiation mode Main Use Main. Aggressive is insecure

My identifier My IP address Simple identification for fixed ip

Peer identifier Peer IP address Simple identification for fixed ip

Pre-Shared Key At4aDMOAOub2NwT6gMHA Random key. CREATE YOUR


OWN!

Phase 1 proposal (Algorithms)


Encryption algorithm AES For our sample we will Use AES/256
bits

Hash algoritm SHA512 Use a strong hash like SHA512

DH key group 2048 bit 2048 bit should be sufficient

Lifetime 28800 sec lifetime before renegotiation

221
Advanced Options
Disable Rekey Unchecked Renegotiate when connection is about to expired

Disable Reauth Unchecked For IKEv2 only re-authenticate peer on rekeying

NAT Traversal Disable For IKEv2 NAT traversal is always enabled

Dead Peer Detection Unchecked

Save your setting by pressing:

Now you should see the following screen:

Step 4 - Phase 2 Site B


Press the button that says ‘+ Show 0 Phase-2 entries’

You will see an empty list:

222
Now press the + at the right of this list to add a Phase 2 entry.

General information
Mode Tunnel IPv4 Select Tunnel mode

Description Local LAN Site A Freely chosen description

Local Network
Local Network LAN subnet Route the local LAN subnet

Remote Network
Type Network Route a remote network

Address 192.168.1.1/24 The remote LAN subnet

Phase 2 proposal (SA/Key Exchange)


Protocol ESP Choose ESP for encryption

Encryption algorithms AES / 256 For the sample we use AES 256

Hash algortihms SHA512 Choose a strong hash like SHA512

PFS Key group 2048 bit Not required but enhanced security

Lifetime 3600 sec

223
Save your setting by pressing:

Enable IPsec for Site B, Select:

Save:

And Apply changes:

You are done configuring Site B.

IPsec Tunnel Ready


The tunnel should now be up and routing the both networks. Go to VPN->IPsec->Status
Overview to see current status. Press on the (i) to see the details of the phase 2
tunnel(s), like this:

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.

Check your ipsec log to see if that reviels a possible cause.

Common issues are unequal settings. Both ends must use the same PSK and
encryption standard.

Phase 1 works but no phase 2 tunnels are


connected
Did you set the correct local and remote networks. A common mistake is to fill in the ip
address of the remote host in stead of its network ending with x.x.x.0

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.

No issues with NAT without NAT-T

With this how-to we’ll show you how to configure OPNsense’s SSL VPN for road
warriors and give you configuration examples for:

Two Factor Authentication (2FA)

Multi Factor Authentication ( Client Certificate + Password + OTP )

Client configuration on Windows, OSX, iOS and 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

Company Network with Remote Client

229
Company Network
Hostname fw1

WAN IP 172.18.0.129

LAN IP 192.168.1.0/24

LAN DHCP Range 192.168.1.100-


192.168.1.200

SSL VPN Clients 10.10.0.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.

For completeness of this how-to we will also prepare a user.

Configure TOTP server


To configure a Time based One Time Password server go to System->Access-
>Servers and click on Add server in the top right corner of the form.

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.

Click Save to add the new server.

Add Certificate Authority


The VPN server needs a certificate authority to sign client or server certificates.

To setup a new certificate authority go to System->Trust->Authorities and click on add


or import ca in the top right corner of the form.

231
For our example we will use the following setting:

Descriptive name SSL VPN CA

Method Create an internal Certificate Authority

Key length (bits) 4096

Digest Algorithm SHA512

Lifetime (days) 365

Country Code : NL

State or Province : ZH

City : Middelharnis

Organization : OPNsense

Email Address : spam@opnsense.org

Common Name : internal-sslvpn-ca

Click Save to add the new Certificate Authority.

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):

Method Create an internal Certificate

Descriptive name SSLVPN Server Certificate

Certificate authority SSL VPN CA

Type Server Certificate

Key length (bits) 4096

Digest Algorithm SHA512

Lifetime (days) 365

Country Code : NL

State or Province : ZH

City : Middelharnis

Organization : OPNsense

Email Address : spam@opnsense.org

Common Name : SSLVPN Server Certificate

Click Save to create the certificate.

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.

For the first step we enter:

Username Donald

Password (2x) S3cr3tP@ssw0rd

Full name Donald Duck

Certificate True

OTP seed 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):

Method Create an internal Certificate

Descriptive Name Leave default (Donald)

Certificate authority SSL VPN CA

234
Type Client Certificate

Key length 4096

Digest Algorithm SHA512

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

Step 1 - Add SSL Server


Adding a new SSL VPN server is relatively simple. We’ll start by adding one that uses
our two factor authentication. This setup offers a good protection and it is easy to setup
on the clients as each client can use the same configuration.

Go to VPN->OpenVPN->Servers and click on add server in to top right corner of the


form.

For our example will use the following settings:

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.

Server Mode Remote Access (User Auth)

Backend for authentication TOTP VPN Access Server

235
Protocol UDP

Device Mode tun

Interface WAN

Local port 1194

Description My SSL VPN Server

TLS Authentication Leave both on enabled (checked)

Peer Certificate Revocation List N/A

Server Certificate SSLVPN Server Certificate (CA: SSL VPN


CA)

DH Parameters Length 4096

Encryption algorithm AES-256-CBC (256-bit)

Auth Digest Algorithm SHA512 (512-bit)

Hardware Crypto No Hardware Crypto Acceleration

Certificate Depth One (Client+Server)

IPv4 Tunnel Network 10.10.0.0/24

IPv6 Tunnel Network Leave Empty

236
Redirect Gateway Leave Unchecked

IPv4 Local Network/s 192.168.1.0/24

IPv6 Local Network/s Leave Empty

IPv4 Remote Network/s Leave Empty

IPv6 Remote Network/s Leave Empty

Concurrent connections Leave Empty

Compression Enabled with Adaptive Compression

Type-of-Service Leave Unchecked

Duplicate Connections Leave Unchecked

Disable IPv6 Checked

Dynamic IP Leave Unchecked

Address Pool Leave Checked

Topology Leave Unchecked

DNS Default Domain Leave Unchecked

DNS Servers Leave Unchecked

237
Force DNS cache update Leave Unchecked

NTP Servers Leave Unchecked

NetBIOS Options Leave Unchecked

Client Management Port Leave Unchecked

Renegotiate time 0

Note

Renegotiate time is used to renegotiate data channel key after n seconds


(default=3600).When using a one time password, be advised that your connection will
automatically drop because your password is not valid anymore.Set to 0 to disable,
remember to change your client when changed later.

Click Save to add the new server.

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.

Some sample screenshots (Mac OSX):

Import Configuration

Connect & login

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.

Import the hostname-udp-1194-ios-config.ovpn file into OpenVPN for Android. Clicking


on the file should be enough to get it imported. When asked for an application to open
the file with, select OpenVPN for Android.

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.

Import the hostname-udp-1194-andoroid-config.ovpn file into OpenVPN Connect.

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.

Step 4 - Multi Factor Authentication


For two factor authentication you need the factors username/password and a token.
OPNsense supports another layer, namely a user certificate. This means that every user
will be uniquely identified by the user certificate. In this case the multi factors are:

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.

Before you start


Before starting with the configuration of an OpenVPN SSL tunnel you need to have a
working OPNsense installation wit a unique LAN IP subnet for each side of your
connection (you local network need to different than that of the remote network).

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

LAN DHCP Range 192.168.1.100-


192.168.1.200

Tunnel Network 10.10.0.0/24

Network Site B

Site B - Client
Hostname fw2

WAN IP 172.10.2.1/16

LAN Net 192.168.2.0/24

LAN DHCP Range 192.168.2.100-


192.168.2.200

246
Tunnel Network 10.10.0.0/24

Full Network Diagram Including SSL VPN Tunnel


SSL VPN Site-to-Site tunnel network

Step 1 - Add SSL Server


Adding a new SSL VPN server is relatively simple. We’ll start by adding a server that
uses a shared key. This setup offers a good protection and it is easy to setup.

Go to VPN->OpenVPN->Servers and click on add server in to top right corner of the


form.

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.

Server Mode Peer to Peer (Shared Key)

Protocol UDP

247
Device Mode tun

Interface WAN

Local port 1194

Description SSL VPN Server

Shared Key Leave on enabled (checked) to create a new


key

Server Certificate SSLVPN Server Certificate (CA: SSL VPN CA)

DH Parameters Length 4096

Encryption algorithm AES-256-CBC (256-bit)

Auth Digest Algorithm SHA512 (512-bit)

Hardware Crypto No Hardware Crypto Acceleration

IPv4 Tunnel Network 10.10.0.0/24

IPv4 Local Network/s 192.168.1.0/24

IPv4 Remote Network/s 192.168.2.0/24

Compression Enabled with Adaptive Compression

Click Save to add the new server.

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-----

Step 3 - Server 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.

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.

Step 4 - Site B Client


Now we will have to setup the client. Login to the second firewall, go to VPN-
>OpenVPN->Clients and click on add client in the upper right corner of the form.

Now enter the following into the form (and leave everything else default):

Server Mode Peer to Peer (Shared Key)

Protocol UDP

252
Device Mode tun

Interface WAN

Server host or address 172.10.1.1

Server port 1194

Description SSL VPN Client

Shared Key Uncheck to paste the shared key

… Paste your shared key

Server Certificate SSLVPN Server Certificate (CA: SSL VPN


CA)

DH Parameters Length 4096

Encryption algorithm AES-256-CBC (256-bit)

Auth Digest Algorithm SHA512 (512-bit)

Hardware Crypto No Hardware Crypto Acceleration

IPv4 Tunnel Network 10.10.0.0/24

IPv4 Remote Network/s 192.168.1.0/24

Compression Enabled with Adaptive Compression

253
Now click on Save to apply your settings.

The Connection Status can be viewed under VPN->OpenVPN->Connection Status

Step 5 - Client Firewall Rules


To allow traffic from the remote network just add a rule under Firewall->Rules
OpenVPN tab.

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:

apt-get install freeradius

Arrange client access


Edit the file /etc/freeradius/clients.conf and append a block for your network, as sample
we will use 10.211.55.0/24.

client 10.211.55.0/24 {
secret = testing123

256
shortname = test-network
}

Enable daily session limits


Enable daily session limits, which needs accounting to signal the clients use.

In /etc/freeradius/sites-available/default uncomment daily in authorize and accounting


sections.

in /etc/freeradius/radiusd.conf uncomment daily in the instantiate section

append to /etc/freeradius/dictionary

ATTRIBUTE Daily-Session-Time 3000 integer


ATTRIBUTE Max-Daily-Session 3001 integer

uncomment sradutmp in the accounting section, to be able to use the radwho command.

Add test users


You can add your test users to /etc/freeradius/users, they should look like this:

"test" Cleartext-Password := "test", Max-Daily-Session := 1800


Framed-IP-Address = 10.211.55.100,
Reply-Message = "Hello, %{User-Name}"

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.

Share internet bandwidth amongst users evenly

Limit maximum internet bandwidth users can consume

Prioritize Applications (Weighted) using Queues

Multi Interface shaping for a GuestNet

Reserve dedicated bandwidth


In this scenario we will create a pipe dedicated for traffic going to and coming from our
realtime application. For the sample we presume a SIP trunk or hosted Voice Over IP
(VOIP) server.

For this example we presume a requirement of 4 uncompressed voice channels of


64Kbps, resulting in a total bandwidth of 256Kbps. The internet connection in this
example has 10Mbps Download and 1Mbps Upload.

Shaping hosted VOIP / SIP trunk sample

To start go to Firewall->Traffic Shaper->Settings.

Step 1 - Create Upload and Download Pipes

259
On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.

Create Pipe For Upload (To our VOIP Server)

enabled Checked Check to enable the pipe

bandwidth 256 Numeric value of the desired bandwidth

bandwidth Metric Kbit/s Metric to use with the numeric value

mask (Empty) Used for auto queueing, empty for our sample

description PipeUp- Free field, enter something descriptive


256Kbps

Create Pipe For Upload (Other Traffic = 1024Kbps - 256Kbps = 768Kbps)

enabled Checked Check to enable the pipe

bandwidth 768 Numeric value of the desired bandwidth

bandwidth Metric Kbit/s Metric to use with the numeric value

mask (Empty) Used for auto queueing, empty for our sample

description PipeUp- Free field, enter something descriptive


768Kbps

Create Pipe For Download (From our VOIP Server)

260
enabled Checked Check to enable the pipe

bandwidth 256 Numeric value of the desired bandwidth

bandwidth Metric Kbit/s Metric to use with the numeric value

mask (Empty) Used for auto queueing, empty for our sample

description PipeDown- Free field, enter something descriptive


256Kbps

Create Pipe For Download (Other Traffic = 10240Kbps - 256Kbps = 9984Kbps )

enabled Checked Check to enable the pipe

bandwidth 9984 Numeric value of the desired bandwidth

bandwidth Metric Kbit/s Metric to use with the numeric value

mask (Empty) Used for auto queueing, empty for our sample

description PipeDown- Free field, enter something descriptive


9984Kbps

Step 2 - Create Rules


On the Rules tab click the + button in the lower right corner. An empty Edit rule screen
will popup.

Create a rule for traffic directed towards the VOIP Server (Upload).

261
sequence 11 Auto generated number, overwrite only when
needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source ip to shape, leave on any

src-port any The source port to shape, leave on any

destination 172.10.2.1 The ip address of our VOIP server

dst-port any Use any of the destination port if static

target PipeUP-256Kbps Select the Upload 256Kbps Pipe

description ShapeVOIPUpload Enter a descriptive name

Create a rule for traffic coming from the VOIP Server (Download).

sequence 21 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source 172.10.2.1 The ip address of our VOIP server

src-port any The source port to shape, leave on any

262
destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

target PipeDown256Kbps Select the Download 256Kbps Pipe

description ShapeVOIPDown Enter a descriptive name

Create a rule for all other internet upload traffic

sequence 31 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source 192.168.1.0/24 The source ip’s to shape, our LAN network

src-port any The source port to shape, leave on any

destination any the destination address, leave in any

dst-port any Use any of the destination port if static

target PipeUp- Select the Upload 256Kbps Pipe


768Kbps

description ShapeUpload Enter a descriptive name

263
Create a rule for all other internet download traffic

sequence 41 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source ip to shape, leave on any

src-port any The source port to shape, leave on any

destination 192.168.1.0/24 The destination ip’s to shape, our LAN network

dst-port any The destination port to shape, leave on any

target PipeDown- Select the Download 256Kbps Pipe


9984Kbps

description ShapeDown Enter a descriptive name

Note

Be aware of the sequence! It is important to make sure the right traffic is passed to the
right pipe.

Now press to activate the traffic shaping rules.

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.

Shaping hosted VOIP / SIP trunk sample

To start go to Firewall->Traffic Shaper->Settings.

Step 1 - Create Upload and Download Pipes

265
On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.

Create Pipe For Upload

enabled Checked Check to enable the pipe

bandwidth 1 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask empty Select destination to share the bandwidth

description PipeUp- Free field, enter something descriptive


1Mbps

Create Pipe For Download

enabled Checked Check to enable the pipe

bandwidth 10 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask empty Select destination to share the bandwidth

description PipeDown- Free field, enter something descriptive


10Mbps

Step 2 - Create a Queues

266
On the Queues tab click the + button in the lower right corner. An empty Edit queue
screen will popup.

Create Queue for Upload

enabled Checked Check to enable the pipe

pipe PipeUp-1Mbps Select our Pipe

weight 100 Weight to use with the numeric value

mask source Every source creates a match

description QueueUp-1Mbps Free field, enter something descriptive

Create Queue for Download

enabled Checked Check to enable the pipe

pipe PipeDown- Select our Pipe


10Mbps

weight 100 Weight to use with the numeric value

mask destination Every source creates a match

description QueueDown- Free field, enter something descriptive


10Mbps

Step 3 - Create Rules

267
On the Rules tab click the + button in the lower right corner. An empty Edit rule screen
will popup.

Create a rule for traffic directed towards the internet (Upload).

sequence 11 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source 192.168.1.0/24 The source ip to shape, select the LAN network

src-port any The source port to shape, leave on any

destination any The destination to shape, leave on any

dst-port any Use any of the destination port if static

target QueueUp- Select the Upload 1Mbps Queue


1Mbps

description ShapeUpload Enter a descriptive name

Create a rule for traffic coming from the internet (Download).

sequence 21 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

268
proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port any The source port to shape, leave on any

destination 192.168.1.0/24 The destination ip to shape, select LAN network

dst-port any The destination port to shape, leave on any

target QueueDown- Select the Download 10Mbps Queue


10Mbps

description ShapeDownload Enter a descriptive name

Now press to activate the traffic shaping rules.

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.

Simple network diagram

To start go to Firewall->Traffic Shaper->Settings.

Step 1 - Create Upload and Download Pipes


On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.

270
Create Pipe For Download

enabled Checked Check to enable the pipe

bandwidth 1 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask destination Select source to limit bandwidth per client

description PipeDown- Free field, enter something descriptive


1Mbps

Step 2 - Create Rules


On the Rules tab click the + button in the lower right corner. An empty Edit rule screen
will popup.

Create a rule for traffic coming from the internet (Download).

sequence 21 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port any The source port to shape, leave on any

271
destination 192.168.1.0/24 The destination ip to shape, select LAN network

dst-port any The destination port to shape, leave on any

target PipeDown- Select the Download 256Kbps Pipe


1Mbps

description ShapeDownload Enter a descriptive name

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.

Now press to activate the traffic shaping rules.

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

HTTP (80) 1 1Mbps

HTTPS (443)

To start go to Firewall->Traffic Shaper->Settings.

Step 1 - Create Download Pipe


On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen
will popup.

Create Pipe For Download (10Mbps)

enabled Checked Check to enable the pipe

bandwidth 10 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask (empty) Leave empty

description PipeDown- Free field, enter something descriptive


10Mbps

Step 2 - Create Queues


On the Queues tab click the + button in the lower right corner. An empty Edit queue
screen will popup.

274
Create Queue for SMTP

enabled Checked Check to enable the pipe

pipe PipeDown- Select our Pipe


10Mbps

weight 9 Weight to use with the numeric value

mask (empty) Leave empty

description Queue-SMTP Free field, enter something descriptive

Create Queue for HTTP

enabled Checked Check to enable the pipe

pipe PipeDown- Select our Pipe


10Mbps

weight 1 Weight to use with the numeric value

mask (empty) Leave empty

description Queue-HTTP Free field, enter something descriptive

Step 3 - Create Rules


On the Rules tab click the + button in the lower right corner. An empty Edit rule screen
will popup.

275
Create a rule for smtp download traffic (email)

sequence 11 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port smtp The source port to shape, smtp or 25

destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

target Queue-SMTP Select the SMTP queue

description ShapeSMTPDownload Enter a descriptive name

Create a rule for http download traffic

sequence 21 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

276
src-port http The source port to shape, http or 80

destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

target Queue-HTTP Select the HTTP queue

description ShapeHTTPDownload Enter a descriptive name

Adding an extra rule for https traffic is simple as we can use the same http queue if we
like:

sequence 31 Auto generated number, overwrite only


when needed

interface WAN Select the interface connected to the


internet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port https The source port to shape, https or 443

destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

target Queue-HTTP Select the HTTP queue

277
description ShapeHTTPSDownload Enter a descriptive name

This way http and https traffic will be treated the same (total max of 1Mbps).

Now press to activate the traffic shaping rules.

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.

Simple network diagram

Step 1 - Create Upload and Download Pipes


On the Pipes tab click the + button in the lower right corner. An empty Edit Pipe screen

279
will popup.

Create Pipe For Upload (GuestNet - em2)

enabled Checked Check to enable the pipe

bandwidth 1 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask (Empty) Leave empty

description PipeUp- Free field, enter something descriptive


1Mbps

Create Pipe For Download (GuestNet - em2)

enabled Checked Check to enable the pipe

bandwidth 2 Numeric value of the desired bandwidth

bandwidth Metric Mbit/s Metric to use with the numeric value

mask (Empty) Leave empty

description PipeDown- Free field, enter something descriptive


2Mbps

Step 2 - Create Rules


On the Rules tab click the + button in the lower right corner. An empty Edit rule screen

280
will popup.

Important - Before you continue!


First change the mode to advanced, see the toggle in the left top corner of the popup
dialog. One click should shift it from red (disabled) to green (enabled).

Create a rule for the download traffic

sequence 11 Auto generated number, overwrite only when


needed

interface WAN Select the interface connected to the internet

interface2 GuestNet Select the interface that matches your GuestNet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port any The source port to shape, leave on any

destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

direction in Match incoming packages (download)

target PipeDown-2Mbps Select the Download pipe

description GuestNetDownload Enter a descriptive name

281
Create a rule for the upload traffic

sequence 21 Auto generated number, overwrite only when


needed

interface WAN Select the interface that matches your GuestNet

interface2 GuestNet Select the interface connected to the internet

proto ip Select the protocol, ip in our example

source any The source address, leave on any

src-port any The source port to shape, leave on any

destination any The destination ip to shape, leave on any

dst-port any The destination port to shape, leave on any

direction out Match incoming packages (download)

target PipeUp-1Mbps Select the Download pipe

description GuestNetUpload Enter a descriptive name

Now press to activate the traffic shaping rules.

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.

Graphs & Totals


The default view of Insight is the Top users and Graphical Overview. This view allows for
quick examination of current and past flows, showing a graph for in and out going traffic
for each configured intertface.

Select Range & Resolution


In the top right corner a selection can be made for the date range and accuracy
(resolution) of the collected traffic flows.

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.

Port Pie Chart


The port pie chart shows the percentage per port/application. One can change the view
by clicking or double clicking on one of the shown port names/numbers.

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 :

FlowSourceAddrTotals - Totals per source address

FlowInterfaceTotals - Totals per interface

FlowDstPortTotals - Totals per destination port

FlowSourceAddrDetails - Full details per source address

Select the Resolution in seconds (300,3600,86400)

Then select a date range (from/to) and click the export button.

291
292
293
Configure Netflow Exporter

Configuring the Netflow Exporter is a simple task. Go to Reporting->NetFlow.

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).

For local analysis using Insight also enable Capture local.

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.

Step 1 - Add New Authentication Server


To add a TOTP server go to System->Access-Servers and press Add server in the top
right corner. Then fill in the form as follows:

Descriptive name TOTP Server Choose a server name

Type Local+Timebased One Time Select the TOTP server Type


Password

Token length 6 6 for Google Authenticator

Time window Leave Empty for Google


Authenticator

Grace period Leave Empty for Google


Authenticator

Step 2 - Install Google Authenticator


Go to the App Store of your platform and search for Google Authenticator. Install using
the normal procedure for your device.

Step 3 - Add or modify user


For this example we will create a new user, go to System->Access-Users and click on

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.

When done press Save.

Step 4 - Activate Authenticator for this OTP


seed
To activate your new OTP seed on the Google Authenticator, first reopen the user you
just created by clicking on the pencil icon.

Now it will show a QR code:

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.

In case of SailOTP the configuration works like this:

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:

Name Platform URL

FreeOTP Android, iOS https://freeotp.github.io/

Google Authenticator Android, iOS https://www.google.com/landing/2step/

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

The code will change every 30 seconds. Sample code:

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.

Devices used for this How-to


For this how-to we used a Deciso Netboard A10 desktop appliance
[https://www.deciso.com/product-catalog/opn20076b/] and a Huawei ME909u-521
miniPCIe cellular modem provided by OSNet [https://www.osnet.eu/].

Note

Support for the ME909u-521 will be added in OPNsense 16.1.18.

Step 1 - Configure Point to Point device


Go to Interfaces->Point-to-Point->Devices and click on Add in the upper right corner
of the form.

Fill in the form like this (Example is for Dutch Mobile 4G KPN Subscription):

Link Type PPP

Link interface(s) /dev/cuaU0.0 ( HUAWEI Mobile Connect - Modem)

Description 4G Cellular Network

309
Service Provider Select Country, Provider & Plan for auto configuration

Username Leave Empty (for NL KPN)

Password Leave Empty (for NL KPN)

Phone Number *99# (for NL KPN)

Access Point Name (APN) fastinternet (for NL KPN 4G)

If you need to enter a PIN number then click on Advanced Options

Click Save to apply the settings.

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.

No click Save below the form.

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.

Setting up IPv6 using DHCPv6

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’.

It is advisable at this point to reboot the system.

Setting up IPv6 using Static Assignment


Although slightly more complex, this option gives you greater control over LAN DHCP6
server, as this can be tailored to specific needs.

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.

Set up the gateway like this:

319
320
Click Save.

WAN Interface
Once we have our gateway in place we can then set up the WAN interface. Select
Interfaces->WAN.

Go to IPv6 Configuration Type and Select Static IPv6.

Go to Static IPv6 Configuration and set the IPv6 Static address:

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.

Click Save and Apply.

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

2a02:8242:55AB:0:4:3:2:1 would suffice.

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.

Click Save and Apply.

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]

Firstly, enable the server.

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.

Once these details have been entered, click save.

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.

Max keepalive timeout


The time after which the socket will be closed if it stays inactive.

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

Scan for filetypes


The type of files which should be analyzed. You should scan as many file types as
possible but keep in mind that scanning requires resources which have to be available.

Send percentage data


Amount of Data of the original file which should be included in the preview. More Data
will have better scanning results and is better for security while a lower value improves
performance.

Allow 204 response

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.

Enable freshclam service


Freshclam is a service to update your malware signatures. If you use ClamAV, it is
recommended to update the signatures on a regular basis.

Enable TCP Port


This checkbox needs to be checked, if you want to use clamd over the network or for
local services, which use a TCP connection.

Maximum number of threads running


Thread limit is used to avoid a denial of service of the daemon and your machine.
Usually a number next or equal to the number of cores would be good.

Maximum number of queued items


This is the maximum of files which can be in the queued for scanning. The reason is the
same as for the threads.

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.

Max directory recursion


Limit the depth of the directory tree. In the worst case there is a loop which causes the
scanner to run endlessly and this setting should prevent it.

Follow directory symlinks


If this is checked, clamav will follow directory symlinks which may lead to a loop. If you
want to check this, make sure the recursion limit is set to a useful 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 portable executable


Check this box, if you want to scan PE files. If you are using PE-files (*.exe, *.dll etc.)
files in your network, checking this box is recommended.

Scan executeable and linking format


Check this box, if you want to scan ELF-files. ELF is for example used on Linux based
operating systems and on *BSD.

Detect broken executables


This setting will mark an executable as broken if it does not match the spec. A
executable may be broken because of a download issue or manipulation. In any case,
there should not be any legit case to pass a broken executable.

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).

OLE2 block macros


Check this box, if documents containing macros should be blocked. If you don’t use
macros and you don’t expect them from your business partners or friends, this setting is
recommended.

Scan PDF files

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.

Decode mail files


If you select this option, the sections of emails will be read and therefore it will be
possible to scan email attachments. Mail attachments are important to scan as an
attached file may contain malware. For example, some malware campaigns used a
JScript file which has been packed in a ZIP file which was attached to an email.

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.

Block encrypted archive


Encrypted archives are usually used to transfer files encrypted which don’t support
encryption on their own or the sender is not aware how to encrypt those files. A tool like

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.

Core Router of Site A


General Settings:

Setting Value

Enable Checked

Advertise Default Gateway Checked

Passive Interfaces Empty

Route Redistribution Empty

Networks:

Network Network Mask

192.168.0.0 30

192.168.1.0 30

192.168.1.4 30

Left Floor Router of Site A

340
General Settings:

Setting Value

Enable Checked

Advertise Default Gateway Unchecked

Passive Interfaces Interface name of 10.1.1.0

Route Redistribution Empty

Networks:

Network Network Mask

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).

Advertise Default Gateway


Advertise Default Gateway should be checked, if this machine has a default gateway to
the internet. Always Advertise means, that this route should be also broadcasted, if it is
not available. Be careful with this option in HA setups.

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).

Prefix-List in and Out


Only used for advanced route filtering using access lists.

Interfaces
This tab shows an overview of the configured interfaces:

Note

345
Changes in this view do NOT apply the settings.

If you add or edit an entry, you will get this dialog:

Interface
Choose a single interface, where this interface settings apply to.

Authentication Type and Authentication Key

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.

Hello and Dead Interval


Hello interval is the interval in which hello packets (detection of other OSPF routers) are
sent out. A bigger value means sower detection but less load on the interface. Dead
Interval is the time window, in which the router has to receive a hello packet from
another router. If it does not, it is removed.

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.

Send log messages to syslog and Syslog


level
Settings are the same as for the log file but for syslog. This is useful if you use an
external logging server.

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:

DROP list [https://www.spamhaus.org/drop/drop.txt]

EDROP list [https://www.spamhaus.org/drop/edrop.txt]

Step 1 - Create an Alias for Spamhaus


Go to Firewall->Aliases->All and press the Add a new alias button in the top right
corner of the form.

Enter the following data:

Name spamhaus_drop Name of our alias

Description Spamhaus DROP Freely chosen description

Type URL Table (IPs) URL type

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 Add a new alias.

Name spamhaus_edrop Name of our alias

Description Spamhaus EDROP Freely chosen description

Type URL Table (IPs) URL type

Host(s) https://www.spamhaus.org/drop/edrop.txt Extended 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:

Action Block Choose block to drop the incoming traffic

Interface WAN Should be the default value

TCP/IP Version IPv4 For our example we use IPv4

Source spamhaus_drop Our alias for the DROP list

355
Category Spamhaus Freely chosen Category

Description Block DROP Freely chosen description

Save and repeat this action for the EDROP list:

Action Block Choose block to drop the incoming traffic

Interface WAN Should be the default value

TCP/IP Version IPv4 For our example we use IPv4

Source spamhaus_edrop Our alias for the DROP list

Category Spamhaus Freely chosen Category

Description Block EDROP Freely chosen description

356
Save

Step 3 - Firewall Rules Outbound Traffic


Now do the same for outbound traffic traffic on the LAN interface. Go to Firewall->Rules
Select the LAN tab and press the + icon in the lower right corner.

Action Block Choose block to drop the incoming traffic

Interface LAN Should be the default value

TCP/IP Version IPv4 For our example we use IPv4

357
Destination spamhaus_drop Our alias for the DROP list

Category Spamhaus Freely chosen Category

Description Block DROP Freely chosen description

Save and add the EDROP list:

Action Block Choose block to drop the incoming traffic

Interface LAN Should be the default value

TCP/IP Version IPv4 For our example we use IPv4

Destination spamhaus_edrop Our alias for the DROP list

Category Spamhaus Freely chosen Category

Description Block EDROP Freely chosen description

Save and Apply changes

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.

Enable VLAN assignment


If you check this box, the RADIUS packets will have some unencrypted tags for the
network device to allow dynamic VLAN assignment. In this case, the authentication is
still encrypted but some metadata will be readable. You need to enable this checkbox, if
you want to set a VLAN on a switchport, which depends on the authenticated user.

Users

363
A user is an entity, which is meant to authenticate against the RADIUS server (computer
or human).

To create a user, click the + button.

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.

IP Address and Subnetmask


If you want to use FreeRADIUS for point to point links, you can add an IP address here
which will be assigned to the client. The same is valid for Subnetmask.

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.

To create a new client, click the + button:

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.

IP Address or Network with CIDR


This is the IP address of the Client (not the authenticating device). For example this
could be the IP address of your switch.

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.

Step 1 - Configure Interface


For the Guest Network we will add a new interface. Go to Interfaces->Assignments
And use the + to add a new interface. Press Save. The new interface will be called
OPT1, click on [OPT1] in the left menu to change its settings.

369
Select Enable Interface and fill in the following data for our example:

Description GUESTNET A descriptive name for the interface

Block Private networks unselected

Block bogon networks unselected

IPv4 Configuration Type Static IPv4 Set a static IPv4 address for the example

IPv6 configuration Type None

MAC address (Leave Blank)

MTU (Leave Blank)

MSS (Leave Blank)

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

IPv4 Upstream Gateway None

Press Save and then Apply changes.

Step 2 - Configure DHCP Server


Go to Services->DHCP->Server and click on the tab GUESTNET.

370
Fill in the following to setup the DHCP server for our guest net (leave
everything
else on its default setting):

Enable Checked Enable the DCHP server on


GUESTNET

Range 192.168.200.100 to Serve ip’s from this range


192.168.200.200

DNS servers 192.168.200.1 Supply a DNS with the lease

Gateway 192.168.200.1 Supply a gateway with the lease

Click Save.

Step 3 - Add Firewall Rules


Go to Firewall->Rules to add a new rule.

Now add the following rules (in order of prevalence):

Allow DNS
Allow the guests access to the DNS forwarder. Rule content (leave all other options
default):

Action Pass Allow this traffic

Interface GUESTNET The GuestNet Interface

371
Protocol TCP/UDP

Source GUESTNET net

Destination GUESTNET address

Destination port range DNS/DNS from DNS to DNS

Category GuestNet Basic Category used for grouping rules


Rules

Description Allow DNS

Click Save.

Allow Captive Portal Login


Action Pass Allow this traffic

Interface GUESTNET The GuestNet Interface

Protocol TCP

Source GUESTNET net

Destination GUESTNET address

Destination port range 8000/10000 (other) used for the cp zones

Category GuestNet Basic Rules Category used for grouping rules

372
Description Allow Captive Portal
Login

Click Save.

Block Local Networks


Action Block Block this traffic

Interface GUESTNET The GuestNet Interface

Protocol any

Source GUESTNET net

Destination LAN net

Category GuestNet Basic Rules Category used for grouping


rules

Description Block Local Networks

Click Save.

Action Block Block this traffic

Interface GUESTNET The GuestNet Interface

Protocol any

373
Source GUESTNET net

Destination GUESTNET address

Category GuestNet Basic Rules Category used for grouping


rules

Description Block Firewall Access

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.

Allow Guest Networks


Action Pass Allow this traffic

Interface GUESTNET The GuestNet Interface

Protocol any

Source GUESTNET net

Destination any

Destination port range any

374
Category GuestNet Basic Category used for grouping rules
Rules

Description Allow Guest Network

Click Save and then Apply changes

Your rules should look similar to the screenshot below:

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

Interfaces GUESTNET Remove the default and add


GUESTNET

Authenticate using (blank) Remove any default setting

Idle timeout 0 Disable Idle Timeout

Hard timeout 0 No hard timeout

Concurrent user logins Unchecked A user may only login once

SSL certificate none Use plain http

Hostname (leave blank) Used for redirecting login page

Allowed addresses (leave blank)

Custom template none Use default template

Description Guest Network Choose a description for the zone

Save and the Apply

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.

Lets make the following changes to the template:

Change the logo to company-logo.png

Remove the navigation bar on the top

Remove the height and width from the <img> tag

Add a welcome text

Make a link to the company website

Find the following part:

<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>

And change to:

<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.

Download the example Template (full)

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.

Step 6 - Limit Guests Bandwidth

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

Go to: Firewall->Traffic Shaper->Settings.

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

bandwidth Metric Mbit/s

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

Click on Save changes.

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):

sequence (leave on default)

interface WAN

interface 2 GUESTNET

direction in

target pipe_10Mbps_down

description Limit Guests download to


10Mbps

Click Save changes.

sequence (leave on default)

interface WAN

383
interface 2 GUESTNET

direction out

target pipe_1Mbps_up

description Limit Guests upload to


1Mbps

Click Save changes.

Now click on Apply to apply the changes.

Step 7 - Test Business GuestNet


Connect your PC or laptop to the Guest Network and start your favourite browser. Enter
an address to browse to and you will be presented with the Login form we created with
the template in the previous step. Click on login and start browsing.

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.

This example will be for our “Royal Hotel”.

Step 8 - Add Voucher Server


To add a Voucher Server go to: System->Access->Servers and click on Add server in
the top right corner of the screen.

Fill in:

Descriptive name Vouchers The name for your voucher server

Type Voucher

Click on Save.

Step 9 - Create Vouchers


Go back to the Captive portal and select Vouchers (Services->Captive Portal-
>Vouchers). Click on Create Vouchers in the lower right corner of the form.

Lets create 1 Day vouchers for our guests:

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"

The content are:

username Username the guest needs to login with

386
password Password the guest needs to login with

vouchergroup The name of the group you created

validity The time the voucher will be valid in seconds

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.

Create something like this:

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

Step 10 - Voucher Authentication


Enable the voucher authentication by changing the zone settings. Go to the tab Zones
and select the Guest Network by clicking on the pencil icon right next to it.

Change Authenticate using from an empty field to Vouchers.

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:

You can drop an active session by clicking on the trashcan.

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.

Check Voucher Status


You can check the validity and active status of a voucher by going to the voucher page
of the captive portal (Services->Captive Protal->Vouchers) and select the correct
database (Wifi day pass in our example).

390
Note

The state valid means it is activated but still valid.

Advanced - Session popup


Lets create a Session Popup so user can see some details about there session and
Logout. For this feature we will use OPNsense’s build-in api calls.

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:

Download the example Template (with popup)

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):

// redirect on successful login


if (data['clientState'] == 'AUTHORIZED') {
window.open("session_popup.html","Session Status & Logout","width=400, height=400"

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.

Type the following on the cli prompt to do so (for zone id 0):

configctl captiveportal list_clients 0

The output will be something similar to this:

393
394
HAProxy
Installation
First of all, you have to install the HAProxy plugin (os-haproxy) from the plugins view.

First Step: Configure Backend Servers

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.

For a HTTP Backend, configure like this:

Name Name of this server

Description Keep it empty

FQDN or IP Enter the IP of your Server

Port Port of the Server

SSL Keep the default


(disabled)

Verify SSL Certificate Keep the default

396
(checked)

SSL Verify CA Keep the default (empty)

Second Step: Configure a Backend


Now, as we have the backend services, we can build a backend by combining them to
groups of servers, which will serve the same service. For example if you are hosting a
Webservice and want to scale horizontally, every server in the cluster will be a “Server”,
but they will be combined to a so called “Backend”, so HAProxy can load balance
between them.

To create a new Backend, click the +.

And fill out the form:

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.

Enabled Enable the Backend (checked)

Name Enter a name for the Backend

Description Enter an optional description

Mode Select the mode HTTP as this is an HTTP


backend

Balancing Algorithm Select an load balancing algorithm

Servers Select the previously configured servers

Third Step: Configure an ACL


In this step an ACL will has to be created which is later used to decide which traffic from
a frontend belongs to which backend.

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:

Name Choose a name for this ACL

400
Description Keep it empty or choose one for your
information

Expression Select “Host contains”

Negate condition Keep it unchecked

Value Enter the (partial) hostname to compare

Click “Save changes”.

Fourth Step: Configure an Action


As promised in the previous step, the ACLs will be used. An Action will link multiple
ACLs with a Backend. An Action is created using the + button.

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”.

Name Choose a name for this Action

Description You can add an optional


description

Test Type Keep it at the default (“IF”)

402
Select ACLs Select the ACLs to be used

Logical operator Keep the default (“AND”)

Choose action Choose “Use Backend”

Use Server Keep the default (“none”)

Fifth Step Configure a frontend


Now its nearly done. The only thing that needs to be configured for HAProxy is a
Frontend. A Frontend is a a group of bound ports which are used for incoming
connections. From this Frontend we need to know which backend the request will routed
to. For this, the previously configured action is needed.

To create a new Frontend, click the + button:

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

Name Use any name

Description You may keep it empty

Listen Address Enter one or more host:port combinations, use 0.0.0.0:80 for HTTP via
IPv4

Type Choose HTTP / HTTPS

Default Keep the default of “None”


Backend

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.

All other Options


Keep all other options at the default

Sixth step: Enable and start

405
This is the last step - on the General tab, we will enable the service after a config test.

For that, the “Enable HAProxy” checkbox needs to be checked.

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

Condition type Path matches

Path matches /

Create a Rule:

407
name forward_to_dir

Test type IF

conditions root

Logical ops none

Execute function http-request redirect

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.

Add Basic Authentication to a Service


I have a Webapplication which have to be exposed to the outside and doesn’t allow
authentication. So HAProxy with basic auth would be just fine to get a mininum of
security.

Go to “Rules & Conditions” - “Conditions” and Add a new one:

409
name choose a name

Condition type Custom

option pass-through http_auth(admins)

Add a rule:

410
name a name for your rule

Test type UNLESS

condition select the previously created one

Logical operator none

Execute function http-request auth”

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:

An active support subscription


see: https://opnsense.org/support-overview/commercial-support/)

Supply your Amazon Account Number


to share the Amazon Machine Image with.

Step 1 - New Instance


Start a new instance and then go to “instances”, followed by “launch instance” and then
“My AMIs”, don’t forget to select “Shared with me”

Step 2 - Select Type


Choose an instance type

414
Step 3 - Configure security group

415
To configure security group, make sure you allow https access from your own network.

Step 4 - Configure a disk

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.

Step 7 - Review status page

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

Step 9 - Initial root password


Copy your initial root password (line ** set initial….)

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.

To make it easier we create a Phase with company A using 192.168.1.0/24 and


company B using 192.168.2.0/24. Now we need to add on each side the local LAN in the
field “Manual SPD entries”. So for company A we set 10.0.1.0/24 in the field and for B
10.0.2.0/24. This allows the NAT process to speak with the Security Policy Database.

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.

Parent interface WAN

GIF remote address Server IPv4 Address

GIF tunnel local address Client IPv6 Address

GIF tunnel remote address Server IPv6 Address/64

Route caching disabled

ECN friendly behavior disabled

Description Tunnel Broker

Note

Make sure to include the /64 prefixes!

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.

Step 3 - Basic Firewall Rules


Now add basic firewall rules. Since I have a LAN network and a WLAN network, I allow
WLAN to initiate connections to LAN, but not the other way around. I only have servers
on LAN whereas most of my clients are on WLAN (Wireless LAN). I block all incoming to
LAN and WLAN. Of course, outbound connections are fine.

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.

Save your settings.

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.

The required plugins are:

ClamAV

Postfix

Redis

436
Rspamd

After a page reload you will get some new menu entry under services for all installed
plugins.

Configuration Of The Plugins


1. ClamAV
For ClamAV, you can follow the instructions in ClamAV.

2. Redis (optional but recommended)


In the next step, we need to install the Redis database. Redis is required for caching and
for some features of the rspamd plugin.

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.

If you are ready, rspamd should be up and running.

Now you should configure the rspamd modules you need.

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:

After a click, you will see the form:

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.

Save the changes and switch to Antispam tab.

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

mdns-repeater requires at least 2 interfaces to work.

The configuration is fairly simple. Just enable the service and add the interfaces. For
example:

Property Value

Enabled checked

Interfaces LAN, OPT1,


OPT2

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 monitor IP’s to the gateways

Add a gateway group

Configure DNS for each gateway

Use policy based routing to utilize our gateway group

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.

Step 1 - Add monitor IP’s


You may skip this step if you already have setup the monitoring ip and both gateways
are shown as online.

To add a monitoring ip go to System->Gateways->All and click on the first pencil


symbol to edit the first gateway.

Now make sure the following is configured:

Disable Gateway Monitoring Unchecked Make sure monitoring is


enabled

447
Monitor IP 8.8.8.8 We use Google’s DNS

Mark Gateway as Down Unchecked

Then click on the second pencil symbol to edit the second gateway.

Now make sure the following is configured:

Disable Gateway Monitoring Unchecked Make sure monitoring is


enabled

Monitor IP 8.8.4.4 We use Google’s second DNS

Mark Gateway as Down Unchecked

Step 2 - Add Gateway Group


Go to System->Gateways->Group and press + Add Group in the upper right corner.

Use the following settings:

Group Name WANGWGROUP Enter a name for the gw routing later on

Gateway Priority WANGW / Tier 1 Select the first gateway and Tier 1

.. WAN2GW / Tier 2 Select the second gateway and Tier 2

Trigger Level Packet Loss Select the trigger you want to use

Description Failover Group Freely chosen description

448
Tip

Trigger Level Explained

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.

Packet Loss or High Latency


Triggers for either of the above conditions.

Step 3 - Configure DNS for each gateway


Go to System->Settings->General and make sure each gateway has its own DNS
setup: like this:

DNS servers

8.8.8.8 WANGW

8.8.4.4 WAN2GW

Step 4 - Policy based routing


Go to Firewall->Rules

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).

Now under Gateway change selection to WANGWGROUP.

Save and Apply changes

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.

Step 5 - Add allow rule for DNS traffic


Add a rule just above the default LAN allow rule to make sure traffic to and from the
firewall on port 53 (DNS) is not going to be routed to the Gateway Group that we just
defined.

Start with pressing the + icon in the bottom left corner.

Enter the following details:

Action Pass Allow this traffic to pass

Interface LAN

TCP/IP Version IPv4 For our example we use IPv4

Protocol TCP/UDP Select the right protocol

450
Source any

Destination Single host or Network

Destination 192.168.1.1/32 IP of the firewall only hence /32

Destination port range DNS - DNS Only DNS

Category DNS See Organize PF Rules by Category

Description Local Route DNS Freely chosen description

Gateway default Select default

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.

The current options are:


Latency thresholds
Low and high thresholds for latency in milliseconds.

Packet Loss thresholds


Low and high thresholds for packet loss in %.

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.

Avg Delay Replies Qty


How many replies should be used to compute average delay for controlling “delay”
alarms?

Avg Packet Loss Probes Qty


How many probes should be used to compute average packet loss.

Lost Probe Delay


The delay (in qty of probe samples) after which loss is computed.

Configure Load Balancing


To setup load balancing follow the same configuration procedure as for Failover, but in
step 2 choose same Tier for both Gateways.

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.

To set this option can be set under Firewall->Settings->Advanced.

Unequal Balancing (Weight)

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.

Combining Balancing & Failover


To combine Load Balancing with Failover you will have 2 or more WAN connections for
Balancing purposes and 1 or more for Failover. OPNsense offers 5 tiers (Failover
groups) each tier can hold multiple ISP’s/WAN gateways.

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.

This How To will use the Plugins C-ICAP and ClamAV.

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.

Step 1 - Setup the Proxy


Start with setting up the proxy with its basic configuration, see Setup Caching Proxy.

Step 2 - Setup Transparent Mode

454
To setup the transparent mode, see: Setup Transparent Proxy.

Step 3 - Install and Configure the ClamAV


and the C-ICAP plugins
Note

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

Step 4 - 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 the C-ICAP plugin,
the default URLs will be:

Request Modify URL icap://[::1]:1344/avscan

Response Modify URL icap://[::1]:1344/avscan

Now click on Apply

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

IMPORTANT NOTE : YOU DOWNLOAD THESE FILES AT YOUR OWN RISK!

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.

Logfile, Syslog level


If the corresponding checkbox is enabled, this will be the minimum severity for sending
or writing log messges.

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”.

Fascist Firewall Ports


These are the unfiltered ports of the firewall. The defaults of 80 and 443 are choosen,
because they are commonly open.

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.

SOCKS Port Number


The port which should be used for the SOCKS server.

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 DNS Port


If you are using Tor transparently, you can resolve .onion addresses to IPs of the given
pool for example. This also allows to keep DNS secret.

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.

Map Host To IP Pool


This option will assign IP addresses to resolved .onion domains by the Tor DNS service.
Checking this box is recommend but a transparent IP pool is required

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.

Relays And Bridges

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.

Reject Private IPs


IMPORTANT DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. This
option blocks access to RFC1918 addresses regardless of the configured policy. If you
disable this option, somebody can invade your network.

Bridge
Enable this setting, if you want to be a bridge.

Publish Server Descriptor


If this is disabled, Tor will not publish descriptors. If you don’t want to be in a directory
(for example for testing reasons), uncheck this option.

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.

Click on + to add a new ACL.

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.

Start Port, End Port


This match is the target port of a connection. You can provide only a start port if you
want to match a single port. If you provide both, a port range will be used.

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.

Step 1 - Add New LDAP server


To add a new LDAP server as authentication source, go to System->Access->Servers
and click on Add server the top right corner, just above the form.

Enter the following information:

Descriptive name ws2012 Enter a descriptive name

Type LDAP Select LDAP

Hostname or IP 10.10.10.1 Enter the IP address of you LDAP Server

472
address

Port value 389 Enter the port number, 389 is default

Transport TCP - Standard Select Standard or Encrypted

Peer Certificate When using SSL Encryption, select the


Authority CA

Protocol version 3 Select protocol version

Bind credentials cn=testusr,CN=Users,

User DN: DC=opnsense,DC=local Enter your credentials

Password: secret alway use a strong password

Search scope

Level: Entire Subtree Select Entire Subtree to retrieve all

Base DN: DC=opnsense,DC=local Enter the Base DN

Authentication Select Click & Select the containers from the list
containers

Extended Query &(objectClass=Person) Extend query, p.e. limit results to


Persons

Initial Template MicrosoftAD Select you LDAP Server Type

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.

If not (or your entered invalid credentials) it shows:

Step 3 - Import Users


If you would like to give LDAP/Active Directory users access to the GUI, you need to
import the users into the local user manager. Go to System->Access->Users you will
see a cloud import icon at the lower right corner of the form.

Click on the cloud import icon to start importing users.

A new form will be show with the individual users, select the ones you like to import.

Step 4 - Update ldap user privileges


Now if you go to System->Access->Users you will see all users including the newly
imported ldap users. You can create a specific group for these users to easily manage
the privileges or use one of your earlier created groups.

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.

Step 5 - Update system access settings


Now we have configures, verified and imported the users from our LDAP server, we
need to change the default settings to allow LDAP users to login.

Go to System->Access->Settings and change the Authentication Server from Local


Database to your newly created LDAP server. Leave the fallback on Local Database
and click on Save and Test.

The test result should look like this:

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.

Disabled Unchecked Can be used to (temporarily) disable an account

Username John A unique username

479
Password secret A strong password

Full name John Doe Optional, Full username

Expiration date Optional, if account should expire enter as


mm/dd/yyy

Group Membership Optional, select one or more groups

Certificate Optional, check if a user certificate should be created

OTP seed Optional, enter or generate a OTP seed (base32)

Authorized keys Optional, paste ssh key for ssh console access

IPsec Pre-Shared Optional, IPsec PSK


Key

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.

Add privileges to a group


After creating a group the privileges can be added by editing the group. Go to System-
>Access-Groups and click on the edit symbol (pencil) right next to the group you like to
change.

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.

Fill in the form:

Descriptive name radius_test Enter a descriptive name

Type Radius Select Radius

Hostname or IP address 10.10.10.1 Enter the IP of your Radius server

Shared Secret secret Shared secret for your Radius server

Services offered Authentication Select Authentication,for Captive portal +


accounting

Authentication port 1812 Port number, 1812 is default for accounting it’s
value 1813

Authentication Timeout 5 Timeout for Radius to respond on requests

Use the tester under System->Access->Tester to test the Radius server.

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.

API Access Token (optional)


This optional entry is for future use and further development of the Zerotier plugin. The
API access token can be generated by logging into your portal [https://my.zerotier.com]
and creating a new API Access Token. When the token has been generated, copy the
value into this input box.

local.conf settings (optional)


As described in the Zerotier Manual, a local.conf can be created to enable or disable
custom node-specific configuration overrides. Further details of permitted options can be
found on the ZeroTier Manual [https://www.zerotier.com/manual.shtml]. Please note that
the local.conf must be a valid JSON document otherwise the service will fail to start.

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.

Local Description (optional)


You may key in a description here that will help you remember what the network is for.
Please note that this field is not the same as the name/description of the Zerotier
network - it’s simply an aide-mémoire to help you remember what the network is for.

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.

Some final “Network” operations:

If you wish to completely remove the network, simply select the network and click on the
Bin icon.

If you wish to edit the network, click on the Pencil 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.

You may choose to do the same for IPv6 Configuration Type .

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

applied to your assigned interface.

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

The structure is pretty much FreeBSD: we have a source code


[https://github.com/opnsense/src] repository and a ports tree
[https://github.com/opnsense/ports]. Historically, we also have a core code
[https://github.com/opnsense/core] and tools repository
[https://github.com/opnsense/tools]. The tools repository is project shell code gluing all
repositories together, producing final images, while the core is the important GUI and
system configuration bits.

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.

Why core is not a part of source

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 core isn’t part of ports either

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.

Here are the build instructions for OPNsense


[https://github.com/opnsense/tools/blob/master/README.md].

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.

Virtual Machine for Development


Running: Use a Virtual Machine for Development

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:

# pkg install vim-lite joe nano gnu-watch git tmux screen

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

Once you have the repository, you switch it live using:

# 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

Basics and Future


PSR-1 Basic Coding Standard
PSR-2 Coding Style Guide
Python PEPs

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).

Reality: Overdue Maintenance


In reality we forked a system that went without code maintenance for a very long time
and we needed to transition that into something more structured.

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:

Hello World Module

Howto use the API

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.

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]].

506
Class names MUST be declared in StudlyCaps .

Class constants MUST be declared in all upper case with underscore separators.

Method names MUST be declared in camelCase .

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.

2.2. Character Encoding


PHP code MUST use only UTF-8 without BOM.

2.3. Side Effects


A file SHOULD declare new symbols (classes, functions, constants, etc.) and cause no
other side effects, or it SHOULD execute logic with side effects, but SHOULD NOT do
both.

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);

// side effect: loads a file


include "file.php";

// side effect: generates output


echo "<html>\n";

// 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
}

// conditional declaration is *not* a side effect


if (! function_exists('bar')) {
function bar()
{
// 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.

Class names MUST be declared in StudlyCaps .

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.

Whatever naming convention is used SHOULD be applied consistently within a


reasonable scope. That scope may be vendor-level, package-level, class-level, or
method-level.

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;

class Foo extends Bar implements FooInterface


{
public function sampleFunction($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}

final public static function bar()


{
// method body
}
}

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.

There MUST NOT be trailing whitespace at the end of non-blank lines.

Blank lines MAY be added to improve readability and to indicate related blocks of code.

There MUST NOT be more than one statement per line.

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.

2.5. Keywords and True/False/Null


PHP keywords [http://php.net/manual/en/reserved.keywords.php] MUST be in lower

515
case.

The PHP constants true , false , and null MUST be in lower case.

3. Namespace and Use Declarations


When present, there MUST be one blank line after the namespace declaration.

When present, all use declarations MUST go after the namespace declaration.

There MUST be one use keyword per declaration.

There MUST be one blank line after the use block.

For example:

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...

4. Classes, Properties, and Methods


The term “class” refers to all classes, interfaces, and traits.

4.1. Extends and Implements

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;

class ClassName extends ParentClass implements \ArrayAccess, \Countable


{
// constants, properties, methods
}

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;

class ClassName extends ParentClass implements


\ArrayAccess,
\Countable,
\Serializable
{
// constants, properties, methods
}

517
4.2. Properties
Visibility MUST be declared on all properties.

The var keyword MUST NOT be used to declare a property.

There MUST NOT be more than one property declared per statement.

Property names SHOULD NOT be prefixed with a single underscore to indicate


protected or private visibility.

A property declaration looks like the following.

<?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
}
}

4.4. Method Arguments


In the argument list, there MUST NOT be a space before each comma, and there MUST
be one space after each comma.

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
}
}

4.5. abstract , final , and static

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;

abstract class ClassName


{
protected static $foo;

abstract protected function zim();

520
final public static function bar()
{
// method body
}
}

4.6. Method and Function Calls


When making a method or function call, there MUST NOT be a space between the
method or function name and the opening parenthesis, there MUST NOT be a space
after the opening parenthesis, and there MUST NOT be a space before the closing
parenthesis. In the argument list, there MUST NOT be a space before each comma, and
there MUST be one space after each comma.

<?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 after the control structure keyword

There MUST NOT be a space after the opening parenthesis

There MUST NOT be a space before the closing parenthesis

There MUST be one space between the closing parenthesis and the opening brace

The structure body MUST be indented once

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.

5.1. if , elseif , else

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.

5.2. switch , case

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

intentional in a non-empty case body.

<?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;
}

5.3. while , do while

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
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {


// 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
};

$noArgs_longVars = function () use (


$longVar1,
$longerVar2,

526
$muchLongerVar3
) {
// body
};

$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};

$longArgs_shortVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use ($var1) {
// body
};

$shortArgs_longVars = function ($arg) use (


$longVar1,
$longerVar2,
$muchLongerVar3
) {
// 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 global variables and global constants

Declaration of functions

Operators and assignment

Inter-line alignment

Comments and documentation blocks

Class name prefixes and suffixes

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.

This article describes how this will be achieved.

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”).

Currently there are two types of services implemented in the daemon:

533
script : execute external (rc) scripts

inline : perform inline actions which are part of configd, currently only template
generation.

Template generation is handled by Jinja2 (http://jinja.pocoo.org/), more


information on how to create application templates can be found at
Using Templates.
Frontend Architecture

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.

Controllers and views


Not all parts of the framework are already implemented, but by deriving all controllers
from the base in the OPNsense project it’s easy to extend and adapt to future needs.
Documentation on how to implement controllers, with the use of views, can be found at
Using controllers and views.

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:

src : the base (FreeBSD ®) system

ports : the ports collection containing third party software

core : the OPNsense gui and system configuration parts

tools : easy tools to build OPNsense

Tip

For detailed information about the development workflow see:


OPNsense development workflow

536
Backend
The OPNsense backend consists of several components (see Architecture for a full
stack description).

Our core backend service (configd) is implemented using Python


[https://en.wikipedia.org/wiki/Python]. and provides two main features:

Service interaction (using configd actions)

Generation of configuration data (using templates)

Because some of the codebase still integrates with our legacy codebase, we provide
additional plugin options for the following components:

Services (the services status)

Syslog (define syslog targets)

Interface (register interfaces, firewall use etc.)

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.

Bootup / autorun options


Using configd
Using legacy plugins
Using Templates

537
538
Bootup / autorun options
syshook
OPNsense offers an easy method to plugin shell scripts during (early) boot stage.

Syshook scripts should be installed in :

/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.

Example (vmware guestd start, filename /usr/local/etc/rc.syshook.d/vmware.early)

#!/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”.

Example (from a configured squid proxy server using /etc/rc.conf.d/squid):

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

Our ssh service has two actions available:

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

command text shell command string to execute

542
parameters %s for every list of parameters to use, example : /i %s
parameter

type script|script_output type of call:


script (only return exit status)

script_output (return result)

message text Message to send to syslog (you can use %s


parameters)

description text User friendly description.

Test action
To test a new configd action, please restart the configd service first using:

service configd restart

Next use the supplied helper command to execute our action:

configctl sshd restart

543
Using legacy plugins
General
Legacy type plugins are located in the following location:

/usr/local/etc/inc/plugins.inc.d/

And contain files with the extension “.inc”.

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).

Every item should contain the following properties:

Property Syntax Description

enable boolean interface enabled, if so it will be saved in the


config

descr text User readable description

545
networks array, [network, list of named arrays containing remote networks
mask]

type text “none”

if text physical interface (e.g. enc0)

virtual boolean Virtual interface, true/false

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

Template package content

Every template directory should contain at least 2 files:

a content descriptor, containing the actual targets, named +TARGETS

one or more template(s)

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

Will create a file /tmp/template_sample/simple_page.txt using the template


example_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.*

By default all targets will be removed when calling cleanup.

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.

Those filters are stored in the variable TARGET_FILTERS.

{% 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:

# generate template package


configctl template reload OPNsense/Sample
# cleanup files
configctl template cleanup OPNsense/Sample

Python template usage example


The template system itself is a separate module which is used by configd, to use (or
test) the system without the daemon, use:

# import template system and config.xml handling


from modules import template
from modules import config

# construct a new template object, set root to /tmp/


tmpl = template.Template(target_root_directory="/tmp/")
# open the config.xml and bind to template object
conf = config.Config('/config.xml')
tmpl.setConfig(conf.get())

# generate output for OPNsense/Sample


generated_filenames = tmpl.generate('OPNsense/Sample')

# 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.

Designing the model


Creating models for OPNsense is divided into two separate blocks:

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.

Every model’s class should be derived from OPNsense\Base\BaseModel, a very simple


model without any (additional) logic is defined with:

<?php
namespace myVendorName\myModule;

use OPNsense\Base\BaseModel;

class myModel extends 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.

Using the same model, we would create the following file:

/usr/local/opnsense/mvc/app/models/myVendorName/myModule/myModel.xml

And start describing our (information) model, like this:

<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.

From top to bottom we find the following nodes in our tree:

exampleNumber, defined as a TextField

Mask, validation can be performed by a regex expression, this sets the expression

Default, this field is default filled with a number: 5

ValidationMessage, when validation fails, this message is returned

contacts, this is a container

entity, is defined as a recurring item, which holds the next items

email, defined as an EmailField

555
when validation fails, the ValidationMessage is returned

name, defined as a TextField without any validations

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");

// include myModel and the shared config component


use myVendorName\myModule\myModel;
use OPNsense\Core\Config;

// 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";

// add a new contact node


$node = $myMdl->contacts->entity->add();
$node->email = "test@test.com";
$node->name = "my test user";

// perform validation on the data in our model


$validationMessages = $myMdl->performValidation();
foreach ($validationMessages as $messsage) {
echo "validation failure on field ". $messsage->getField()." returning message : "
}

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:

/ui/ for the new user interface parts

/api/ used for webservices (REST)

This part of the routing is handled by lighthttpd using mod_alias and mod_rewrite.

User interface Routing


If you look at the controller directory in OPNsense, you will notice there are different
directory levels under the root controller directory in
/usr/local/opnsense/mvc/app/controllers. To support different apps and vendors
eventually, we already used a structure which is automatically used to setup the routing.

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).

The complete path of the helloworld page would eventually be:

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

/usr/local/opnsense/mvc/app/config/services.php to wire it all together.

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

And called via the following url:

560
https://{host}}/api/sample/tools/echo

When the controller has a method called echoAction.

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.

Controllers are placed in the directory


/usr/local/opnsense/mvc/app/controllers/<Vendor_name>/<Module_name>/ and should
use the standard Phalcon naming conventions, suffix Controller.php on every class file
and suffix Action on all action methods.

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

View based controllers


For rendering standard pages we have chosen to use Volt templates, the base controller
to inherit from in this case is OPNsense\Base\ControllerBase and should take care of
binding a template to the controller. Every template automatically receives standard
features (such as the menu system).

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');
}

And the volt template SampleVendor/Sample/index.volt could contain something like:

the contents of my_variable1 => <b> {{ my_variable1 }} </b> <br>


the contents of my_variable2 => <b> {{ my_variable2 }} </b> <br>

A full example can be found in the OPNsense\Sample controller directory.

More information on how to write Volt pages can be found here :


http://docs.phalconphp.com/en/latest/reference/volt.html

API based controllers


For API calls a separate class is used to derive from, which implements a simple
interface to handle calls. The main difference with the view controllers is that an action
should return a named array containing response data in stead of picking a template.

A simple index controller to echo a request back looks like this:

class TestController extends ApiControllerBase


{
/**
* @return array
*/
public function echoAction()
{
if ($this->request->hasPost("message")) {
$message = $this->request->getPost("message");
} else {

563
$message = " " ;
}

return array("message" => $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.

Our base UI controller (\OPNsense\Base\ControllerBase) implements the menu system


for further use.

An example of how to create a menu, is given below:

// create new menu


$menu = new Menu\MenuSystem();
// append an additional dynamic item into the system
$menu->appendItem("System.Advanced", "test123", array("url"=>"/testpage.php","order"=>
// test, print menu as structured named array
print_r($menu->getItems("/testpage.php"));

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:

order, sort order in our menu

VisibleName, name to use ( if not set the tagname / id will be used)

cssClass, style attributes for the frontend system.

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

Usage from php


Using the system from php is rather simple:

$acl = new OPNsense\Core\ACL();


if ( $acl->isPageAccessible("user", "/firewall_rules.php") ) {
print ( "/firewall_rules.php is accessible" ) ;
}

Usage in Volt templates


The acl scheme is bound to the default UI controller, and can be used by using the acl
keyword:

{% 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

In our sample case this will be: OPNsense/HelloWorld

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.

First we start by creating two files inside the models/OPNsense/HelloWorld directory.

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;

class HelloWorld extends 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.

Create a template named index.volt inside the views/OPNsense/HelloWorld directory


containing the following data:

<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)

First Input Form


Building your first input form

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:

Property Default Description

General.Enabled Enabled (1) Should this module be enabled (Boolean)

General.SMTPHost <empty> IP address for the remote smtp host

General.FromEmail sample@example.com Email address of the sender

580
General.ToEmail <empty> Email address to send our test email to

General.Description <empty> Description, used as subject of the email.

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>
………

All available field types can be found in the models/OPNsense/Base/FieldTypes


directory. If specific field types support additional parameters, for example for validation,
they should be registered in the model as well (just like the default tag in Enabled).

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.

When opening the page again it will render like this:

Create API calls


Create API calls to retrieve and store data

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.

* retrieve HelloWorld general settings


* @return array general settings
*/
public function getAction()
{
// define list of configurable settings
$result = array();
if ($this->request->isGet()) {
$mdlHelloWorld = new HelloWorld();
$result['helloworld'] = $mdlHelloWorld->getNodes();
}
return $result;
}

(/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();
}

// serialize model to config and save


if ($valMsgs->count() == 0) {
$mdlHelloWorld->serializeToConfig();
Config::getInstance()->save();
$result["result"] = "saved";
}
}
return $result;

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;

Support jQuery API calls


Update the view to support the API calls using jQuery

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.

Add this to the index.volt template from the HelloWorld module:

<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.
});

// link save button to API set action


$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/helloworld/settings/set",formid='frm_GeneralSettings'
// action to run after successful save, for example reconfigure service.
});
});

});

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.

Our example will write a simple configuration file, stored in


/usr/local/etc/helloworld/helloworld.conf

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.

{% if helpers.exists('OPNsense.helloworld.general') and OPNsense.helloworld.general.Enabled


[general]
SMTPHost={{ OPNsense.helloworld.general.SMTPHost|default("") }}
FromEmail={{ OPNsense.helloworld.general.FromEmail|default("") }}
ToEmail={{ OPNsense.helloworld.general.ToEmail|default("") }}
Subject={{ OPNsense.helloworld.general.Description|default("") }}
{% endif %}

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:

public function reloadAction()


{
$status = "failed";
if ($this->request->isPost()) {
$backend = new Backend();
$bckresult = trim($backend->configdRun("template reload OPNsense/HelloWorld"));
if ($bckresult == "OK") {

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

Containing something like this:

[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.

Controlling the sample


In stead of running all kinds of shell commands directly from the php code, which very
often need root access (starting/stopping services, etc), we should always communicate
to our backend process which holds templates of possible things to run and protects
your system from executing arbitrary commands.

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:

configctl template reload OPNsense/HelloWorld

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:

service configd restart

And test our new command using:

configctl helloworld test

Which should return some response in json format.

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.

public function testAction()


{
if ($this->request->isPost()) {
$backend = new Backend();
$bckresult = json_decode(trim($backend->configdRun("helloworld test")), true);
if ($bckresult !== null) {
// only return valid json type responses
return $bckresult;
}
}

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:

(in script section)


$("#testAct").click(function(){
$("#responseMsg").removeClass("hidden");
ajaxCall(url="/api/helloworld/service/test", sendData={},callback=function(data,status
// action to run after reload
$("#responseMsg").html(data['message']);
});
});

(in html section)

<div class="alert alert-info hidden" role="alert" id="responseMsg">

</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:

<?= gettext('your string here') ?>

And this way into a volt template:

{{ lang._('your string here') }}

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.

For php it works this way:

<?= sprintf(gettext('your %s here'), $data) ?>

And for volt templates it works this way:

{{ lang._('your %s here') | format(data) }}

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.

Create an installable plugin


All files are created in their original locations (on the OPNsense machine /usr/local/…),
now we are ready to create a package from them. To fully use this process and create
the actual package, it’s best to setup a full build environment (explained over here:
https://github.com/opnsense/tools )

When everything is in place, we will create a new plugin directory. For this example we
will use the following:

/usr/plugins/devel/helloworld/

Add a new Makefile, containing the information for our plugin:

600
PLUGIN_NAME= helloworld
PLUGIN_VERSION= 1.0
PLUGIN_COMMENT= A sample framework application
#PLUGIN_DEPENDS=
PLUGIN_MAINTAINER= user@domain

.include "../../Mk/plugins.mk"

Then create an src directory in here:


/usr/plugins/devel/helloworld/src/

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.

if /usr/local/etc/rc.d/configd status > /dev/null; then


/usr/local/etc/rc.d/configd restart

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

(-1.0 comes from the version in the makefile)

Reference

source of this example :


https://github.com/opnsense/plugins/tree/master/devel/helloworld

build instructions : https://github.com/opnsense/tools

frontend template language reference (Volt) :


https://docs.phalconphp.com/en/latest/reference/volt.html

configuration template language reference (mostly the same as Volt) :


http://jinja.pocoo.org/docs/dev/

OPNsense architecture Architecture

OPNsense creating models Develop:Frontend/Creating_models

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

Code sample (python)


For the python code sample we use the nice “requests” library (http://docs.python-
requests.org/en/latest/), which makes http calls very easy.

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

# define endpoint and credentials


api_key = 'w86XNZob/8Oq8aC5hxh2he+vLN00r0kbNarNtdpoQU781fyoeaOBQsBwkXUt'
api_secret = 'puOyw0Ega3xZXeD26XVrJ5WYFepOseySWLM53pJASeTA3'
url = 'https://192.168.1.1/api/core/firmware/status'

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)

if response['status'] == 'ok' and response['status_upgrade_action'] == 'all':


print ('OPNsense can be upgraded')
print ('download size : %s' % response['download_size'])
print ('number of packages : %s' % response['updates'])
if response['upgrade_needs_reboot'] == '1':
print ('REBOOT REQUIRED')
elif response['status'] == 'ok' and response['status_upgrade_action'] == 'pkg':
print ('OPNsense can be upgraded, but needs a pkg upgrade first')
elif 'status_msg' in response:
print (response['status_msg'])
else:
print ('Connection / Authentication issue, response received:')
print 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

And schedule the actual upgrade of all packages using:

curl -XPOST -d '{"upgrade":"all"}' -H "Content-Type: application/json" -k -u "w86XNZob/8Oq8aC5hxh2h

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.

Relations with OPNsense


OPNsense is build on top of FreeBSD. The aim of the OPNsense team is to stay as
close to the original FreeBSD source as possible. OPNsense can be installed on a
standard FreeBSD installation, this way a hosted system can be converted easily to run
OPNsense. A bootstrap script is available to make the installation process a joy full
experience.

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.

Free, Libre Open Source Software

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.

Relations with OPNsense

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.

Our extensive knowledge of software development provides the OPNsense community


with a modern and professional approach and results in maintainable software.

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.

Why Fork FreeBSD?


HardenedBSD forked the FreeBSD codebase for ease of development. Prior to
HardenedBSD’s founding, Oliver and Shawn worked on separate repositories,
occasionally causing collaboration issues. Unifying the codebases was a natural step in
efficient, effective collaboration between the two individuals. Two years have passed
since the unification of the work and HardenedBSD is growing faster than ever.

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.

Cooperation with OPNsense


In May 2015, HardenedBSD announced their cooperation with OPNsense. A
HardenedBSD-flavored versions of OPNsense is available as of June 2015.

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.

Manuel Kasper, wrote the following on 15 February 2015:

Dear m0n0wall enthusiasts,

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.”

source: opensource.org [http://opensource.org/about]

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]

Deciso believes that sharing knowledge makes for better products.

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.

OPNsense License & Copyright


OSI Approved License

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.

OPNsense is available under the BSD 2-Clause “Simplified” or “FreeBSD” license:

OPNsense® [http://opnsense.org] is Copyright © 2014 – 2016 by Deciso B.V. All rights


reserved. 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.

THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED


WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

OPNsense is based on FreeBSD [https://www.freebsd.org] Copyright © The FreeBSD


Project. All rights reserved.

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).

Packages and ports


OPNsense includes various freely available software packages and ports. The current
ports are listed here
[https://github.com/opnsense/tools/blob/master/config/latest/ports.conf].

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:

Deciso B.V. All rights reserved.

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.

THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND


CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

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.

The official OPNsense logo is available for download: OPNsense logo .

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.

To receive community support, the following options are available:

627
Start searching this documentation & wiki

The OPNsense forum [https://forum.opnsense.org]

Ask online users on IRC Freenode [https://freenode.net/] #opnsense

Community Support Levels


Tier 1 – Core (Critical)
Core team develops and supports,

Compiler errors or functional failures block git merges and releases,

Functionality is part of the standard installation.

Tier 2 – Plugins (Non-Critical)


Core team develops and supports, sometimes with help from community members

Compiler errors or functional failures block git merges,

Functionality problems such as ‘known issues’ or might still going into releases,

Features require user to install the plugin / functionality not installed by default.

Tier 3 – Plugins (Community)


Tier 3 is community supported, this means the OPNsense core development team won’t
support it to avoid overloading the team,

628
When accepting a Tier 3 feature into the code base, it will come with a number of limits
and conditions:

Submitter must commit to maintaining it:

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!

Why wait? Donate today !

630
Partner program
The OPNsense project offers a partner program where businesses receive project
benefits while supporting the project financially.

Main benefits include:

Listing on our OPNsense partner page [https://opnsense.org/partners/]

Access to the core team

To get enlisted as partner of the OPNsense project means a minimum annual


investment of € 2500.Partners that made an exceptional contribution to the project are
assigned the Platinum Partner status.

Support Contract
with a support contract we support you and you support us as OPNsense is fully
supported by Deciso.

For support options see OPNsense Commercial Support [https://opnsense.org/support-


overview/commercial-support/]

Development
Contributing to the ongoing development of OPNsense can be done by:

631
Testing a development version and

Report issues and/or

Help fixing issues as well as by

Contributing new functionality

Share your code with the project by manner of a pull request.

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:

pkg install -y opnsense-devel

And to revert back to the production version:

pkg install -y opnsense

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.

Designing new features


If you like to help designing new features then start with reading the Development
manual and checkout our roadmap [https://opnsense.org/about/road-map/] as well as
our issue tracker [https://github.com/opnsense/core/issues]. Before starting it is always a
good to share your idea first with a core developer, to do so you can use either:

github [https://github.com/opnsense/core/] and create a issue


[https://github.com/opnsense/core/issues/new] and mention you volunteer for taking on
the development task (we will correctly label it as enhancement or feature)

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).

Documentation & wiki articles


The easiest way to help with documentation is to write how-to type articles. As the wiki &
documentation project itself is written in reStructuredText you can offer your content in
this format (preferably as pull request), but other formats are also possible, such as:

634
markup with ./images/directory including the used images(in any)

word document with embedded images (if any)

To include you documentation send it to contact @ opnsense.org. Make sure that:

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.

Forum & IRC


If you are an experienced network engineer, know a lot about firewall technology or if
you are excited about OPNsense, then you can contribute to the project by helping
others on the forum or on irc.

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

You might also like