Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions .github/workflows/build-freebsd16.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
name: FreeBSD Package Matrix

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
merge_group:
branches: [ "main" ]
release:
types: [ published ]
workflow_dispatch:

permissions:
contents: write

jobs:
build:
name: Build pfSense package on FreeBSD ${{ matrix.target.label }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- label: "15.0"
freebsd_major: "15"
release: "15.0"

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Prepare cache directories (${{ matrix.target.label }})
run: |
mkdir -p ".cache/freebsd-${{ matrix.target.freebsd_major }}/distfiles"
mkdir -p ".cache/freebsd-${{ matrix.target.freebsd_major }}/pkg"

- name: Cache FreeBSD distfiles and pkg (${{ matrix.target.label }})
uses: actions/cache@v4
with:
path: |
.cache/freebsd-${{ matrix.target.freebsd_major }}/distfiles
.cache/freebsd-${{ matrix.target.freebsd_major }}/pkg
key: freebsd-cache-${{ matrix.target.freebsd_major }}-${{ github.ref_name }}-${{ hashFiles('security/pfSense-pkg-crowdsec/**') }}
restore-keys: |
freebsd-cache-${{ matrix.target.freebsd_major }}-
- name: Build and bundle packages (${{ matrix.target.label }})
uses: vmactions/freebsd-vm@v1
with:
release: ${{ matrix.target.release }}
usesh: true
sync: rsync
prepare: pkg update -f && pkg install -y git ca_root_nss pkgconf poudriere-devel rsync crowdsec crowdsec-firewall-bouncer
run: |
set -eux
WORKSPACE="${GITHUB_WORKSPACE}"
HOST_CACHE="${WORKSPACE}/.cache/freebsd-${{ matrix.target.freebsd_major }}"

if [ ! -f /usr/ports/Mk/bsd.port.mk ]; then
mkdir -p /usr/ports
git clone --depth 1 https://git.FreeBSD.org/ports.git /usr/ports
fi

mkdir -p /usr/ports/security
rsync -a "${WORKSPACE}/security/pfSense-pkg-crowdsec/" /usr/ports/security/pfSense-pkg-crowdsec/

mkdir -p /usr/ports/distfiles /var/cache/pkg
if [ -d "${HOST_CACHE}/distfiles" ] && [ "$(ls -A "${HOST_CACHE}/distfiles" || true)" ]; then
rsync -a "${HOST_CACHE}/distfiles/" /usr/ports/distfiles/ || true
fi
if [ -d "${HOST_CACHE}/pkg" ] && [ "$(ls -A "${HOST_CACHE}/pkg" || true)" ]; then
rsync -a "${HOST_CACHE}/pkg/" /var/cache/pkg/ || true
fi

cd /usr/ports/security/pfSense-pkg-crowdsec
# Keep dependency resolution non-interactive inside CI.
env BATCH=yes make clean package

PKG_OUTPUT=/usr/ports/packages/All
WORKDIR=/tmp/crowdsec-release
mkdir -p "${WORKDIR}/All"
cp "${PKG_OUTPUT}"/pfSense-pkg-crowdsec-*.pkg "${WORKDIR}/All/"
pkg fetch -d -o "${WORKDIR}" crowdsec crowdsec-firewall-bouncer

cd "${WORKDIR}/All"
ls -lh
TARFILE="${WORKSPACE}/freebsd-${{ matrix.target.freebsd_major }}-amd64.tar"
tar -czf "${TARFILE}" crowdsec-*.pkg crowdsec-firewall-bouncer-*.pkg pfSense-pkg-crowdsec-*.pkg
sha256 "${TARFILE}" > "${TARFILE}.sha256"
cp "${PKG_OUTPUT}"/pfSense-pkg-crowdsec-*.pkg "${WORKSPACE}/pfSense-pkg-crowdsec-${{ matrix.target.freebsd_major }}.pkg"
sha256 "${WORKSPACE}/pfSense-pkg-crowdsec-${{ matrix.target.freebsd_major }}.pkg" > "${WORKSPACE}/pfSense-pkg-crowdsec-${{ matrix.target.freebsd_major }}.pkg.sha256"
rsync -a /usr/ports/distfiles/ "${HOST_CACHE}/distfiles/" || true
rsync -a /var/cache/pkg/ "${HOST_CACHE}/pkg/" || true

- name: Upload artifact (${{ matrix.target.label }})
uses: actions/upload-artifact@v4
with:
name: freebsd-${{ matrix.target.freebsd_major }}-amd64
path: |
freebsd-${{ matrix.target.freebsd_major }}-amd64.tar
freebsd-${{ matrix.target.freebsd_major }}-amd64.tar.sha256
pfSense-pkg-crowdsec-${{ matrix.target.freebsd_major }}.pkg
pfSense-pkg-crowdsec-${{ matrix.target.freebsd_major }}.pkg.sha256

bundle_freebsd16:
name: Repack FreeBSD 16 release bundle
needs: build
runs-on: ubuntu-latest
steps:
- name: Download FreeBSD 15 artifact
uses: actions/download-artifact@v4
with:
name: freebsd-15-amd64
path: artifacts/freebsd-15

- name: Download upstream FreeBSD 16 bundle
run: |
set -eux
API_URL="https://api.github.com/repos/crowdsecurity/pfSense-pkg-crowdsec/releases/latest"
RELEASE_JSON=$(curl -fsSL "$API_URL")
ASSET_URL=$(printf '%s' "$RELEASE_JSON" | tr ',' '\n' | grep '"browser_download_url":' | grep '/freebsd-16-amd64.tar"' | sed -E 's/.*"browser_download_url": *"([^"]+)".*/\1/' | head -n 1)
if [ -z "$ASSET_URL" ]; then
echo "Unable to locate freebsd-16-amd64.tar in the upstream release assets."
exit 1
fi
curl -fsSL "$ASSET_URL" -o freebsd-16-amd64.upstream.tar

- name: Repack FreeBSD 16 artifact with rebuilt pfSense package
run: |
set -eux
WORKDIR=$(mktemp -d)
trap 'rm -rf "$WORKDIR"' EXIT

tar -xzf freebsd-16-amd64.upstream.tar -C "$WORKDIR"
find "$WORKDIR" -maxdepth 1 -name 'pfSense-pkg-crowdsec-[0-9]*.pkg' -delete

# The pfSense package contains only scripts and static assets, so the
# NO_ARCH package rebuilt on 15.0 can be reused inside the 16 bundle.
cp artifacts/freebsd-15/pfSense-pkg-crowdsec-15.pkg "$WORKDIR/pfSense-pkg-crowdsec-16.pkg"

(
cd "$WORKDIR"
tar -czf "$GITHUB_WORKSPACE/freebsd-16-amd64.tar" crowdsec-*.pkg crowdsec-firewall-bouncer-*.pkg pfSense-pkg-crowdsec-*.pkg
)

sha256sum freebsd-16-amd64.tar | awk '{print $1 " freebsd-16-amd64.tar"}' > freebsd-16-amd64.tar.sha256
cp artifacts/freebsd-15/pfSense-pkg-crowdsec-15.pkg pfSense-pkg-crowdsec-16.pkg
sha256sum pfSense-pkg-crowdsec-16.pkg | awk '{print $1 " pfSense-pkg-crowdsec-16.pkg"}' > pfSense-pkg-crowdsec-16.pkg.sha256

- name: Upload artifact (FreeBSD 16)
uses: actions/upload-artifact@v4
with:
name: freebsd-16-amd64
path: |
freebsd-16-amd64.tar
freebsd-16-amd64.tar.sha256
pfSense-pkg-crowdsec-16.pkg
pfSense-pkg-crowdsec-16.pkg.sha256

release:
name: Publish GitHub Release assets
needs: [build, bundle_freebsd16]
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download FreeBSD 15 artifact
uses: actions/download-artifact@v4
with:
name: freebsd-15-amd64
path: artifacts/freebsd-15

- name: Download FreeBSD 16 artifact
uses: actions/download-artifact@v4
with:
name: freebsd-16-amd64
path: artifacts/freebsd-16

- name: List assets
run: ls -R artifacts

- name: Publish release assets
uses: softprops/action-gh-release@v2
with:
files: |
artifacts/freebsd-15/*
artifacts/freebsd-16/*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/work
debug-logs/
51 changes: 51 additions & 0 deletions 0001-fix-no-working-build-for-25.11-FreeBSD-16-amd64.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From a77ea2c5b223eb621bae29c310a4ff014c19b85f Mon Sep 17 00:00:00 2001
From: frli4797 <5780904+frli4797@users.noreply.github.com>
Date: Tue, 10 Mar 2026 11:19:43 +0100
Subject: [PATCH] fix: no working build for 25.11/FreeBSD:16:amd64 Fixes #121

---
.../files/usr/local/pkg/crowdsec.inc | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/security/pfSense-pkg-crowdsec/files/usr/local/pkg/crowdsec.inc b/security/pfSense-pkg-crowdsec/files/usr/local/pkg/crowdsec.inc
index b867819..3e7b9c1 100644
--- a/security/pfSense-pkg-crowdsec/files/usr/local/pkg/crowdsec.inc
+++ b/security/pfSense-pkg-crowdsec/files/usr/local/pkg/crowdsec.inc
@@ -65,7 +65,9 @@ $crowdsec_aliases = array(
*/
function crowdsec_config_migrate()
{
- parse_config(true);
+ if (function_exists('parse_config')) {
+ parse_config(true);
+ }
$cf = config_get_path('installedpackages/crowdsec/config/0', []);

// noop on fresh install
@@ -156,8 +158,11 @@ function crowdsec_install()
// Prepare rc.conf.d variables
mwexec('sysrc -f /usr/local/etc/rc.conf.d/crowdsec crowdsec_machine_name=pfsense');
mwexec('sysrc -f /usr/local/etc/rc.conf.d/crowdsec_firewall crowdsec_firewall_name=pfsense-firewall');
+
+ if (function_exists('parse_config')) {
+ parse_config(true);
+ }
// UPDATE pfSense ALIAS TABLES
- parse_config(true);
config_init_path(implode('/', ['aliases']));
$exist_aliases = config_get_path('aliases/alias', []);
$exist_aliases_names = array_column($exist_aliases, 'name');
@@ -224,7 +229,9 @@ function crowdsec_deinstall()
// Delete aliases
global $crowdsec_aliases;
$delete_flag = false;
- parse_config(true);
+ if (function_exists('parse_config')) {
+ parse_config(true);
+ }
foreach ($crowdsec_aliases as $crowdsec_alias) {
$crowdsec_index = get_alias_index($crowdsec_alias['name']);
if ($crowdsec_index !== -1) {
--
2.53.0

18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ It is not installed from the official repositories, at least not yet, but you ar

Please refer to the [detailed documentation](https://docs.crowdsec.net/docs/getting_started/install_crowdsec_pfsense/) to install or update it from a release archive.

## Building for FreeBSD 16 / pfSense 25.11

If you need a package that already includes the latest fixes from this fork (for example commit `a77ea2c5` to restore compatibility with the pfSense 25.11 / FreeBSD 16 preview), follow the step-by-step guide in [`docs/build-install-freebsd16.md`](docs/build-install-freebsd16.md).

The document explains how to build the port locally, bundle it with the required `crowdsec` and `crowdsec-firewall-bouncer` packages, and install the resulting tarball with `install-crowdsec.sh --from <tarfile>`.

### CI-built artifacts

If you prefer automation, enable the [`FreeBSD Package Matrix`](.github/workflows/build-freebsd16.yml) workflow in your fork. It rebuilds the script-only `pfSense-pkg-crowdsec` port inside a supported FreeBSD 15.0 VM, publishes a native `freebsd-15-amd64.tar`, and then repacks the upstream `freebsd-16-amd64.tar` release bundle with that rebuilt `NO_ARCH` package so the latest fixes are available for pfSense 25.11 / FreeBSD 16 as well. When you cut a GitHub Release, the workflow automatically attaches both tarballs alongside the rebuilt `pfSense-pkg-crowdsec-*.pkg` files to the release page.

### Installing with a custom pfSense package

`install-crowdsec.sh` now accepts `--pkg-override-repo <owner/repo>` (and optionally `--pkg-override-release <tag>`, `--pkg-override-url <direct .pkg>`, or `--pkg-override-sha256 <checksum>`) so you can download `pfSense-pkg-crowdsec` from this fork while still fetching the other packages from the upstream release bundle and verifying the override against a published SHA-256.

### Downloading CI logs locally

Run `scripts/fetch-gh-logs.sh [run-id]` to pull the latest (or specified) GitHub Actions logs via the `gh` CLI. Logs are saved under `debug-logs/run-<id>/` and are ignored by git so you can review failures locally without polluting commits.

It provides a basic UI with settings to configure the Security Engine and the Firewall Remediation Component (bouncer).

Three types of configuration are supported:
Expand Down
91 changes: 91 additions & 0 deletions docs/build-install-freebsd16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Building and Installing pfSense-pkg-crowdsec for FreeBSD 16 / pfSense 25.11

This guide describes how to build and install the CrowdSec pfSense package so that it already contains commit `a77ea2c5` ("fix: no working build for 25.11/FreeBSD:16:amd64") from this fork. Follow the steps on a FreeBSD 16 host (for example a pfSense 25.11 development VM) with root access.

## 1. Prepare the builder

```sh
pkg install -y git ca_root_nss pkgconf poudriere-devel
mkdir -p /usr/ports/security
```

*Any FreeBSD 16 environment with the default ports tree layout works; poudriere is optional but pulls in the tools that `make package` expects.*

## 2. Clone this fork and check the required commit

```sh
cd /usr/local/src
git clone https://github.com/crowdsecurity/pfSense-pkg-crowdsec.git crowdsec-pfsense
cd crowdsec-pfsense
git checkout a77ea2c5b223eb621bae29c310a4ff014c19b85f
```

The latest commit adds a guard around `parse_config()` so the package works on FreeBSD 16.

## 3. Stage the port into the local tree

```sh
rsync -a security/pfSense-pkg-crowdsec/ /usr/ports/security/pfSense-pkg-crowdsec/
```

If `/usr/ports` is elsewhere in your build jail, adjust the destination accordingly.

## 4. Build the package for amd64/FreeBSD 16

```sh
cd /usr/ports/security/pfSense-pkg-crowdsec
make clean package
```

The resulting package is placed under `/usr/ports/packages/All/pfSense-pkg-crowdsec-0.1.6.pkg`. Confirm that `pkg info -F` on the artifact lists the `a77ea2c5` commit hash in `+COMPACT_MANIFEST`.

## 5. Assemble a release-style tarball

`install-crowdsec.sh` expects a tarball that contains these files:

- `crowdsec-*.pkg`
- `crowdsec-firewall-bouncer-*.pkg`
- `pfSense-pkg-crowdsec-*.pkg` (the one you just built)

Fetch the dependency packages already published by Netgate/CrowdSec for FreeBSD 16 and build the tarball:

```sh
WORKDIR=/tmp/crowdsec-release
mkdir -p "$WORKDIR"
pkg fetch -d -o "$WORKDIR" crowdsec crowdsec-firewall-bouncer
cd "$WORKDIR/All"
TARBALL=/tmp/freebsd-16-amd64.tar
cp /usr/ports/packages/All/pfSense-pkg-crowdsec-*.pkg .
tar -czf "$TARBALL" crowdsec-*.pkg crowdsec-firewall-bouncer-*.pkg pfSense-pkg-crowdsec-*.pkg
```

The tarball layout now matches the official releases, but it embeds the rebuilt pfSense package from this fork.

## 6. Install on the target firewall

1. Copy the tarball to the pfSense appliance:

```sh
scp /tmp/freebsd-16-amd64.tar root@<firewall>:/root/
```

2. On the firewall, run the bundled installer script in this repo (use the `--from` option to skip the GitHub download):

```sh
pfSense# pkg install -y git
pfSense# git clone https://github.com/crowdsecurity/pfSense-pkg-crowdsec.git /root/pfSense-pkg-crowdsec
pfSense# cd /root/pfSense-pkg-crowdsec
pfSense# sh install-crowdsec.sh --from /root/freebsd-16-amd64.tar
```

3. Accept the prompts. The script stops the previous services, installs the three packages in dependency order, and restarts CrowdSec only after the pfSense plugin configures aliases.

## 7. Verification

```sh
pkg info pfSense-pkg-crowdsec | grep Version
grep parse_config /usr/local/pkg/crowdsec.inc
service crowdsec status
```

You should see version `0.1.6` (or higher) and the guarded `parse_config()` logic from commit `a77ea2c5`. CrowdSec should be running, and the UI (Services ➝ CrowdSec) will show the updated build.
Loading