Building pfSense from Source and Contributing
pfSense CE is an open-source project built on FreeBSD. Its source code is hosted on GitHub across three primary repositories: the base system with the GUI, modified FreeBSD sources, and a ports collection. Developers can build pfSense from source, apply fixes through the System Patches package without a full rebuild, or contribute to the project via pull requests.
Source Code Repositories
pfSense CE development spans three GitHub repositories:
| Repository | Contents | Purpose |
|---|---|---|
| pfSense/pfSense | GUI code, build scripts | Web interface, PHP logic, utilities |
| pfSense/FreeBSD-src | OS source code | FreeBSD kernel and base system |
| pfSense/FreeBSD-ports | Ports and packages | Build information for software, pfSense packages |
The primary development branch is master for the pfSense/pfSense repository and devel for FreeBSD-ports. Release branches follow the naming convention RELENG_2_8_1.
Build Environment Requirements
Building pfSense from source requires a FreeBSD-based environment matching the target release version. pfSense uses poudriere for package building and installation image creation.
Minimum requirements:
- FreeBSD matching the target pfSense release (see the version correspondence table )
- Poudriere installed for port building
- Adequate disk space (at least 50 GB for a full build)
- Git for repository management
# Install required tools on FreeBSD
pkg install git poudriereRepository Structure
The pfSense/pfSense repository is organized as follows:
src/- PHP files for the web interface, configuration scriptstools/- build scripts and developer utilitiessrc/etc/inc/- core PHP modules (config.inc, util.inc, interfaces.inc)src/usr/local/www/- web interface pagessrc/etc/phpshellskel/- PHP Shell scripts
Building from Source
The process for building pfSense CE from source:
# Clone the main repository
git clone https://github.com/pfsense/pfSense.git
cd pfSense
# Switch to the desired branch (e.g., RELENG_2_8_1)
git checkout RELENG_2_8_1
# Start the build (requires a configured poudriere environment)
./build.shA full build compiles the FreeBSD kernel, builds all ports via poudriere, and produces an installation ISO image. The process is time-consuming and requires proper environment configuration.
System Patches - Fixes Without Rebuilding
The System Patches package allows applying corrections to pfSense without a full system rebuild. Patches can be obtained from the official repository, pasted in manually, or uploaded from external sources.
Installation
Install the package via System > Package Manager > Available Packages by searching for System Patches.
Usage
Once installed, the package is accessible at System > Patches. It provides:
- Fetching recommended patches from Netgate with auto-apply capability
- Adding custom patches from URLs, pasted text, or uploaded files
- Applying and reverting patches through the web interface
- Testing fixes from pull requests before they are merged into a release
System Patches is particularly useful for validating GitHub pull request fixes before upgrading to the next pfSense version.
gitsync - Updating Between Snapshots
The gitsync utility synchronizes PHP code from the pfSense CE Git repository, enabling developers to receive fixes between official releases without installing a new snapshot.
Limitations
- Works only with pfSense CE; not compatible with pfSense Plus
- Synchronizes PHP files only - binary changes are not applied
- Some PHP changes require corresponding binary updates available only through a full snapshot
- Recommended for use only when directed by developers or when the user closely follows development activity
Running gitsync
From the pfSense console menu, select option 12 (developer shell):
> playback gitsync masterOr from the standard shell (console option 8):
pfSsh.php playback gitsync masterTo synchronize with a specific release branch, replace master with the branch name:
pfSsh.php playback gitsync RELENG_2_8_1If Git is not installed, add it manually:
pkg install gitIf errors occur due to repository URL changes, remove the old clone:
rm -rf /root/pfsense/
pfSsh.php playback gitsync masterSubmitting Pull Requests
To contribute changes to pfSense CE via GitHub:
- Create an issue entry in pfSense Redmine for the bug or feature (minor typo fixes are exempt)
- Fork the appropriate repository:
pfSense/pfSense- for base system and GUI changespfSense/FreeBSD-ports- for package changes
- Make changes in the correct branch:
master- for pfSense/pfSensedevel- for FreeBSD-ports
- Reference the Redmine ticket number in your commit message
- Create a pull request with a description and a link to the Redmine entry
- Add the PR link to the corresponding Redmine issue
Pull requests can be tested on a live system using the System Patches package before they are accepted into the main branch.
Developer Style Guide
pfSense follows the K&R BSD KNF coding style. Key rules:
Formatting
- Tabs for indentation (8-stop width); spaces are not permitted
- Braces are mandatory for all
if,for, andforeachblocks, even single-line ones - Space between keywords and parentheses (
if (,foreach (), but not between function names and arguments (function_name() - No trailing whitespace on any line
PHP Conventions
- Variable names in lowercase with underscores (
$my_variable) or camelCase ($myVariable) - Never use
$gas a loop variable - it conflicts with the pfSense global$g - Use
elseifinstead ofelse iffor compatibility with PHP alternative syntax - Do not use deprecated PHP functions
Security
- Minimize shell command execution; when necessary, use
escapeshellarg()for variables - Always escape user input with
htmlspecialchars()when rendering output - Follow MVC principles: separate display logic from validation and storage logic
Comments
- Use
//or/* */syntax, written in English - Labels:
TODO:for planned work,FIXME:for known issues,NOTE:for important clarifications
PHP 8.x Considerations
pfSense has migrated to PHP 8.x, which introduces several requirements for developers:
- Strict typing: implicit type coercions generate warnings
- Removed functions:
each(),create_function(), andmysql_*are no longer available - Named arguments: function parameter names must maintain backward compatibility
- Use
elseifinstead ofelse if- the latter does not work correctly with alternative syntax
Verify code compatibility with the target PHP version before submitting a pull request.
Debug Kernel
For diagnosing kernel-level issues, pfSense provides a package with debug symbols:
pkg install pfSense-kernel-debugThe debug kernel includes symbols needed for analyzing core dumps and kernel tracing. Use it when reproducing a kernel panic or preparing a bug report related to kernel behavior.
FreeBSD Issue Policy
pfSense is based on FreeBSD, and certain issues belong to the FreeBSD base system rather than pfSense itself. When encountering a bug related to the kernel, drivers, or FreeBSD base utilities:
- Verify whether the issue reproduces on a clean FreeBSD installation of the corresponding version
- If it reproduces on FreeBSD, report it to the FreeBSD bug tracker
- If the issue is pfSense-specific, create an entry in pfSense Redmine
Netgate developers do not fix issues in the FreeBSD base system, except for critical security vulnerabilities.
Reporting Bugs and Requesting Features
Reporting Bugs
To report a bug in pfSense:
- Check whether the issue already exists in pfSense Redmine
- Gather diagnostic information (pfSense version, FreeBSD version, logs)
- Create a new entry with a detailed description: reproduction steps, expected behavior, and actual behavior
- Attach screenshots, logs, and panic information if applicable
Requesting Features
Feature requests are also created in Redmine. Describe the proposed functionality, its justification, and potential implementation approaches. Technical development questions can be discussed on the Netgate Forum .
Related Sections
- Package Development - creating custom packages, port structure, XML manifest
- Custom Scripts - automation scripts, Shellcmd, and Cron
- API and Automation - programmatic management via REST API