├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── build ├── arm.sh ├── audit.sh ├── base.sh ├── boot.sh ├── chroot.sh ├── clean.sh ├── clone.sh ├── common.sh ├── compress.sh ├── confirm.sh ├── connect.sh ├── core.sh ├── distfiles.sh ├── download.sh ├── dvd.sh ├── fingerprint.sh ├── info.sh ├── kernel.sh ├── list.sh ├── make.conf.sh ├── nano.sh ├── options.sh ├── packages.sh ├── plugins.sh ├── ports.sh ├── prefetch.sh ├── print.sh ├── rebase.sh ├── release.sh ├── rename.sh ├── serial.sh ├── sign.sh ├── skim.sh ├── sync.sh ├── test.sh ├── tests.sh ├── update.sh ├── upload.sh ├── verify.sh ├── vga.sh ├── vm.sh └── xtools.sh ├── composite ├── custom.sh ├── distribution.sh ├── factory.sh ├── hotfix.sh ├── nightly.sh ├── pkgver.sh └── watch.sh ├── config └── 25.1 │ ├── SMP │ ├── SMP-ARM │ ├── aux.conf │ ├── base.obsolete.amd64 │ ├── base.plist.amd64 │ ├── build.conf │ ├── extras.conf │ ├── kernel.debug │ ├── kernel.default │ ├── make.conf │ ├── plugins.conf │ ├── ports.conf │ ├── skim.conf │ └── src.conf ├── device ├── A10.conf ├── ARM64.conf ├── R4S.conf ├── ROCKPRO64.conf └── RPI.conf └── scripts ├── parse_ports_log.py ├── pkg_fingerprint.sh └── pkg_sign.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /config/*/build.conf.local 2 | /config/*/plugins.conf.local 3 | /config/*/repo.key 4 | /config/*/repo.pub 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2025 Franco Fichtner 2 | Copyright (c) 2015-2017 The FreeBSD Foundation 3 | Copyright (c) 2004-2011 Scott Ullrich 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-2025 Franco Fichtner 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions 5 | # are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | # SUCH DAMAGE. 25 | 26 | STEPS= audit arm base boot chroot clean clone compress confirm \ 27 | connect core distfiles download dvd fingerprint info \ 28 | kernel list make.conf nano options packages plugins ports \ 29 | prefetch print rebase release rename serial sign skim \ 30 | sync test tests update upload verify vga vm xtools 31 | SCRIPTS= custom distribution factory hotfix nightly pkgver watch 32 | 33 | .PHONY: ${STEPS} ${SCRIPTS} 34 | 35 | PAGER?= less 36 | 37 | .MAKE.JOB.PREFIX?= # tampers with some of our make invokes 38 | 39 | all: 40 | @cat ${.CURDIR}/README.md | ${PAGER} 41 | 42 | lint-steps: 43 | .for STEP in common ${STEPS} 44 | @sh -n ${.CURDIR}/build/${STEP}.sh 45 | .endfor 46 | 47 | lint-composite: 48 | .for SCRIPT in ${SCRIPTS} 49 | @sh -n ${.CURDIR}/composite/${SCRIPT}.sh 50 | .endfor 51 | 52 | lint: lint-steps lint-composite 53 | 54 | # Special vars to load early build.conf settings: 55 | 56 | ROOTDIR?= /usr 57 | 58 | TOOLSDIR?= ${ROOTDIR}/tools 59 | TOOLSBRANCH?= master 60 | 61 | _OS!= uname -r 62 | _OS:= ${_OS:C/-.*//} 63 | 64 | .if defined(CONFIGDIR) 65 | _CONFIGDIR= ${CONFIGDIR} 66 | .elif defined(SETTINGS) 67 | _CONFIGDIR= ${TOOLSDIR}/config/${SETTINGS} 68 | .elif !defined(CONFIGDIR) 69 | __CONFIGDIR!= find -s ${TOOLSDIR}/config -name "build.conf" -type f 70 | .for DIR in ${__CONFIGDIR} 71 | . if exists(${DIR}) && empty(_CONFIGDIR) 72 | _CONFIGOS!= grep '^OS?*=' ${DIR} 73 | . if ${_CONFIGOS:[2]} == ${_OS} 74 | _CONFIGDIR= ${DIR:C/\/build\.conf$//} 75 | . endif 76 | . endif 77 | .endfor 78 | .endif 79 | 80 | .if empty(_CONFIGDIR) 81 | .error Found no configuration matching OS version "${_OS}" 82 | .endif 83 | 84 | .-include "${_CONFIGDIR}/build.conf.local" 85 | .include "${_CONFIGDIR}/build.conf" 86 | 87 | _ARCH!= uname -p 88 | _VERSION!= date '+%Y%m%d%H%M' 89 | 90 | # Bootstrap the build options if not set: 91 | 92 | ABI?= ${_CONFIGDIR:C/^.*\///} 93 | ADDITIONS?= # empty 94 | ARCH?= ${_ARCH} 95 | COMSPEED?= 115200 96 | DEBUG?= # empty 97 | DEVICE?= A10 98 | KERNEL?= SMP 99 | NAME?= OPNsense 100 | SUFFIX?= # empty 101 | TESTS?= # empty 102 | TYPE?= ${NAME:tl} 103 | UEFI?= arm dvd serial vga vm 104 | VERSION?= ${_VERSION} 105 | ZFS?= # empty 106 | 107 | GITBASE?= https://github.com/opnsense 108 | MIRRORS?= https://opnsense.c0urier.net \ 109 | https://mirrors.nycbug.org/pub/opnsense \ 110 | https://mirror.wdc1.us.leaseweb.net/opnsense \ 111 | https://mirror.sfo12.us.leaseweb.net/opnsense \ 112 | https://mirror.fra10.de.leaseweb.net/opnsense \ 113 | https://mirror.ams1.nl.leaseweb.net/opnsense 114 | SERVER?= user@does.not.exist 115 | UPLOADDIR?= . 116 | 117 | STAGEDIRPREFIX?=/usr/obj 118 | 119 | EXTRABRANCH?= # empty 120 | 121 | COREBRANCH?= stable/${ABI} 122 | COREVERSION?= # empty 123 | COREDIR?= ${ROOTDIR}/core 124 | COREENV?= CORE_PHP=${PHP} CORE_ABI=${ABI} CORE_PYTHON=${PYTHON} 125 | 126 | PLUGINSBRANCH?= stable/${ABI} 127 | PLUGINSDIR?= ${ROOTDIR}/plugins 128 | PLUGINSENV?= PLUGIN_PHP=${PHP} PLUGIN_ABI=${ABI} PLUGIN_PYTHON=${PYTHON} 129 | 130 | PORTSBRANCH?= master 131 | PORTSDIR?= ${ROOTDIR}/ports 132 | PORTSENV?= # empty 133 | 134 | PORTSREFURL?= https://git.FreeBSD.org/ports.git 135 | PORTSREFDIR?= ${ROOTDIR}/freebsd-ports 136 | PORTSREFBRANCH?=main 137 | 138 | SRCBRANCH?= stable/${ABI} 139 | SRCDIR?= ${ROOTDIR}/src 140 | 141 | # A couple of meta-targets for easy use and ordering: 142 | 143 | kernel ports distfiles: base 144 | .if !empty(TESTS) 145 | base: tests 146 | .endif 147 | audit plugins: ports 148 | core: plugins 149 | packages test: core 150 | arm dvd nano serial vga vm: kernel core 151 | sets: kernel distfiles packages 152 | images: dvd nano serial vga vm 153 | release: dvd nano serial vga 154 | 155 | # Expand target arguments for the script append: 156 | 157 | .for TARGET in ${.TARGETS} 158 | _TARGET= ${TARGET:C/\-.*//} 159 | .if ${_TARGET} != ${TARGET} 160 | .if ${SCRIPTS:M${_TARGET}} 161 | ${_TARGET}_ARGS+= ${TARGET:C/^[^\-]*(\-|\$)//} 162 | .else 163 | ${_TARGET}_ARGS+= ${TARGET:C/^[^\-]*(\-|\$)//:S/,/ /g} 164 | .endif 165 | ${TARGET}: ${_TARGET} 166 | .endif 167 | .endfor 168 | 169 | .if "${VERBOSE}" != "" 170 | VERBOSE_FLAGS= -x 171 | .else 172 | VERBOSE_HIDDEN= @ 173 | .endif 174 | 175 | .for _VERSION in ABI APACHE DEBUG LUA PERL PHP PYTHON RUBY SSL VERSION ZFS 176 | VERSIONS+= PRODUCT_${_VERSION}=${${_VERSION}} 177 | .endfor 178 | 179 | # Expand build steps to launch into the selected 180 | # script with the proper build options set: 181 | 182 | .for STEP in ${STEPS} 183 | ${STEP}: lint-steps 184 | @echo ">>> Executing build step ${STEP} on ${_CONFIGDIR:C/.*\///}" >&2 185 | ${VERBOSE_HIDDEN} cd ${.CURDIR}/build && \ 186 | sh ${VERBOSE_FLAGS} ./${.TARGET}.sh -a ${ARCH} -F ${KERNEL} \ 187 | -n ${NAME} -v "${VERSIONS}" -s ${_CONFIGDIR} \ 188 | -S ${SRCDIR} -P ${PORTSDIR} -p ${PLUGINSDIR} -T ${TOOLSDIR} \ 189 | -C ${COREDIR} -R ${PORTSREFDIR} -t ${TYPE} -k "${PRIVKEY}" \ 190 | -K "${PUBKEY}" -l "${SIGNCHK}" -L "${SIGNCMD}" -d ${DEVICE} \ 191 | -m ${MIRRORS:Ox:[1]} -o "${STAGEDIRPREFIX}" -c ${COMSPEED} \ 192 | -b ${SRCBRANCH} -B ${PORTSBRANCH} -e ${PLUGINSBRANCH} \ 193 | -g ${TOOLSBRANCH} -E ${COREBRANCH} -G ${PORTSREFBRANCH} \ 194 | -H "${COREENV}" -u "${UEFI:tl}" -U "${SUFFIX}" \ 195 | -V "${ADDITIONS}" -O "${GITBASE}" -r "${SERVER}" \ 196 | -h "${PLUGINSENV}" -I "${UPLOADDIR}" -D "${EXTRABRANCH}" \ 197 | -A "${PORTSREFURL}" -J "${PORTSENV}" ${${STEP}_ARGS} 198 | .endfor 199 | 200 | .for SCRIPT in ${SCRIPTS} 201 | ${SCRIPT}: lint-composite 202 | ${VERBOSE_HIDDEN} cd ${.CURDIR} && \ 203 | sh ${VERBOSE_FLAGS} ./composite/${SCRIPT}.sh ${${SCRIPT}_ARGS} 204 | .endfor 205 | 206 | .if "${_OS}" != "${OS}" 207 | .error Expected OS version ${OS} for ${_CONFIGDIR}; to continue anyway set OS=${_OS} 208 | .endif 209 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | About the OPNsense tools 2 | ======================== 3 | 4 | In conjunction with src.git, ports.git, core.git and plugins.git they 5 | create sets, packages and images for the OPNsense project. 6 | 7 | Setting up a build system 8 | ========================= 9 | 10 | Install [FreeBSD](https://www.freebsd.org/) 14.2-RELEASE for amd64 11 | on a machine with at least 40GB of hard disk and at least 8GB of RAM 12 | to successfully build all standard images. All tasks require a root 13 | user. Do the following to grab the repositories (overwriting standard 14 | ports and src): 15 | 16 | # pkg install git 17 | # cd /usr 18 | # git clone https://github.com/opnsense/tools 19 | # cd tools 20 | # make update 21 | 22 | Note that the OPNsense repositories can also be setup in a non-/usr directory 23 | by setting ROOTDIR. For example: 24 | 25 | # mkdir -p /tmp/opnsense 26 | # cd /tmp/opnsense 27 | # git clone https://github.com/opnsense/tools 28 | # cd tools 29 | # env ROOTDIR=/tmp/opnsense make update 30 | 31 | TL;DR 32 | ===== 33 | 34 | # make dvd 35 | 36 | If successful, a dvd image can be found under: 37 | 38 | # make print-IMAGESDIR 39 | 40 | Detailed build steps and options 41 | ================================ 42 | 43 | How to specify build options on the command line 44 | ------------------------------------------------ 45 | 46 | The build is broken down into individual stages: base, 47 | kernel, ports, plugins and core can be built separately and 48 | repeatedly without affecting the other stages. All stages 49 | can be reinvoked and continue building without cleaning the 50 | previous progress. A final stage assembles all five stages 51 | into a target image. 52 | 53 | All build steps are invoked via make(1): 54 | 55 | # make step OPTION="value" 56 | 57 | Available early build options are: 58 | 59 | * SETTINGS: the name of the requested local configuration 60 | * CONFIGDIR: read configuration from other directory and override SETTINGS 61 | (make sure to use an absolute path when specifying) 62 | 63 | Available build options are: 64 | 65 | * ABI: a custom ABI (defaults to SETTINGS) 66 | * ADDITIONS: a list of packages/plugins to add to images 67 | * ARCH: the target architecture if not native 68 | * COMSPEED: serial speed, e.g. "115200" (default) 69 | * DEBUG: build a debug kernel with additional object information 70 | * DEVICE: loads device-specific modifications, e.g. "A10" (default) 71 | * KERNEL: the kernel config to use, e.g. SMP (default) 72 | * MIRRORS: a list of mirrors to prefetch sets from 73 | * NAME: "OPNsense" (default) 74 | * PRIVKEY: the private key for signing sets 75 | * PUBKEY: the public key for signing sets 76 | * SUFFIX: the suffix of top package name (default is empty) 77 | * TYPE: the base name of the top package to be installed 78 | * UEFI: use amd64 hybrid images for said images, e.g. "vga vm" 79 | * VERSION: a version tag (if applicable) 80 | * ZFS: ZFS pool name to create for VM images, e.g. "zpool" 81 | 82 | How to specify build options via configuration file 83 | --------------------------------------------------- 84 | 85 | The configuration file is required at "CONFIGDIR/build.conf". 86 | Its contents can be modified to adapt a non-standard build environment 87 | and to avoid excessive Makefile arguments. 88 | 89 | A local override exists as "CONFIGDIR/build.conf.local" and is 90 | parsed first to allow more flexible overrides. Use with care. 91 | 92 | How to run individual or composite build steps 93 | ---------------------------------------------- 94 | 95 | Kernel, base, packages and release sets are stored under: 96 | 97 | # make print-SETSDIR 98 | 99 | All final images are stored under: 100 | 101 | # make print-IMAGESDIR 102 | 103 | Build the userland binaries, bootloader and administrative files: 104 | 105 | # make base 106 | 107 | Build the kernel and loadable kernel modules: 108 | 109 | # make kernel 110 | 111 | Build all the third-party ports: 112 | 113 | # make ports 114 | 115 | Build additional plugins if needed: 116 | 117 | # make plugins 118 | 119 | Wrap up our core as a package: 120 | 121 | # make core 122 | 123 | A dvd live image is created using: 124 | 125 | # make dvd 126 | 127 | A serial memstick live image is created using: 128 | 129 | # make serial 130 | 131 | A vga memstick live image is created using: 132 | 133 | # make vga 134 | 135 | A flash card full disk image is created using: 136 | 137 | # make nano 138 | 139 | A virtual machine full disk image is created using: 140 | 141 | # make vm 142 | 143 | A special embedded device image based on vm variety: 144 | 145 | # make factory 146 | 147 | Release sets can be built as follows although the result is 148 | an unpredictable set of images depending on the previous 149 | build states: 150 | 151 | # make release 152 | 153 | However, the release target is necessary for the following 154 | target which includes sanity checks, proper clearing of the 155 | images directory and core package version alignment: 156 | 157 | # make distribution 158 | 159 | Cross-building for other architecures 160 | ------------------------------------- 161 | 162 | This feature is currently experimental and requires installation 163 | of packages for cross building / user mode emulation and additional 164 | boot files to be installed as prompted by the build system. 165 | 166 | A cross-build on the operating system sources is executed by 167 | specifying the target architecture and custom kernel: 168 | 169 | # make base kernel DEVICE=BANANAPI 170 | 171 | In order to speed up building of using an emulated packages build, 172 | the xtools set can be created like so: 173 | 174 | # make xtools DEVICE=BANANAPI 175 | 176 | The xtools set is then used during the packages build similar to 177 | the distfiles set. 178 | 179 | # make packages DEVICE=BANANAPI 180 | 181 | The final image is built using: 182 | 183 | # make arm- DEVICE=BANANAPI 184 | 185 | Currently available device are: BANANAPI and RPI2. 186 | 187 | About other scripts and tweaks 188 | ============================== 189 | 190 | Device-specific settings 191 | ------------------------ 192 | 193 | Device-specific settings can be found and added in the 194 | device/ directory. Of special interest are hooks into 195 | the build process for required non-default settings for 196 | image builds. The .conf files are shell scripts that can 197 | define hooks in the form of e.g.: 198 | 199 | serial_hook() 200 | { 201 | # ${1} is the target file system root 202 | touch ${1}/my_custom_file 203 | } 204 | 205 | These hooks are available for all image types, namely 206 | dvd, nano, serial, vga and vm. Device-specific hooks 207 | are loaded after config-specific hooks and both of them 208 | can coexist in a given build. 209 | 210 | Updating the code repositories 211 | ------------------------------ 212 | 213 | Updating all or individual repositories can be done as follows: 214 | 215 | # make update[-[,...]] [VERSION=git.tag] 216 | 217 | Available update options are: core, plugins, ports, portsref, src, tools 218 | 219 | VERSION can be used to update to the matching git tag instead of HEAD. 220 | 221 | Regression tests and ports audit 222 | -------------------------------- 223 | 224 | Before building images, you can run the regression tests 225 | to check the integrity of your core.git modifications plus 226 | generate output for the style checker: 227 | 228 | # make test 229 | 230 | To check the binary packages from ports against the upstream 231 | vulnerability database run the following: 232 | 233 | # make audit 234 | 235 | Advanced package builds 236 | ----------------------- 237 | 238 | Package sets ready for web server deployment are automatically 239 | generated and modified by ports, plugins and core steps. The 240 | build automatically caches temporary build dependencies to avoid 241 | spurious rebuilds. These packages are later discarded to provide 242 | a slim runtime set only. 243 | 244 | If signing keys are available, the packages set will be signed 245 | twice, first embedded into repository metadata (inside) and 246 | then again as a flat file (outside) to ensure integrity. 247 | 248 | For faster ports building it may be of use to cache all distribution 249 | files before running the actual build: 250 | 251 | # make distfiles 252 | 253 | For targeted rebuilding of already built packages the following 254 | works: 255 | 256 | # make ports-[,...] 257 | # make plugins-[,...] 258 | # make core-[,...] 259 | 260 | Please note that reissuing ports builds will clear plugins and 261 | core progress. However, following option apply to PORTSENV: 262 | 263 | * BATCH=no Developer mode with shell after each build failure 264 | * DEPEND=no Do not tamper with plugins or core packages 265 | * MISMATCH=no Rebuild packages that have a version mismatch 266 | * PRUNE=no Do not check ports integrity prior to rebuild 267 | 268 | The defaults for these ports options are set to "yes". A sample 269 | invoke is as follows: 270 | 271 | # make ports-curl PORTSENV="DEPEND=no PRUNE=no" 272 | 273 | Both ports and plugins builds allow to override the current list 274 | derived from their respective configuration files, i.e.: 275 | 276 | # make ports PORTSLIST="security/openssl" 277 | # make plugins PLUGINSLIST="devel/debug" 278 | 279 | Acquiring precompiled sets from the mirrors or another local directory 280 | --------------------------------------------------------------------- 281 | 282 | Compiled sets can be prefetched from a mirror if they exist, 283 | while removing any previously available set: 284 | 285 | # make prefetch-