# opnsense/core: the PHP backend behind the OPNsense firewall GUI

> opnsense/core is the PHP codebase that renders the OPNsense web GUI, serves its API and drives the system configuration. It is a package source tree for developers, not an installer, and its README points elsewhere for building.

**opnsense/core** — OPNsense GUI, API and systems backend

- Repository: https://github.com/opnsense/core
- Website: https://opnsense.org/
- Stars: 4,699 · Forks: 993
- Language: PHP
- License: BSD-2-Clause
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/opnsense-core

## What opnsense/core actually is, and who it is for

This repository is the GUI, API and systems backend of OPNsense, written in PHP. It is not the router firmware image and not the installer. The README opens by inviting developers to contribute to the code base, and the repository layout backs that up: the top level holds a Makefile, an Mk/ directory of included make fragments, a plist, a Scripts/ directory and the src/ tree where the code lives. There is no ISO, no disk image and no install script for an appliance here.

That shapes the audience narrowly. If you run OPNsense on a box at home or in an office, this repository is not the thing you download. If you write a plugin, patch a form, add an API endpoint, or want to read how the configuration model is assembled before filing a bug, this is the tree you clone. The README also points contributors at CONTRIBUTING.md and at the architecture document under docs.opnsense.org, which is where the codebase outline lives rather than in the README itself.

## How the PHP tree, MVC code and build fragments fit together

The Makefile is the clearest statement of architecture available in the README and the repository files. It includes Mk/version.mk, Mk/defaults.mk, Mk/common.mk, Mk/git.mk, Mk/lint.mk, Mk/style.mk and Mk/sweep.mk, so the build logic is split by concern rather than kept in one file. The main target simply pages out README.md, which tells you the Makefile is a developer entry point, not a packaging pipeline by itself.

The part worth reading closely is the loop over ABI, PHP and PYTHON. For each of those three names the Makefile checks whether CORE_<NAME> is set, and if it is empty it emits a warning that reads Cannot build without CORE_<NAME> set, then appends the assignment to CORE_MAKE. In other words the build does not silently guess your target ABI or interpreter versions. There is a follow-on check on the ABI string: _CORE_NEXT strips the dots from CORE_ABI, and the Makefile compares the second field against 7. That is version gating written directly into make syntax, and it means a mismatched ABI is caught at build time rather than at runtime.

The README describes the project's own approach as evolving gradually toward a new codebase rather than a big bang rewrite. For anyone reading the source, that explains why the tree mixes older procedural PHP with MVC code: make style runs PSR12 checks on MVC PHP and PEP8 checks on Python, which implies both styles coexist and only the MVC portion is held to the PHP standard.

## Building a package from the opnsense/core source tree

The README says the build tools live in a separate repository at github.com/opnsense/tools, and that notes on building OPNsense are found there. So the first step is not in this repository at all. What this repository gives you is the make package target, which the README says creates a package of the current state of the repository and may require several packages to be installed, offering help when a missing file must be fetched from an external location.

Options are passed as make variable assignments. The README gives this exact example:

```bash
make package CORE_NAME=my_new_name
```

The README lists the options you can set: CORE_DEPENDS for required dependencies, CORE_DEPENDS_ARCH for architecture-specific packages, CORE_ORIGIN for a FreeBSD compatible package or ports origin, CORE_COMMENT for a short description, CORE_MAINTAINER for the maintainer email, CORE_WWW for the web URL, and CORE_NAME for the package name. It adds that options are either set to sane defaults or detected at runtime, which is why the example above only overrides one of them.

For day to day work the README suggests an OPNsense VM with the os-debug plugin installed, which offers the necessary tools. The remaining targets are short and specific: make update pulls the latest commits from the current branch from upstream, make upgrade runs the package build and replaces the installed package on the system, make collect fetches changes from the running system for all known files, and make lint runs several syntax checks, which the README recommends before opening a pull request. make style runs the PSR12 and PEP8 checks, and make sweep runs several automatic sanitizers over the code base.

## Where opnsense/core is the wrong thing to reach for

The most common mismatch is treating this repository as a distribution. Nothing in the README describes downloading an image, writing it to media, or running an installer. The homepage field points at opnsense.org for the product, and the build notes point at opnsense/tools. If your goal is a working firewall by the end of the afternoon, this tree adds a FreeBSD build environment, a package toolchain and an ABI decision before you get anywhere near a bootable system.

A second limitation is the build's own strictness. The Makefile warns rather than defaults when CORE_ABI, CORE_PHP or CORE_PYTHON is empty, so a fresh checkout on a host without those values set will not produce a package. The ABI string is then parsed and compared against 7, which means the build is tied to a specific FreeBSD ABI generation. Cross-building for a different ABI is not something the README or the Makefile shows.

Third, the README is thin on rollback. make upgrade replaces the currently installed package in the system, and the README does not document a revert target or a way to restore the previous package after a failed upgrade. make collect exists to pull changes from the running system, which is useful in the other direction, but the README does not describe it as a backup mechanism. Anyone testing a change on a live firewall should treat that gap as a real risk rather than assume the tooling handles it.

## opnsense/core against pfSense and against building your own stack

The comparison people actually search for is OPNsense versus pfSense, and the repositories differ in a way that matters to a developer. OPNsense's core is published here as PHP under the 2-Clause BSD licence, with the README stating that every contribution must be licensed under the same conditions to keep the project free and accessible. The build tooling is a separate public repository, and the contribution path is a normal GitHub pull request flow with a CONTRIBUTING.md and a SECURITY.md in the tree.

A second alternative is not another firewall at all but assembling the pieces yourself on FreeBSD: PF for filtering, a web server, and your own configuration layer. That gives you total control over the data model, and it also means you own the GUI, the API, the upgrade path and the config parsing. opnsense/core is the opposite trade: you inherit an existing MVC structure, a plist, a package build and a lint and style gate, and in exchange you work inside someone else's conventions. The Makefile's ABI check is a good illustration of that bargain, since it constrains you to a supported target in return for catching a mismatch early.

If you only need to automate an existing OPNsense box, neither path is necessary. The repository describes itself as providing the API as well as the GUI, so scripting against a running system is a lighter option than building the core from source.

## Licence, contribution terms and the cost of tracking the tree

The licence is BSD-2-Clause, given in the LICENSE file and restated in the README, which adds that contributions must carry the same terms. For a company embedding or forking the PHP code, that is a permissive arrangement, but the README's contribution clause is a condition on what you send upstream rather than a restriction on your own fork. This is a description of what the files say, not legal advice; the LICENSE file is the text that governs.

The maintenance cost of following this tree is set by how fast the branch moves. The last push to master was on 2026-09-22, one day before this writing, and the repository is not archived. A fork that patches GUI pages or API endpoints will need to rebase against that pace, and the lint, style and sweep targets exist precisely because the project expects changes to be checked before they land. The Makefile copyright header runs from 2014 to 2026, so the tree has been carried forward for a long time rather than restarted.

One practical cost worth naming: make style splits its checks by language, PSR12 for MVC PHP and PEP8 for Python. If your change touches both, you run both gates. The README presents these as things to run before a pull request, which is a reasonable reading of their purpose.

## Conclusion

Adopt opnsense/core if you are modifying OPNsense itself: adding a plugin hook, fixing a GUI page, or reading how an API endpoint is wired. Do not adopt it as a way to get a firewall running; the README sends you to opnsense/tools for build notes and to the project site for the product. Before you touch anything, verify your CORE_ABI, CORE_PHP and CORE_PYTHON values, since the top-level Makefile warns and skips the build when any of the three is empty.

## FAQ

### Is OPNsense a router or a firewall?

The repository describes itself as the OPNsense GUI, API and systems backend, and its topic list includes firewall, routing, shaping and VPN, so it covers both roles in one system. opnsense/core is the PHP code behind that system rather than the product image.

### Is OPNsense free for home use?

The README states that OPNsense is and will always be available under the 2-Clause BSD license, and that every contribution must be licensed under the same conditions. It does not describe separate home or commercial tiers.

### How do I build a package from the opnsense/core repository?

Run make package, optionally overriding options such as CORE_NAME, for example make package CORE_NAME=my_new_name. The README notes the target may require several packages to be installed and that the build tools themselves live in the opnsense/tools repository.

### Which variables must be set before opnsense/core will build?

The top-level Makefile warns Cannot build without CORE_ABI, CORE_PHP or CORE_PYTHON set when any of those three is empty. It also parses CORE_ABI and compares part of the version string against 7.

### Can I install a firewall directly from opnsense/core?

No. The README covers building a package and the make targets around it, and sends readers to github.com/opnsense/tools for build notes. It does not describe downloading or writing an installation image.

## Sources

- [Issues](https://github.com/opnsense/core/issues)
- [License: BSD-2-Clause](https://github.com/opnsense/core/blob/master/LICENSE)
- [opnsense/core on GitHub](https://github.com/opnsense/core)
- [Project website](https://opnsense.org/)
- [README](https://github.com/opnsense/core/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/opnsense-core
