Tag Archives: server

FreeBSD and Poudriere in High Security Environments

Most of the time FreeBSD systems are used with wide open connection to the Internet along with fully working DNS that resolves anything the Root Servers resolve … but FreeBSD – besides being used as SONY PlayStation gaming systems or Netflix storage layer.

Its also used in high security environments without any external DNS access or direct Internet connection to the outside World … yet the security patches are fetched and applied and custom PKGBASE and/or Poudriere systems build base system/packages while fetching them from the Internet over some dedicated proxy.

Many people will not read entire article so I will point that in the beginning – that I am really grateful to Mariusz Zaborski (oshogbo) for his help with this one – without his help – it just would not happen.

By default FreeBSD does not work well in such environments … in this article we will configure FreeBSD to make everything work as needed.

The Table of Contents is as follows.

  • FreeBSD and Poudriere in High Security Environments
  • Example Proxy Configuration
  • Physical (or Virtual) FreeBSD Host
    • pkg(8)
    • FreeBSD Ports Tree
    • Proxy on the Fly
    • Back to the PKGBASE
  • Poudriere in Proxy World
    • Basic Poudriere Setup
    • Important Poudriere Config Part

Example Proxy Configuration

For completeness I will add Squid configuration used here – so that all information will be available.

proxy # grep '^[^#]' /usr/local/etc/squid/squid.conf
http_port 127.0.0.1:3128
http_port 10.0.0.41:3128
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
acl localnet src 127.0.0.1
acl localnet src 10.0.0.0/8     # RFC 1918 local private network (LAN)
acl localnet src 172.16.0.0/12  # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
http_access allow localnet
http_access allow localhost
http_access deny all
visible_hostname proxy.xyz
acl custom-local dstdomain .custom.xyz
cache_peer 10.0.0.42 parent 3128 0 no-query default name=weathertop
cache_peer_domain 10.0.0.43 !.xyz
never_direct deny custom-local
never_direct allow all
cache_dir ufs /var/local/squid/cache 50 16 256
coredump_dir /var/local/squid/cache
access_log stdio:/var/local/log/squid/access.log
cache_store_log stdio:/var/local/log/squid/store.log
cache_log /var/local/log/squid/cache.log
refresh_pattern ^ftp:          1440 20% 10080
refresh_pattern ^gopher:       1440  0%  1440
refresh_pattern -i (/cgi-bin/|\?) 0  0%     0
refresh_pattern .                 0 20%  4320
email_err_data off

Now we will configure a FreeBSD host to use it properly.

Physical (or Virtual) FreeBSD Host

For a start we will make pkg(8) work with our proxy system.

pkg(8)

I installed that FreeBSD 15.0-RELEASE system with PKGBASE way – Brave New PKGBASE World – described in details here. With offline install using PKGBASE packages from the install disc1.iso medium.

That means the pkg(8) is already bootstrapped … we will turn that ‘OFF’ for a moment.

test # pkg info
FreeBSD-acct-15.0              System resource accounting
FreeBSD-acpi-15.0              Advanced Configuration and Power Interface (ACPI) utilities
FreeBSD-apm-15.0               Intel / Microsoft APM BIOS utility
(...)
FreeBSD-zlib-lib32-15.0        DEFLATE (gzip) data compression library (32-bit libraries)
FreeBSD-zoneinfo-15.0          Timezone database
pkg-2.4.2                      Package manager

test # mv /var/db/pkg /var/db/pkg.BCK
test # mv /usr/local  /usr/local.BCK

Now if you would like to bootstrap pkg(8) it will fail.

test # pkg
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly, please wait...
pkg: Error fetching https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/Latest/pkg.pkg: Transient resolver failure
A pre-built version of pkg could not be found for your system.
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0, please wait...
pkg: Error fetching https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/Latest/pkg.pkg: Transient resolver failure
A pre-built version of pkg could not be found for your system.

Now we will export(1) needed proxy setting into environment.

test # export HTTP_PROXY="http://10.0.0.41:3128" 

test # export HTTPS_PROXY="http://10.0.0.41:3128"

test # export FTP_PROXY="http://10.0.0.41:3128"

test # env | grep -i proxy
HTTP_PROXY=http://10.0.0.41:3128
HTTPS_PROXY=http://10.0.0.41:3128
FTP_PROXY=http://10.0.0.41:3128

If you want to make it permanent for the default sh(1) shell then do this.

test # cat < /etc/profile.d/proxy.sh
export HTTP_PROXY=http://10.0.0.41:3128
export HTTPS_PROXY=http://10.0.0.41:3128
export FTP_PROXY=http://10.0.0.41:3128
EOF

Now with each new login these proxy settings will be available.

Lets try with pkg(8) again.

test # pkg info
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
Installing pkg-2.4.2...
Extracting pkg-2.4.2: 100%
pkg-2.4.2                      Package manager

The pkg(8) has now bootstrap completed and will work, right? Right?

test # pkg update
Updating FreeBSD-ports repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports'
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports
Updating FreeBSD-ports-kmods repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports-kmods'
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports-kmods
Error updating repositories!

Small modification is needed. One need to remove pkg+ prefix from all url: paths and to switch mirror_type: from srv to none. Then it will work.

Now … the reason why FreeBSD uses the pkg+ prefix is this:

  • pkg+https:// tells pkg(8) to use libpkg internal HTTP/HTTPS fetcher.
  • https:// tells pkg(8) to use external fetcher – usually with FreeBSD fetch(1) tool.

Now … the needed changes.

test # \
  grep '^[^#]' /etc/pkg/FreeBSD.conf \
    | sed -e 's.pkg+..g' \
          -e 's."srv"."none".g' \
          -e 's.enabled: no.enabled: yes.g' \
    > /root/FreeBSD.conf 

The diff(1) for that change is below.

root # diff -u /etc/pkg/FreeBSD.conf /root/FreeBSD.conf 
--- /etc/pkg/FreeBSD.conf  2025-11-28 00:00:00.000000000 +0000
+++ /root/FreeBSD.conf     2026-01-07 00:11:41.534051000 +0000
@@ -10,23 +10,23 @@
 #
 
 FreeBSD-ports: {
-  url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
-  mirror_type: "srv",
+  url: "https://pkg.FreeBSD.org/${ABI}/quarterly",
+  mirror_type: "none",
   signature_type: "fingerprints",
   fingerprints: "/usr/share/keys/pkg",
   enabled: yes
 }
 FreeBSD-ports-kmods: {
-  url: "pkg+https://pkg.FreeBSD.org/${ABI}/kmods_quarterly_${VERSION_MINOR}",
-  mirror_type: "srv",
+  url: "https://pkg.FreeBSD.org/${ABI}/kmods_quarterly_${VERSION_MINOR}",
+  mirror_type: "none",
   signature_type: "fingerprints",
   fingerprints: "/usr/share/keys/pkg",
   enabled: yes
 }
 FreeBSD-base: {
-  url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}",
-  mirror_type: "srv",
+  url: "https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}",
+  mirror_type: "none",
   signature_type: "fingerprints",
   fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
-  enabled: no
+  enabled: yes
 }

Now – lets leave the original /etc/pkg/FreeBSD.conf unmodified and create /usr/local/etc/pkg/repos/FreeBSD.conf that will override the defaults.

test # mkdir -pv /usr/local/etc/pkg/repos
/usr/local/etc/pkg
/usr/local/etc/pkg/repos

test # cp /root/FreeBSD.conf /usr/local/etc/pkg/repos/

Now that pkg(8) should work well over proxy.

test # pkg update 
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB   3.6MB/s    00:03    
Processing entries: 100%
FreeBSD-ports repository update completed. 36390 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   31 KiB  31.3kB/s    00:01    
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 204 packages processed.
Updating FreeBSD-base repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   80 KiB  81.5kB/s    00:01    
Processing entries: 100%
FreeBSD-base repository update completed. 496 packages processed.

Lets try to actually install any software.

test # pkg install lsblk beadm 
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
The following 2 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        beadm: 1.3.5_1 [FreeBSD-ports]
        lsblk: 4.0 [FreeBSD-ports]
        gitup: 1.0 [FreeBSD-ports]

Number of packages to be installed: 3

18 KiB to be downloaded.

Proceed with this action? [y/N]: y
[1/3] Fetching lsblk-4.0~3110a4bb46.pkg: 100%    7 KiB   7.2kB/s    00:01    
[2/3] Fetching beadm-1.3.5_1~53f06720d4.pkg: 100%   11 KiB  11.0kB/s    00:01    
[3/3] Fetching gitup-1.0~2c88a1f1f1.pkg: 100%   36 KiB  37.0kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/3] Installing beadm-1.3.5_1...
[1/3] Extracting beadm-1.3.5_1: 100%
[2/3] Installing lsblk-4.0...
[2/3] Extracting lsblk-4.0: 100%
[3/3] Installing gitup-1.0...
[3/3] Extracting gitup-1.0: 100%

test # lsblk -d
DEVICE SIZE MODEL
nda0    10G bhyve-NVMe
-       10G TOTAL SYSTEM STORAGE

Works.

If for some reason the above method will not work – you may also configure proxy server within the pkg(8) config /usr/local/etc/pkg.conf file.

test # tail -5 /usr/local/etc/pkg.conf
PKG_ENV {
  HTTP_PROXY: "http://10.0.0.41:3128"
  HTTPS_PROXY: "https://10.0.0.41:3128"
  FTP_PROXY: "http://10.0.0.41:3128"
}

These settings will also override any ‘system’ settings we set previously in the /etc/profile.d/proxy.sh file.

FreeBSD Ports Tree

We already installed gitup tool that will allow us to update the FreeBSD Ports tree easily.

Its default config is more then enought.

test # grep -m 1 -A 6 ports /usr/local/etc/gitup.conf
        "ports" : {
                "repository_path"  : "/ports.git",
                "branch"           : "main",
                "target_directory" : "/usr/ports",
                "ignores"          : [],
        },

Lets try fetching the FreeBSD Ports tree now.

test # gitup ports
# Host: git.freebsd.org
# Port: 443
# Proxy Host: 10.0.0.41
# Proxy Port: 3128
# Repository Path: /ports.git
# Target Directory: /usr/ports
# Want: 284813ec0382a2bfe5b2e74a3081a67599d3155d
# Branch: main
# Action: clone
  75 MB in 0m25s, 4614 kB/s now 
 + /usr/ports/.arcconfig
 + /usr/ports/.gitignore
 + /usr/ports/.hooks/pre-commit
(...)
 + /usr/ports/x11/zutty/Makefile
 + /usr/ports/x11/zutty/distinfo
 + /usr/ports/x11/zutty/pkg-descr
#
# Please review the following file(s) for important changes.
#       /usr/ports/UPDATING
#       /usr/ports/mail/dspam/files/UPDATING
#
# Done.

Seems to work.

To now update the FreeBSD Ports tree run gitup(1) command again.

test # gitup ports
# Scanning local repository...
# Host: git.freebsd.org
# Port: 443
# Proxy Host: 10.0.0.41
# Proxy Port: 3128
# Repository Path: /ports.git
# Target Directory: /usr/ports
# Have: 284813ec0382a2bfe5b2e74a3081a67599d3155d
# Want: 7b2f3c4f484b1634066997a91836554608c72c48
# Branch: main
# Action: pull
 * /usr/ports/lang/spidermonkey115/Makefile
 * /usr/ports/lang/spidermonkey115/distinfo
 * /usr/ports/lang/spidermonkey140/Makefile
 * /usr/ports/lang/spidermonkey140/distinfo
# Done.

If for some reason You will find gitup(1) or git(1) does not work – you may always configure system wide proxy as follows.

test # git config --system http.proxy http://10.0.0.41:3128

That would help.

Proxy on the Fly

If for some reason You will need to force the proxy settings for a single command – then use something like that below.

test # \
  env HTTP_PROXY="http://10.0.0.41:3128"  \
      HTTPS_PROXY="http://10.0.0.41:3128" \
      FTP_PROXY="http://10.0.0.41:3128" 
    command ...

Back to the PKGBASE

Now – lets bring back our original pkg(8) config – we may ‘keep’ the current ‘test’ bootstrap if needed with .CUSTOM suffix.

test # mv /usr/local  /usr/local.CUSTOM
test # mv /var/db/pkg /var/db/pkg.CUSTOM

test # mv /usr/local.BCK  /usr/local
test # mv /var/db/pkg.BCK /var/db/pkg

Now the ‘original’ pkg(8) config that keeps PKGBASE information works again.

test # pkg info | (head -3 ;echo '(...)'; tail -3)
FreeBSD-acct-15.0              System resource accounting
FreeBSD-acpi-15.0              Advanced Configuration and Power Interface (ACPI) utilities
FreeBSD-apm-15.0               Intel / Microsoft APM BIOS utility
(...)
FreeBSD-zlib-lib32-15.0        DEFLATE (gzip) data compression library (32-bit libraries)
FreeBSD-zoneinfo-15.0          Timezone database
pkg-2.4.2                      Package manager

But when we will now try to update the pkg(8) repositories it will fail … why?

test # pkg update
Updating FreeBSD-ports repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports'
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports
Updating FreeBSD-ports-kmods repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports-kmods'
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports-kmods
Error updating repositories!

Its because our config override was placed in /usr/local path … and we just wiped that away.

Copy working proxy config again then.

test # mkdir -pv /usr/local/etc/pkg/repos
/usr/local/etc/pkg
/usr/local/etc/pkg/repos

test # cp /root/FreeBSD.conf /usr/local/etc/pkg/repos/

Now update will work again.

test # pkg update
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB   5.4MB/s    00:02    
Processing entries: 100%
FreeBSD-ports repository update completed. 36390 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   31 KiB  31.3kB/s    00:01    
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 204 packages processed.
Updating FreeBSD-base repository catalogue...
pkg: Repository FreeBSD-base has a wrong packagesite, need to re-create database
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   80 KiB  81.5kB/s    00:01    
Processing entries: 100%
FreeBSD-base repository update completed. 496 packages processed.
All repositories are up to date.

You can even do PKGBASE upgrade if wanted.

test # pkg upgrade
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
Checking for upgrades (4 candidates): 100%
Processing candidates (4 candidates): 100%
The following 4 package(s) will be affected (of 0 checked):

Installed packages to be UPGRADED:
        FreeBSD-kernel-generic: 15.0 -> 15.0p1 [FreeBSD-base]
        FreeBSD-rescue: 15.0 -> 15.0p1 [FreeBSD-base]
        FreeBSD-runtime: 15.0 -> 15.0p1 [FreeBSD-base]
        FreeBSD-utilities: 15.0 -> 15.0p1 [FreeBSD-base]

Number of packages to be upgraded: 4

62 MiB to be downloaded.

Proceed with this action? [y/N]: 

Poudriere in Proxy World

Now to another deeper level – like in Inception (2010) movie – the Poudriere package building harvester.

If you want to check more on the Poudriere itself you can check these:

Now – first we need to install poudriere-devel package as it has the latest features.

test # pkg install poudriere-devel ccache4 git nginx
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
The following 28 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        brotli: 1.1.0,1 [FreeBSD-ports]
        ccache4: 4.10.2_1 [FreeBSD-ports]
        curl: 8.16.0 [FreeBSD-ports]
        expat: 2.7.3 [FreeBSD-ports]
        gettext-runtime: 0.23.1 [FreeBSD-ports]
        git: 2.51.0 [FreeBSD-ports]
        indexinfo: 0.3.1_1 [FreeBSD-ports]
        libffi: 3.5.1 [FreeBSD-ports]
        libidn2: 2.3.8 [FreeBSD-ports]
        libnghttp2: 1.67.0 [FreeBSD-ports]
        libpsl: 0.21.5_2 [FreeBSD-ports]
        libssh2: 1.11.1,3 [FreeBSD-ports]
        libunistring: 1.4.1 [FreeBSD-ports]
        mpdecimal: 4.0.1 [FreeBSD-ports]
        nginx: 1.28.0_3,3 [FreeBSD-ports]
        p5-Authen-SASL: 2.1900 [FreeBSD-ports]
        p5-Crypt-URandom: 0.54 [FreeBSD-ports]
        p5-Digest-HMAC: 1.05 [FreeBSD-ports]
        p5-Error: 0.17030 [FreeBSD-ports]
        p5-IO-Socket-SSL: 2.095 [FreeBSD-ports]
        p5-MIME-Base32: 1.303 [FreeBSD-ports]
        p5-MIME-Base64: 3.16 [FreeBSD-ports]
        p5-Mozilla-CA: 20250602 [FreeBSD-ports]
        p5-Net-SSLeay: 1.94 [FreeBSD-ports]
        p5-URI: 5.32_1 [FreeBSD-ports]
        poudriere-devel: 3.4.99.20251213 [FreeBSD-ports]
        python311: 3.11.14 [FreeBSD-ports]
        readline: 8.2.13_2 [FreeBSD-ports]

Number of packages to be installed: 28

The process will require 283 MiB more space.
41 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/25] Fetching mpdecimal-4.0.1~f774e949d8.pkg: 100%  157 KiB 160.5kB/s    00:01    
(...)
[28/28] Installing git-2.51.0...
===> Creating groups
Creating group 'git_daemon' with gid '964'
===> Creating users
Creating user 'git_daemon' with uid '964'
[28/28] Extracting git-2.51.0: 100%

Basic Poudriere Setup

We will now setup some basic Poudriere setup.

test # export SSL=/usr/local/etc/ssl

test # mkdir -p \
              /usr/ports/distfiles \
              ${SSL}/keys \
              ${SSL}/certs

test # chmod 0600 ${SSL}/keys

test # openssl genrsa -out ${SSL}/keys/poudriere.key 4096

test # openssl rsa \
              -in  ${SSL}/keys/poudriere.key -pubout \
              -out ${SSL}/certs/poudriere.cert

test # mkdir /var/ccache

test # cat < /usr/local/etc/poudriere.conf
ZPOOL=zroot
FREEBSD_HOST=ftp://ftp.freebsd.org
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=/usr/local/poudriere/data
DISTFILES_CACHE=/usr/ports/distfiles
CCACHE_DIR=/var/ccache
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key
URL_BASE=http://0.0.0.0/
USE_TMPFS=no
TMPFS_LIMIT=12
MAX_MEMORY=12
PARALLEL_JOBS=4
PREPARE_PARALLEL_JOBS=4
MAX_FILES=4096
KEEP_OLD_PACKAGES=yes
KEEP_OLD_PACKAGES_COUNT=3
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
RESTRICT_NETWORKING=no
PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
PACKAGE_FETCH_BRANCH="latest"
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"
EOF

test # mkdir -p /usr/local/poudriere/data/logs/bulk

test # ln -s \
              /usr/local/etc/ssl/certs/poudriere.cert \
              /usr/local/poudriere/data/logs/bulk/poudriere.cert

test # cat < /usr/local/etc/poudriere.d/make.conf
# general
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes

# ccache(1)
WITH_CCACHE_BUILD=yes

# ports options
FORCE_MAKE_JOBS=yes
MAKE_JOBS_UNSAFE=yes
MAKE_JOBS_NUMBER=8
EOF

test # sed -i '' -E 's|text/plain[\t\ ]*txt|text/plain txt log|g' /usr/local/etc/nginx/mime.types

test # cat < /usr/local/etc/nginx/nginx.conf
events {
  worker_connections 1024;
}

http {
  include      mime.types;
  default_type application/octet-stream;

  server {
    listen 80 default;
    server_name 0.0.0.0;
    root /usr/local/share/poudriere/html;

    location /data {
      alias /usr/local/poudriere/data/logs/bulk;
      autoindex on;
    }

    location /packages {
      root /usr/local/poudriere/data;
      autoindex on;
    }
  }
}
EOF

test # mkdir /root/.cache

test # ln -sf /var/ccache /root/.cache/ccache

test # cat < /var/ccache/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
hash_dir = false
EOF

Important Poudriere Config Part

The IMPORTANT settings here – to allow Poudriere function properly within proxy environment – are these five lines in the /usr/local/etc/poudriere.conf file.

export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"
PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
PACKAGE_FETCH_BRANCH="latest"

The first three are obvious – and YES – they need the export prefix to work.

The other two are less obvious … and I will show You why in a moment.

We need to create some FreeBSD jail – we will use 14.3-RELEASE as example. Use any version that you will be building packages for.

test # poudriere jail -c -j 14-3-R-amd64 -v 14.3-RELEASE
[00:00:00] Creating 14-3-R-amd64 fs at /usr/local/poudriere/jails/14-3-R-amd64... done
[00:00:00] Using pre-distributed MANIFEST for FreeBSD 14.3-RELEASE amd64
[00:00:00] Fetching base for FreeBSD 14.3-RELEASE amd64
base.txz                                               200 MB 5128 kBps    41s
[00:00:41] Extracting base... done
[00:00:49] Fetching src for FreeBSD 14.3-RELEASE amd64
src.txz                                                206 MB 4828 kBps    44s
[00:01:34] Extracting src... done
[00:01:46] Fetching lib32 for FreeBSD 14.3-RELEASE amd64
lib32.txz                                               60 MB   11 MBps    05s
[00:01:52] Extracting lib32... done
[00:01:54] Cleaning up... done
[00:01:54] Recording filesystem state for clean... done
[00:01:54] Upgrading using http
Looking up update.FreeBSD.org mirrors... none found.
Fetching public key from update.FreeBSD.org... done.
Fetching metadata signature for 14.3-RELEASE from update.FreeBSD.org... done.
Fetching metadata index... done.
Fetching 2 metadata files... done.
Inspecting system... done.
Preparing to download files... done.
Fetching 196 patches.....10....20....30....40....50....60....70....80....90....100....110....120....130....140....150....160....170....180....190... done.
Applying patches... done.
Fetching 40 files... ....10....20....30....40 done.
The following files will be removed as part of updating to
14.3-RELEASE-p7:
/usr/src/contrib/libarchive/libarchive/archive_getdate.c
/usr/src/contrib/libarchive/libarchive/archive_getdate.h
/usr/src/contrib/libarchive/libarchive/test/test_archive_getdate.c
(...)
/usr/src/usr.bin/tar/tests/Makefile
/usr/src/usr.sbin/freebsd-update/freebsd-update.sh
/usr/src/usr.sbin/rtsold/rtsol.c
Installing updates... done.
14.3-RELEASE-p7
[00:03:25] Recording filesystem state for clean... done
[00:03:25] Jail 14-3-R-amd64 14.3-RELEASE-p7 amd64 is ready to be used

test # poudriere jail -l
JAILNAME     VERSION         OSVERSION ARCH  METHOD TIMESTAMP           PATH
14-3-R-amd64 14.3-RELEASE-p7 1403000   amd64 http   2026-01-07 01:33:45 /usr/local/poudriere/jails/14-3-R-amd64

We also need FreeBSD Ports tree … just in a Poudriere way.

test # poudriere ports -c
[00:00:00] Creating default fs at /usr/local/poudriere/ports/default... done
[00:00:00] Cloning the ports tree...
fatal: unable to access 'https://git.FreeBSD.org/ports.git/': Could not resolve host: git.FreeBSD.org
[00:00:45] Error: /usr/local/share/poudriere/ports.sh:303: fail
[00:00:45] Error while creating ports tree, cleaning up.

This is where the dedicated git(1) config is needed as its a bitch and ignores *_PROXY variables πŸ™‚

test # git config --system http.proxy http://10.0.0.41:3128

test # poudriere ports -c
[00:00:00] Creating default fs at /usr/local/poudriere/ports/default... done
[00:00:00] Cloning the ports tree... done

test # poudriere ports -l
PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2026-01-07 01:49:46 /usr/local/poudriere/ports/default

Works.

Now – lets try to actually build something with Poudriere.

We will try two ports that one needs to be actually build (dosunix) and one that is in POSIX sh(1) and does not need building (lsblk).

I will intentionally run first building process with proxy variables disabled like this in the /usr/local/etc/poudriere.conf file:

# PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
# PACKAGE_FETCH_BRANCH="latest"
# export HTTP_PROXY="http://10.0.0.41:3128"
# export HTTPS_PROXY="http://10.0.0.41:3128"
# export FTP_PROXY="http://10.0.0.41:3128"

Here.

test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix

Result is below … and as expected it failed.

test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
[00:00:00] Creating the reference jail... done
[00:00:00] Mounting system devices for 14-3-R-amd64-default
[00:00:00] Stashing existing package repository
[00:00:00] Mounting ccache from: /var/ccache
[00:00:00] Mounting ports from: /usr/local/poudriere/ports/default
[00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default
[00:00:00] Mounting distfiles from: /usr/ports/distfiles
[00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf
/etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf
[00:00:00] Starting jail 14-3-R-amd64-default
Updating /var/run/os-release done.
[00:00:00] Will build as root:wheel (0:0)
[00:00:00] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS
[00:00:00] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no
[00:00:03] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d
[00:00:03] Acquiring build logs lock for 14-3-R-amd64-default... done
[00:00:03] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_01h58m23s
[00:00:03] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_01h58m23s
[00:00:03] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports
[00:00:04] Gathering ports metadata
[00:00:04] Calculating ports order and dependencies
[00:00:04] Sanity checking the repository
[00:00:04] -c specified, cleaning all packages... done
[00:00:04] -C specified, cleaning listed packages
[00:00:04] (-C) Flushing package deletions
[00:00:04] Trimming IGNORED and blacklisted ports
[00:00:04] Package fetch: Looking for missing packages to fetch from pkg+http://pkg.FreeBSD.org/${ABI}/latest
[00:00:04] Package fetch: bootstrapping pkg
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait...
pkg: Attempted to fetch pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/Latest/pkg.pkg
pkg: Attempted to fetch pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/Latest/pkg.txz
pkg: Error: Address family for host not supported
Address resolution failed for http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest.
[00:08:58] Package fetch: Not fetching as remote repository is unavailable.
[00:08:58] pkg bootstrap missing: unable to inspect existing packages, cleaning all packages... done
[00:08:58] Deleting stale symlinks... done
[00:08:58] Deleting empty directories... done
[00:08:58] Unqueueing existing packages
[00:08:58] Unqueueing orphaned build dependencies
[00:08:58] Sanity checking build queue
[00:08:58] [14-3-R-amd64-default] [2026-01-07_01h58m23s] [pkgqueue_sanity_check] Time: 00:08:54
           Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 4
[00:08:58] Recording filesystem state for prepkg... done
[00:08:58] Processing PRIORITY_BOOST
[00:08:58] Building 4 packages using up to 4 builders
[00:08:58] Hit CTRL+t at any time to see build progress and stats
[00:08:58] [01] [00:00:00] Builder starting
[00:08:58] [01] [00:00:00] Builder started
[00:08:58] [01] [00:00:00] Building   ports-mgmt/pkg | pkg-2.5.1
[00:11:56] [01] [00:02:58] Finished   ports-mgmt/pkg | pkg-2.5.1: Failed: fetch
[00:11:56] [01] [00:02:58] Skipping   devel/ccache | ccache-3.7.12_8: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed
[00:11:56] [01] [00:02:58] Skipping   converters/dosunix | dosunix-1.0.14: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed
[00:11:56] [01] [00:02:58] Skipping   sysutils/lsblk | lsblk-4.0: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed
[00:11:57] Stopping up to 4 builders
[00:11:57] Creating pkg repository
[00:11:57] No packages present
[00:11:57] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767751820 via .latest symlink
[00:11:57] Removing old packages
[00:11:57] Failed ports: ports-mgmt/pkg:fetch
[00:11:57] Skipped ports: converters/dosunix devel/ccache sysutils/lsblk
[00:11:57] [14-3-R-amd64-default] [2026-01-07_01h58m23s] [committing] Time: 00:11:53
           Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 1 Skipped: 3 Fetched: 0 Remaining: 0
[00:11:57] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_01h58m23s
[00:11:57] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_01h58m23s
[00:11:57] Cleaning up
[00:11:57] Stopping up to 4 builders
[00:11:57] Unmounting file systems
test # 

Now I will run it again but with proxy setting enabled in the /usr/local/etc/poudriere.conf file like that.

# PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
# PACKAGE_FETCH_BRANCH="latest"
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"

It should work with one small caveat.

test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
[00:00:00] Creating the reference jail... done
[00:00:00] Mounting system devices for 14-3-R-amd64-default
[00:00:00] Stashing existing package repository
[00:00:00] Mounting ccache from: /var/ccache
[00:00:00] Mounting ports from: /usr/local/poudriere/ports/default
[00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default
[00:00:00] Mounting distfiles from: /usr/ports/distfiles
[00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf
/etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf
[00:00:00] Starting jail 14-3-R-amd64-default
Updating /var/run/os-release done.
[00:00:00] Will build as root:wheel (0:0)
[00:00:01] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS
[00:00:01] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no
[00:00:04] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d 
[00:00:04] Acquiring build logs lock for 14-3-R-amd64-default... done
[00:00:04] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_02h13m56s
[00:00:04] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_02h13m56s
[00:00:04] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports
[00:00:04] Gathering ports metadata
[00:00:04] Calculating ports order and dependencies
[00:00:04] Sanity checking the repository
[00:00:04] -c specified, cleaning all packages... done
[00:00:04] -C specified, cleaning listed packages
[00:00:04] (-C) Flushing package deletions
[00:00:04] Trimming IGNORED and blacklisted ports
[00:00:04] Package fetch: Looking for missing packages to fetch from pkg+http://pkg.FreeBSD.org/${ABI}/latest
[00:00:04] Package fetch: bootstrapping pkg
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait...
[14-3-R-amd64-default] Installing pkg-2.5.1...
[14-3-R-amd64-default] Extracting pkg-2.5.1: 100%
Updating Poudriere repository catalogue...
pkg: No SRV record found for the repo 'Poudriere'
[14-3-R-amd64-default] Fetching meta.conf: 100%    179 B   0.2 k/s    00:01    
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository Poudriere
Error updating repositories!
[00:00:29] Package fetch: Not fetching as remote repository is unavailable.
[00:00:29] pkg bootstrap missing: unable to inspect existing packages, cleaning all packages... done
[00:00:29] Deleting stale symlinks... done
[00:00:29] Deleting empty directories... done
[00:00:29] Unqueueing existing packages
[00:00:29] Unqueueing orphaned build dependencies
[00:00:29] Sanity checking build queue
[00:00:29] [14-3-R-amd64-default] [2026-01-07_02h13m56s] [pkgqueue_sanity_check] Time: 00:00:26
           Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 4
[00:00:29] Recording filesystem state for prepkg... done
[00:00:29] Processing PRIORITY_BOOST
[00:00:30] Building 4 packages using up to 4 builders
[00:00:30] Hit CTRL+t at any time to see build progress and stats
[00:00:30] [01] [00:00:00] Builder starting
[00:00:30] [01] [00:00:00] Builder started
[00:00:30] [01] [00:00:00] Building   ports-mgmt/pkg | pkg-2.5.1
[00:02:34] [01] [00:02:04] Finished   ports-mgmt/pkg | pkg-2.5.1: Success
[00:02:34] [02] [00:00:00] Builder starting
[00:02:34] [01] [00:00:00] Building   devel/ccache | ccache-3.7.12_8
[00:02:35] [02] [00:00:01] Builder started
[00:02:35] [02] [00:00:00] Building   sysutils/lsblk | lsblk-4.0
[00:02:36] [02] [00:00:01] Finished   sysutils/lsblk | lsblk-4.0: Success
[00:02:39] [01] [00:00:05] Finished   devel/ccache | ccache-3.7.12_8: Success
[00:02:39] [01] [00:00:00] Building   converters/dosunix | dosunix-1.0.14
[00:02:42] [01] [00:00:03] Finished   converters/dosunix | dosunix-1.0.14: Success
[00:02:42] Stopping up to 4 builders
[00:02:42] Creating pkg repository
[00:02:42] Signing repository with key: /usr/local/etc/ssl/keys/poudriere.key
Creating repository in /tmp/packages: 100%
Packing files for repository: 100%
[00:02:43] Signing pkg bootstrap with method: pubkey
[00:02:43] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767752199 via .latest symlink
[00:02:43] Removing old packages
[00:02:43] Built ports: ports-mgmt/pkg sysutils/lsblk devel/ccache converters/dosunix
[00:02:43] [14-3-R-amd64-default] [2026-01-07_02h13m56s] [committing] Time: 00:02:39
           Queued: 4 Inspected: 0 Ignored: 0 Built: 4 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 0
[00:02:43] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_02h13m56s
[00:02:43] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_02h13m56s
[00:02:43] Cleaning up
[00:02:43] Stopping up to 4 builders
[00:02:43] Unmounting file systems

Also in nice graphical colored form.

The build generally ended successfully – we have our packages available.

test # ls -l /usr/local/poudriere/data/packages/14-3-R-amd64-default/All/
total 6294
-rw-r--r--  1 root wheel  126041 Jan  7 02:16 ccache-3.7.12_8.pkg
-rw-r--r--  1 root wheel    5963 Jan  7 02:16 dosunix-1.0.14.pkg
-rw-r--r--  1 root wheel    6544 Jan  7 02:16 lsblk-4.0.pkg
-rw-r--r--  1 root wheel 6290261 Jan  7 02:16 pkg-2.5.1.pkg

The only errors were these below and they did not broken our build:

(...)
Updating Poudriere repository catalogue...
pkg: No SRV record found for the repo 'Poudriere'
[14-3-R-amd64-default] Fetching meta.conf: 100%    179 B   0.2 k/s    00:01    
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository Poudriere
Error updating repositories!
[00:00:29] Package fetch: Not fetching as remote repository is unavailable.
(...)

To get the idea what is wrong here we need to level up our debugging skill and get our hands dirty with FreeBSD tools like ktrace(8) and kdump(8) to know what is missing.

test # ktrace -di poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
(...)
[00:00:32] [01] [00:00:00] Builder starting
[00:00:33] [01] [00:00:01] Builder started
[00:00:33] [01] [00:00:00] Building   ports-mgmt/pkg | pkg-2.5.1

When You reach this place – just hit [CTRL]+[C] to stop it – its not needed to wait for it.

Now check with kdump(8) the gathered data.

test # kdump | grep -m 5 -C 2 'pkg+' | tail -4
        Poudriere: {
        url: pkg+http://pkg.FreeBSD.org/${ABI}/latest,
        mirror_type: srv
        }

I wanted to show only the part that was important – Of course I did not guessed it like that … just find it with a help of a friend.

Poudriere – on the fly – defines additional repository … and if you did not override it – yes – it will use both pkg+ and srv things that hurt our proxy environment.

This is part of the Poudriere code that is responsible for its generation.

cat >> "${MASTERMNT:?}/etc/pkg/poudriere.conf" <<-EOF
FreeBSD: {
        enabled: no,
        priority: 100
}
FreeBSD-kmods: {
        enabled: no,
        priority: 100
}
FreeBSD-ports: {
        enabled: no,
        priority: 100
}
FreeBSD-ports-kmods: {
        enabled: no,
        priority: 100
}
FreeBSD-base: {
        enabled: no,
        priority: 100
}

Poudriere: {
        url: ${packagesite},
        mirror_type: $(if [ "${packagesite#pkg+}" = "${packagesite}" ]; then echo "none"; else echo "srv"; fi)
}
EOF

So it will generate the ‘broken for proxy’ config like that:

Poudriere: {
        url: pkg+http://pkg.FreeBSD.org/${ABI}/latest,
        mirror_type: srv
}

Looking at the code above you can see the if that checks how the packagesite is defined.

Lets see how Poudriere figures that one out in the code.

test # grep -m 1 packagesite= common.sh
        packagesite="${PACKAGE_FETCH_URL:+${PACKAGE_FETCH_URL}/}${PACKAGE_FETCH_BRANCH}"

So the answer is that we need to set PACKAGE_FETCH_URL and PACKAGE_FETCH_BRANCH in the /usr/local/etc/poudriere.conf file … the ones I commented out to explain all that in details.

So now – with all needed settings enabled at /usr/local/etc/poudriere.conf file … fully working Poudriere build in proxy environment.

PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
PACKAGE_FETCH_BRANCH="latest"
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"

Remember to have the \$ as backslashed as Poudriere is written in POSIX sh(1).

Now the fully working run.

test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
[00:00:00] Creating the reference jail... done
[00:00:00] Mounting system devices for 14-3-R-amd64-default
[00:00:00] Stashing existing package repository
[00:00:00] Mounting ccache from: /var/ccache
[00:00:00] Mounting ports from: /usr/local/poudriere/ports/default
[00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default
[00:00:00] Mounting distfiles from: /usr/ports/distfiles
[00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf
/etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf
[00:00:00] Starting jail 14-3-R-amd64-default
Updating /var/run/os-release done.
[00:00:00] Will build as root:wheel (0:0)
[00:00:00] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS
[00:00:00] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no
[00:00:03] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d 
[00:00:03] Acquiring build logs lock for 14-3-R-amd64-default... done
[00:00:03] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_03h52m21s
[00:00:03] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_03h52m21s
[00:00:03] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports
[00:00:04] Gathering ports metadata
[00:00:04] Calculating ports order and dependencies
[00:00:04] Sanity checking the repository
[00:00:04] -c specified, cleaning all packages... done
[00:00:04] -C specified, cleaning listed packages
[00:00:04] (-C) Flushing package deletions
[00:00:04] Trimming IGNORED and blacklisted ports
[00:00:04] Package fetch: Looking for missing packages to fetch from http://pkg.FreeBSD.org/${ABI}/latest
[00:00:04] Package fetch: bootstrapping pkg
Bootstrapping pkg from http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait...
[14-3-R-amd64-default] Installing pkg-2.5.1...
[14-3-R-amd64-default] Extracting pkg-2.5.1: 100%
Updating Poudriere repository catalogue...
[14-3-R-amd64-default] Fetching meta.conf: 100%    179 B   0.2 k/s    00:01    
[14-3-R-amd64-default] Fetching data: 100%   11 MiB   3.7 M/s    00:03    
Processing entries: 100%
Poudriere repository update completed. 36661 packages processed.
All repositories are up to date.
[00:00:20] Package fetch: Will fetch 3 packages from remote or local pkg cache
Updating database digests format: 100%
The following packages will be fetched:

New packages to be FETCHED:
        ccache: 3.7.12_8 (134 KiB: 91.17% of the 147 KiB to download)
        dosunix: 1.0.14 (6 KiB: 4.04% of the 147 KiB to download)
        lsblk: 4.0 (7 KiB: 4.79% of the 147 KiB to download)

Number of packages to be fetched: 3

147 KiB to be downloaded.
[14-3-R-amd64-default] Fetching ccache-3.7.12_8: 100%  134 KiB 137.3 k/s    00:01    
[14-3-R-amd64-default] Fetching lsblk-4.0: 100%    7 KiB   7.2 k/s    00:01    
[14-3-R-amd64-default] Fetching dosunix-1.0.14: 100%    6 KiB   6.1 k/s    00:01    
[00:00:21] Package fetch: Using cached copy of ccache-3.7.12_8
[00:00:21] Package fetch: Using cached copy of dosunix-1.0.14
[00:00:21] Package fetch: Using cached copy of lsblk-4.0
[00:00:21] Checking packages for incremental rebuild needs
[00:00:21] Deleting stale symlinks... done
[00:00:21] Deleting empty directories... done
[00:00:21] Package fetch: Generating logs for fetched packages
[00:00:21] Unqueueing existing packages
[00:00:21] Unqueueing orphaned build dependencies
[00:00:21] Sanity checking build queue
[00:00:21] [14-3-R-amd64-default] [2026-01-07_03h52m21s] [pkgqueue_sanity_check] Time: 00:00:18
           Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 3 Remaining: 1
[00:00:21] Recording filesystem state for prepkg... done
[00:00:21] Processing PRIORITY_BOOST
[00:00:21] Building 1 packages using up to 1 builders
[00:00:21] Hit CTRL+t at any time to see build progress and stats
[00:00:21] [01] [00:00:00] Builder starting
[00:00:21] [01] [00:00:00] Builder started
[00:00:21] [01] [00:00:00] Building   ports-mgmt/pkg | pkg-2.5.1
[00:02:25] [01] [00:02:04] Finished   ports-mgmt/pkg | pkg-2.5.1: Success
[00:02:25] Stopping up to 1 builders
[00:02:25] Creating pkg repository
[00:02:25] Signing repository with key: /usr/local/etc/ssl/keys/poudriere.key
Creating repository in /tmp/packages: 100%
Packing files for repository: 100%
[00:02:25] Signing pkg bootstrap with method: pubkey
[00:02:25] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767758087 via .latest symlink
[00:02:25] Removing old packages
[00:02:25] Built ports: ports-mgmt/pkg
[00:02:25] Fetched ports: sysutils/lsblk converters/dosunix devel/ccache
[00:02:25] [14-3-R-amd64-default] [2026-01-07_03h52m21s] [committing] Time: 00:02:23
           Queued: 4 Inspected: 0 Ignored: 0 Built: 1 Failed: 0 Skipped: 0 Fetched: 3 Remaining: 0
[00:02:25] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_03h52m21s
[00:02:25] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_03h52m21s
[00:02:25] Cleaning up
[00:02:25] Stopping up to 4 builders
[00:02:25] Unmounting file systems
test # 

… and in the TECHNICOLOR form πŸ™‚

The part that was broken earlier is now fine.

Updating Poudriere repository catalogue...
[14-3-R-amd64-default] Fetching meta.conf: 100%    179 B   0.2 k/s    00:01    
[14-3-R-amd64-default] Fetching data: 100%   11 MiB   3.7 M/s    00:03    
Processing entries: 100%

I believe that concludes this article – let me know if I missed anything.

EOF

ZFS Boot Environments Explained

This article will not be a general ZFS explanation attempt – we will focus on ZFS Boot Environments only. There are a lot of misconceptions and misunderstandings when it comes to them – some people do not know what is inside and outside of ZFS BE – but even worse – some people do not understand them at all.

The Table of Contents for this article is:

  • ZFS Boot Environments Explained
  • What is Included in ZFS BE
  • What Happens with Creation of New ZFS BE
  • Transfer ZFS BE Between Systems
  • Summary

I assume that reader does know what ZFS filesystem concepts and features are – that things like ZFS pool or ZFS dataset are things known to reader … and that a reader can explain differences between ZFS and LVM for example.

What is Included in ZFS BE

This is the first often misunderstood topic … probably because of not understanding the canmount=off ZFS property – you can read more about that in the zfsprops(7) man page.

This is the slide from one of my older ZFS Boot Environments presentationsΒ  – available at https://is.gd/BECTL link – that was held during 2018 NLUUG conference … and the colors are not random … they were prepared that way to give tribute to a country in which NLUUG conference was held – Netherlands.

The idea behind this canmount=off for /var and /usr goes like that:

The /var and /usr ZFS datasets contents are in the ZFS BE – in the zroot/ROOT/default ZFS BE that is created at installer – and the rest like these:

    zroot/tmp
    zroot/usr/home
    zroot/usr/ports
    zroot/usr/src
    zroot/var/audit
    zroot/var/crash
    zroot/var/log
    zroot/var/mail
    zroot/var/tmp

Are EXCLUDED from this ZFS BE.

So by default everything is included in ZFS BE – and if you want to EXCLUDE some parts of /usr or /var – you add needed ZFS datasets for these EXCLUDES.

Below is the default FreeBSD ZFS layout after you select Auto (ZFS) option at the bsdinstall(8) installer.

root@freebsd:~ # zfs set mountpoint=none zroot

root@freebsd:~ # zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
zroot                385M  18.5G    96K  none
zroot/ROOT           383M  18.5G    96K  none
zroot/ROOT/default   383M  18.5G   383M  /
zroot/home            96K  18.5G    96K  /home
zroot/tmp             96K  18.5G    96K  /tmp
zroot/usr            288K  18.5G    96K  /usr
zroot/usr/ports       96K  18.5G    96K  /usr/ports
zroot/usr/src         96K  18.5G    96K  /usr/src
zroot/var            600K  18.5G    96K  /var
zroot/var/audit       96K  18.5G    96K  /var/audit
zroot/var/crash       96K  18.5G    96K  /var/crash
zroot/var/log        120K  18.5G   120K  /var/log
zroot/var/mail        96K  18.5G    96K  /var/mail
zroot/var/tmp         96K  18.5G    96K  /var/tmp

root@freebsd:~ # zfs get canmount
NAME                PROPERTY  VALUE     SOURCE
zroot               canmount  on        default
zroot/ROOT          canmount  on        default
zroot/ROOT/default  canmount  noauto    local
zroot/home          canmount  on        default
zroot/tmp           canmount  on        default
zroot/usr           canmount  off       local
zroot/usr/ports     canmount  on        default
zroot/usr/src       canmount  on        default
zroot/var           canmount  off       local
zroot/var/audit     canmount  on        default
zroot/var/crash     canmount  on        default
zroot/var/log       canmount  on        default
zroot/var/mail      canmount  on        default
zroot/var/tmp       canmount  on        default

The important part here is that both zroot/usr and zroot/var ZFS datasets have the canmount=off ZFS property. That means that the /usr filesystem is NOT kept in the zroot/usr ZFS dataset … its kept inside the zroot/ROOT/default one.

You verify that using oldshool df(1) command like that.

root@freebsd:~ # df -g /usr
Filesystem         1G-blocks Used Avail Capacity  Mounted on
zroot/ROOT/default        18    0    18     2%    /

root@freebsd:~ # df -g /var
Filesystem         1G-blocks Used Avail Capacity  Mounted on
zroot/ROOT/default        18    0    18     2%    /

As You can see both /usr and /var are just directories in the zroot/ROOT/default ZFS dataset. Data is NOT kept in the zroot/usr or zroot/var ZFS datasets … again – because of the canmount=off ZFS property.

Now – the main idea/concept of this FreeBSD default setup is that everything is kept in the zroot/ROOT/default ZFS dataset and all other ZFS dataset are EXCLUDES from it. So zroot/var/audit with canmount=on ZFS property … and exactly the same as for all other ones.

To be honest – to make things brain dead simple I will replace zroot/usr zroot/var ZFS datasets with one that tells exactly what it is used for – with zroot/exclude one – because all the ZFS datasets that will be under it – are EXCLUDED from the ZFS Boot Environment.

root@freebsd:~ # zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
zroot                385M  18.5G    96K  none
zroot/ROOT           383M  18.5G    96K  none
zroot/ROOT/default   383M  18.5G   383M  /
zroot/home            96K  18.5G    96K  /home
zroot/tmp             96K  18.5G    96K  /tmp
zroot/usr            288K  18.5G    96K  /usr
zroot/usr/ports       96K  18.5G    96K  /usr/ports
zroot/usr/src         96K  18.5G    96K  /usr/src
zroot/var            600K  18.5G    96K  /var
zroot/var/audit       96K  18.5G    96K  /var/audit
zroot/var/crash       96K  18.5G    96K  /var/crash
zroot/var/log        120K  18.5G   120K  /var/log	
zroot/var/mail        96K  18.5G    96K  /var/mail
zroot/var/tmp         96K  18.5G    96K  /var/tmp

root@freebsd:~ # zfs create -o canmount=off -o mountpoint=none zroot/exclude

root@freebsd:~ # zfs rename -u zroot/usr  zroot/exclude/usr
root@freebsd:~ # zfs rename -u zroot/var  zroot/exclude/var
root@freebsd:~ # zfs rename -u zroot/home zroot/exclude/home
root@freebsd:~ # zfs rename -u zroot/tmp  zroot/exclude/tmp

root@freebsd:~ # zfs list
NAME                      USED  AVAIL  REFER  MOUNTPOINT
zroot                     385M  18.5G    96K  none
zroot/ROOT                383M  18.5G    96K  none
zroot/ROOT/default        383M  18.5G   383M  /
zroot/exclude            1.16M  18.5G    96K  none
zroot/exclude/home         96K  18.5G    96K  /home
zroot/exclude/tmp          96K  18.5G    96K  /tmp
zroot/exclude/usr         288K  18.5G    96K  /usr
zroot/exclude/usr/ports    96K  18.5G    96K  /usr/ports
zroot/exclude/usr/src      96K  18.5G    96K  /usr/src
zroot/exclude/var         612K  18.5G    96K  /var
zroot/exclude/var/audit    96K  18.5G    96K  /var/audit
zroot/exclude/var/crash    96K  18.5G    96K  /var/crash
zroot/exclude/var/log     132K  18.5G   132K  /var/log
zroot/exclude/var/mail     96K  18.5G    96K  /var/mail
zroot/exclude/var/tmp      96K  18.5G    96K  /var/tmp

Make more sense now? I hope it does … and even after all that renaming I have done above … nothing changed in the ZFS mountpoints … as mountpoint is a separate ZFS property – so even if we logically reorganize our ZFS datasets naming convention – unless inherited from ZFS above when not set – the ZFS mountpoint property stays the same after all our logical reorganization.

The previous df(1) test gives the same results as earlier.

root@freebsd:~ # df -g /usr
Filesystem         1G-blocks Used Avail Capacity  Mounted on
zroot/ROOT/default        18    0    18     2%    /

root@freebsd:~ # df -g /var
Filesystem         1G-blocks Used Avail Capacity  Mounted on
zroot/ROOT/default        18    0    18     2%    /

Both /usr and /var data are kept WITHIN default ZFS Boot Environment.

We can even remove the /usr and /var mountpoint so it will be even more clear.

root@freebsd:~ # zfs set -u mountpoint=/var/tmp   zroot/exclude/var/tmp
root@freebsd:~ # zfs set -u mountpoint=/var/mail  zroot/exclude/var/mail
root@freebsd:~ # zfs set -u mountpoint=/var/log   zroot/exclude/var/log
root@freebsd:~ # zfs set -u mountpoint=/var/crash zroot/exclude/var/crash
root@freebsd:~ # zfs set -u mountpoint=/var/audit zroot/exclude/var/audit
root@freebsd:~ # zfs set -u mountpoint=none       zroot/exclude/var

root@freebsd:~ # zfs set -u mountpoint=/usr/src   zroot/exclude/usr/src
root@freebsd:~ # zfs set -u mountpoint=/usr/ports zroot/exclude/usr/ports
root@freebsd:~ # zfs set -u mountpoint=none       zroot/exclude/usr

root@freebsd:~ # zfs list
NAME                      USED  AVAIL  REFER  MOUNTPOINT
zroot                     385M  18.5G    96K  none
zroot/ROOT                383M  18.5G    96K  none
zroot/ROOT/default        383M  18.5G   383M  /
zroot/exclude            1.16M  18.5G    96K  none
zroot/exclude/home         96K  18.5G    96K  /home
zroot/exclude/tmp          96K  18.5G    96K  /tmp
zroot/exclude/usr         288K  18.5G    96K  none
zroot/exclude/usr/ports    96K  18.5G    96K  /usr/ports
zroot/exclude/usr/src      96K  18.5G    96K  /usr/src
zroot/exclude/var         612K  18.5G    96K  none
zroot/exclude/var/audit    96K  18.5G    96K  /var/audit
zroot/exclude/var/crash    96K  18.5G    96K  /var/crash
zroot/exclude/var/log     132K  18.5G   132K  /var/log
zroot/exclude/var/mail     96K  18.5G    96K  /var/mail
zroot/exclude/var/tmp      96K  18.5G    96K  /var/tmp

root@freebsd:~ # df -g
Filesystem              1G-blocks Used Avail Capacity  Mounted on
/dev/gpt/efiboot0               0    0     0     0%    /boot/efi
devfs                           0    0     0     0%    /dev
zroot/ROOT/default             18    0    18     2%    /
zroot/exclude/tmp              18    0    18     0%    /tmp
zroot/exclude/home             18    0    18     0%    /home
zroot/exclude/var/log          18    0    18     0%    /var/log
zroot/exclude/var/tmp          18    0    18     0%    /var/tmp
zroot/exclude/var/mail         18    0    18     0%    /var/mail
zroot/exclude/var/crash        18    0    18     0%    /var/crash
zroot/exclude/var/audit        18    0    18     0%    /var/audit
zroot/exclude/usr/src          18    0    18     0%    /usr/src
zroot/exclude/usr/ports        18    0    18     0%    /usr/ports

Clear enough now?

What Happens with Creation of New ZFS BE

Another enigma often not understood … or clearly.

Generally the ZFS Boot Environment is a writable ZFS clone made from a ZFS snapshot made in some time.

Let my try to visualize that with my favorite Enterprise Architect ASCII Edition software.

                                 |
                    ZFS DATASET  |   ZFS MOUNTPOINT => WHY
                                 |
          +-------------------+  |
          | ZFS 'zroot' pool  |  |  /sys            => # zfs set mountpoint=/sys sys
          |     (dataset)     |  |  canmount:on     => # zfs set canmount=on     sys
          +---------+---------+  |
                    |            |
            +-------+-------+    |
            |     ROOT      |    |  (none)          => # zfs set mountpoint=none sys/ROOT
            |   (dataset)   |    |  canmount:on     => # zfs set canmount=on     sys/ROOT
            +-------+-------+    |
                    |            |
              +-----+-----+      |
              |  default  |      |  /               => # zfs set mountpoint=/    sys/ROOT/${DATASET}
              | (dataset) |      |  canmount:noauto => # zfs set canmount=noauto sys/ROOT/${DATASET}
           +--+-----------+      |
           |                     |
           +- @2025-11-11@10:10  |  point-in-time   => # zfs snapshot            sys/ROOT/${DATASET}@2025-11-11@10:10
              | (snapshot)       |  (read only)        # beadm create            sys/ROOT/${DATASET}@2025-11-11@10:10
              |                  |
              +- safe            |  clone           => # zfs clone               sys/ROOT/${DATASET}@2025-11-11@10:10 sys/ROOT/safe
              | (clone)          |  (writable)         # beadm create -e default@2025-11-11@10:10 safe
              |                  |
              +- test            |  clone           => # zfs clone               sys/ROOT/${DATASET}@2025-11-11@10:10 sys/ROOT/test
                (clone)          |  (writable)         # beadm create -e default@2025-11-11@10:10 test
                                 |

The beadm(8) command output will show something like that about above ASCII diagram.

root@freebsd:~ # beadm list
BE                  Active Mountpoint  Space Created
default             NR     /           24.0G 2025-10-08 01:42
safe                -      -            1.3G 2025-06-10 09:47
test                -      -            6.4G 2025-08-22 23:02

root@freebsd:~ # zfs list -r -t all zroot/ROOT
NAME                                                 USED  AVAIL  REFER  MOUNTPOINT
zroot/ROOT                                          29.8G   154G    96K  none
zroot/ROOT/default                                   748K   154G  19.5G  /
zroot/ROOT/default@2025-11-11@10:10                 16.1G      -  24.2G  -
zroot/ROOT/safe                                        8K   154G  20.5G  /
zroot/ROOT/test                                      810M   154G  20.9G  /

root@freebsd:~ # beadm list -a
BE/Dataset/Snapshot                Active Mountpoint  Space Created

default
  zroot/ROOT/default               NR     /           24.0G 2025-10-08 01:42

safe
  zroot/ROOT/safe                  -      -          748.0K 2025-06-10 09:47
    default@2025-11-11@10:10       -      -            1.3G 2025-10-08 01:42

test
  zroot/ROOT/test                  -      -          810.0M 2025-08-22 23:02
    default@2025-11-11@10:10        -      -            5.6G 2025-08-22 23:02


root@freebsd:~ # zfs get origin zroot/ROOT/default
NAME                PROPERTY  VALUE   SOURCE
zroot/ROOT/default  origin    -       -

root@freebsd:~ # zfs get origin zroot/ROOT/safe
NAME             PROPERTY  VALUE                                SOURCE
zroot/ROOT/safe  origin    zroot/ROOT/default@2025-11-11@10:10  -

root@freebsd:~ # zfs get origin zroot/ROOT/test
NAME             PROPERTY  VALUE                                SOURCE
zroot/ROOT/test  origin    zroot/ROOT/default@2025-11-11@10:10  -

root@freebsd:~ # zpool get bootfs
NAME   PROPERTY  VALUE                SOURCE
zdata  bootfs    -                    default
zroot  bootfs    zroot/ROOT/default   local

Now … this is where it gets more interesting – You can create or ZFS send|recv as many additional ZFS Boot Environments as You want.

Below is example of such setup.

                                        |
                       ZFS DATASET      |       MOUNTPOINT => WHY
                                        |
         +-----------------------+      |
         |    ZFS 'zroot' pool   |      |  /sys            => # zfs set mountpoint=/sys sys
         |     (ZFS dataset)     |      |  canmount:on     => # zfs set canmount=on     sys
         +-----------+-----------+      |
                     |                  |
           +---------+---------+        |
           |       ROOT        |        |  (none)          => # zfs set mountpoint=none sys/ROOT
           |   (ZFS dataset)   |        |  canmount:on     => # zfs set canmount=on     sys/ROOT
           +---------+---------+        |
                     |                  |
      +--------------+----------+       |
      |              |          |       |
 +----+----+ +-------+---+ +----+----+  |
 | default | |  15.0-RC1 | |  12.2   |  |  /               => # zfs set mountpoint=/    sys/ROOT/${DATASET}
 |(dataset)| | (dataset) | |(dataset)|  |  canmount:noauto => # zfs set canmount=noauto sys/ROOT/${DATASET}
 +---------+ +-----------+ +---------+  |
                                        |

… and from each of these ZFS datasets you may create additional ZFS Boot Environments.

Transfer ZFS BE Between Systems

… and that can be ANY systems. You can transfer ZFS BE between laptops or from laptop to server … or from Bhyve VM to server … any way you like.

Below You will find some examples on how to copy existing ZFS BE over the network from one FreeBSD UNIX system to another.

The mbuffer(1) is not critical here – it just make process faster by making sure there is some data ready to be send at any given time.

root@freebsd:~ # beadm export 14.3 | mbuffer | ssh 10.26 doas beadm import 14.3.w520
summary: 30.3 GiByte in 34min 04.8sec - average of 15.2 MiB/s

Above sends my 14.3 ZFS BE from my ThinkPad W520 into my ThinkPad T14 system – that is why I want to call it 14.3.w520 on the other side – to make sure I remember what it originated from.

You can also create new ZFS BE from scratch like I described in the Other FreeBSD Version in ZFS Boot Environment article.

Summary

I hope now the main principles of ZFS Boot Environments are more clear.

… and if not feel invited to share your doubts.

EOF

Brave New PKGBASE World

Let me put this into first sentence to make things clear – I like PKGBASE and I think it is improvement over freebsd-update(8) and base.txz and kernel.txz – what we currently have in FreeBSD. All the issues will be resolved in time and if You want to play safe you can still use the classic way of FreeBSD life over entire 15.x FreeBSD line.

The Table of Contents for the article.

  • Divided
  • Discussions
  • Problem to Solve
  • Warning
  • Install
  • Documentation
  • New PKGBASE Distribution Sets
  • Minimal RAM Requirements
  • Base Install
  • Repositories
  • Updating
  • Vital
  • PKGBASE Jails
  • Additional Independent Rescue
  • In the Works …

All of the information here is based on the FreeBSD 15.0-BETA2 version but I will update the info as new things are introduced.

Also … as now the base.txz is spread over about 200 or so pkg(8) packages – you will be able to either install everything – like with base.txz or install and maintain only parts that you really need. Do not need compilers? Remove them. Do not want to have documentation/man pages/examples? Uninstall.

Its just important to remember that after you switch any of your FreeBSD systems to PKGBASE – to also switch mentally – to not do several things that you have done in the past in the old ‘classic’ world.

Now …

Divided

I do not remember last time when entire FreeBSD community was more divided in one single concept.

The PKGBASE concept.

FreeBSD concept with which everything is handled by one pkg(8) command – for both Base System and third party packages.

Similar to dnf(8) or apt(8) from the Linux world.

Some time ago I even made a poll on both X/Twitter and Bluesky platforms.

The question was:

– one pkg(8) command for FreeBSD Base System and third party packages.

– separate pkgbase(8) command for FreeBSD Base System and pkg(8) for third party packages.

Results are below.

More or less 50% for each option.

Discussions

I also do not remember when single topic covered most of the Mailing Lists discussions with such coverage.

Below are screenshots or freebsd-pkgbase and freebsd-stable lists.

While I like the PKGBASE concept because now the freebsd-update(8) process is very long over large upgrades and also very interactive – besides other things PKGBASE also solves these two … but it comes at a price.

Problem to Solve

Some may ask what problem PKGBASE tries to resolve … there are few.

First – the delta based design of freebsd-update(8) was PITA for maintenance. The binary diffs where difficult to generate and maintain because FreeBSD Release Engineering team need to store every old version of binaries – then generating binary diffs for each possible upgrade path and later testing that every delta sequence applies correctly. Besides being error prone it was also time consuming. This ‘way’ of things was also sensitive to local modifications and/or corruption. The freebsd-update(8) requires that every local file exactly matches the expected original. If user compiled custom kernel/world or modified/replaced any file manually then the delta patches cannot be applied.

Second – the freebsd-update(8) process was ALWAYS interactive which was quite OK if you have two FreeBSD machines – but it You are responsible for keeping hundreds of FreeBSD machines and need to patch them quickly then it was PITA. Some people coped with that by overwriting the PAGER variable … but that often caused trouble.

FreeBSD # env PAGER=cat freebsd-update fetch install

Third – no file ownership within Base System. If file is not known to pkg(8) then it probably originated in FreeBSD Base System … but you can never be sure. Because freebsd-update(8) only patches files in place it can not track what component owns which file and thus cleanly remove obsolete files.

Forth – with PKGBASE its possible to remove and/or manage optional components cleanly – by removing their pkg(8) packages. Without PKGBASE you can only mange Base System as a whole and patch it with freebsd-update(8) … you can of course build your tailored FreeBSD version with lots of components/subsystems disabled in /etc/src.conf file … but then freebsd-update(8) will not work with them.

Fifth – without PKGBASE – the only way you can update/upgrade a STABLE or CURRENT system is by compiling everything from source. With PKGBASE there will be pkg(8) repos with weekly/monthly updates – so You do not have to waste time and electricity just to update your STABLE/CURRENT system – just update the PKGBASE packages with pkg(8) command.

Warning

I need to warn you about a thing or two in the new PKGBASE world.

[ WARNING: BEGIN ]

Many FreeBSD seasoned sysadmins – including me – knew that from time to time – when its needed – one can just safely wipe all third party packages with pkg delete -fay command. Then one could rm -rf /usr/local /boot/modules to make sure everything was cleaned – and start again with fresh FreeBSD Base System.

With FreeBSD installed in a PKGBASE way the pkg delete -fay command will destroy your FreeBSD system. Literally. So think twice before executing it on a FreeBSD PKGBASE system.

The ZFS Boot Environments feature will NOT protect you from executing pkg delete -fay command on the running system – even if you have created a backup ZFS Boot Environment – you will NOT be able to reach the loader(8) for the boot menu selection.

OK ls boot
boot
 d  zfs
 d  efi
    loader.conf
    entropy
 d  firmware

Because there is not kernel or loader(8) anymore … and its the same in both BIOS and UEFI mode.

Another warning – if you use FreeBSD in PKGBASE mode – do not touch freebsd-update(8) command – it will break the system.

Also – do not update/upgrade PKGBASE system with make installworld or make installkernel commands – it will also do harm.

Alternatively use make buildworld buildkernel update-packages command which will create package repository with packages you can use to update/upgrade the FreeBSD system with pkg(8) command.

This is the default FreeBSD ZFS pool layout.

root@pkgbase:~ # zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
zroot                1.25G  17.7G    96K  /zroot
zroot/ROOT           1.25G  17.7G    96K  none
zroot/ROOT/default   1.24G  17.7G   854M  /
zroot/home            224K  17.7G    96K  /home
zroot/home/vermaden   128K  17.7G   128K  /home/vermaden
zroot/tmp             112K  17.7G   112K  /tmp
zroot/usr             288K  17.7G    96K  /usr
zroot/usr/ports        96K  17.7G    96K  /usr/ports
zroot/usr/src          96K  17.7G    96K  /usr/src
zroot/var             684K  17.7G    96K  /var
zroot/var/audit        96K  17.7G    96K  /var/audit
zroot/var/crash        96K  17.7G    96K  /var/crash
zroot/var/log         196K  17.7G   196K  /var/log
zroot/var/mail        104K  17.7G   104K  /var/mail
zroot/var/tmp          96K  17.7G    96K  /var/tmp

Its a good template to start – I very rarely modify it – but …

If you use multiple independent ZFS Boot Environments keep in mind that /usr/src is not part of ZFS BE and will be overwritten by FreeBSD-src and FreeBSD-src-sys packages from each ZFS BE. To overcome move /usr/src into each ZFS BE so that FreeBSD source tree (and packages) will be consistent and independent from each other for each ZFS Boot Environment you use. Its the same even without PKGBASE – its just a reminder that PKGBASE does not change anything here.

[ WARNING: END ]

Install

Right now bsdinstall from FreeBSD 15.x will ask you important question at the start – in which world you want to live?

I have also read on Mailing Lists that Experimental label will be changed to Tech Preview one.

There is also one important switch on what is available on the installation media. From 15.x series the PKGBASE package sets are on the installation media and older ones like base.txz or kernel.tzx have to be downloaded from the Internet … at least for smallest disc1 media.

Classic Distributions Sets like base.txz and kernel.txz maintained and updated by freebsd-update(8) command or PKGBASE with everything being managed and upgraded by pkg(8) command.

You can even later convert older Distributions Sets install with pkgbasify(8) tool. From what I have seen on the FreeBSD Mailing Lists there is even depkgbasify(8) planned – to convert PKGBASE system back to classic Distributions Sets setup.

Documentation

After VNET Jails were introduced to FreeBSD the official FreeBSD Handbook did not had any documentation about them for more then a decade.

Fortunately the PKGBASE concept is already covered FreeBSD Handbook PKGBASE section.

… and its not some short memo/mention like with fwget(8) tool that was just mentioned once in the FreeBSD 14.0-RELEASE Release Notes and forgotten.

There is also new freebsd-base(7) man page covering PKGBASE concept.

Which is also nice.

There is also some relevant info in the FreeBSD Wiki https://wiki.freebsd.org/pkgbase page.

New PKGBASE Distribution Sets

Say goodbye to traditional base.txz and kernel.tzx sets and welcome newly crafted sets for PKGBASE:

kernel-dbg – Debug symbols for the kernel.

devel – C/C++ compilers and related utilities.

optional – Optional software (excluding compilers).

optional-jail – Optional software (excluding compilers)

base – The complete base system (includes devel and optional)

base-jail – The complete base system (includes devel and optional)

src – System source tree

tests – Test suite.

lib32 – 32-bit compatibility libraries.

debug – Debug symbols for the selected components.

From the good news – you can now select to install a lot smaller Base System that is a lot better suited for FreeBSD Jails – and there are no bad news here – just more options and flexibility πŸ™‚

Minimal RAM Requirements

I am not sure that there are any specific requirements set right now – but the minimum amount of RAM that I was able to install FreeBSD with PKGBASE is 300 MB RAM – and that is with Auto (ZFS) option. I already described it in the Mailing Lists but I will happily repeat that here.

First Select [Live System] option – then execute these:

root@:~ # kldload zfs
ZFS filesystem version: 5
ZFS storage pool version: features support (5000)

root@:~ # sysctl vfs.zfs.arc.min=33554432
vfs.zfs.arc.min: 0 -> 33554432

root@:~ # sysctl vfs.zfs.arc.max=67108864
vfs.zfs.arc.max: 0 -> 67108864

root@:~ # sysctl vm.pageout_oom_seq=1200
vm.pageout_oom_seq: 12 -> 1200

root@:~ # env TERM=xterm bsdinstall

Now you can proceed to the install process. I selected PKGBASE type and offline installation – and then Auto (ZFS). I made the test with only base set chosen – but it probably can also survive more sets selected. I also switched from (BIOS) to (BIOS+UEFI) but that should not make any difference for you.

Some stats after installation (before reboot):

root@:/ # dmesg | grep -i memory
real memory  = 314572800 (300 MB)
avail memory = 263303168 (251 MB)

root@:/ # top -b -o res
last pid:  2544;  load averages:    1.31,    0.80,    0.34  up 0+00:02:20    18:02:03
10 processes:  1 running, 9 sleeping
CPU:  7.8% user,  0.0% nice, 16.7% system, 12.1% interrupt, 63.4% idle
Mem: 3588K Active, 11M Inact, 6376K Laundry, 148M Wired, 5800K Buf, 89M Free
ARC: 47M Total, 2667K MFU, 38M MRU, 128K Anon, 294K Header, 6515K Other
     29M Compressed, 65M Uncompressed, 2.24:1 Ratio

I tried the same with 256 MB RAM but it fails.

Base Install

After selecting base only I got 208 packages installed – including pkg(8) one.

root@pkgbase:~ # pkg info | wc -l
     208

root@pkgbase:~ # pkg info | while read PKG DESC; do printf "%52s  %s\n" ${PKG} ${DESC}; done
                 FreeBSD-acct-15.0.b1.20251011075131  System resource accounting
                 FreeBSD-acpi-15.0.b1.20251011075131  Advanced Configuration and Power Interface (ACPI) utilities
                  FreeBSD-apm-15.0.b1.20251011075131  Intel / Microsoft APM BIOS utility
                   FreeBSD-at-15.0.b1.20251011075131  Scheduled and batch command utilities
                  FreeBSD-atf-15.0.b1.20251011075131  Automated Testing Framework
              FreeBSD-atf-dev-15.0.b1.20251011075131  Automated Testing Framework (development files)
              FreeBSD-atf-lib-15.0.b1.20251011075131  Automated Testing Framework (libraries)
                FreeBSD-audit-15.0.b1.20251011075131  OpenBSM auditing utilities
            FreeBSD-audit-dev-15.0.b1.20251011075131  OpenBSM auditing utilities (development files)
            FreeBSD-audit-lib-15.0.b1.20251011075131  OpenBSM auditing utilities (libraries)
               FreeBSD-autofs-15.0.b1.20251011075131  File system automounter
                FreeBSD-bhyve-15.0.b1.20251011075131  bhyve virtual machine hypervisor
            FreeBSD-blocklist-15.0.b1.20251011075131  Network blocklist daemon
        FreeBSD-blocklist-dev-15.0.b1.20251011075131  Network blocklist daemon (development files)
            FreeBSD-bluetooth-15.0.b1.20251011075131  Bluetooth support
        FreeBSD-bluetooth-dev-15.0.b1.20251011075131  Bluetooth support (development files)
        FreeBSD-bluetooth-lib-15.0.b1.20251011075131  Bluetooth support (libraries)
                FreeBSD-bmake-15.0.b1.20251011075131  Program maintenance utility
           FreeBSD-bootloader-15.0.b1.20251011075131  System boot loader
       FreeBSD-bootloader-dev-15.0.b1.20251011075131  System boot loader (development files)
            FreeBSD-bsdconfig-15.0.b1.20251011075131  System configuration utility
           FreeBSD-bsdinstall-15.0.b1.20251011075131  System installer
                FreeBSD-bsnmp-15.0.b1.20251011075131  Simple and extensible SNMP daemon
            FreeBSD-bsnmp-dev-15.0.b1.20251011075131  Simple and extensible SNMP daemon (development files)
                FreeBSD-bzip2-15.0.b1.20251011075131  A block-sorting data compressor
            FreeBSD-bzip2-dev-15.0.b1.20251011075131  A block-sorting data compressor (development files)
            FreeBSD-bzip2-lib-15.0.b1.20251011075131  A block-sorting data compressor (libraries)
               FreeBSD-caroot-15.0.b1.20251011075131  Mozilla Root Store trusted TLS certificates
            FreeBSD-ccdconfig-15.0.b1.20251011075131  Concatenated disk driver (ccd) configuration utility
              FreeBSD-certctl-15.0.b1.20251011075131  Tool for managing trusted and untrusted TLS certificates
                FreeBSD-clang-15.0.b1.20251011075131  The Clang C, C++, and Objective-C compiler
            FreeBSD-clang-dev-15.0.b1.20251011075131  The Clang C, C++, and Objective-C compiler (development files)
                FreeBSD-clibs-15.0.b1.20251011075131  Core runtime libraries
            FreeBSD-clibs-dev-15.0.b1.20251011075131  Core runtime libraries (development files)
        FreeBSD-console-tools-15.0.b1.20251011075131  Video console utilities
                 FreeBSD-cron-15.0.b1.20251011075131  Command scheduling facility
                  FreeBSD-csh-15.0.b1.20251011075131  C shell with file name completion and command line editing
                  FreeBSD-ctf-15.0.b1.20251011075131  Compact C Type Format (CTF)
              FreeBSD-ctf-dev-15.0.b1.20251011075131  Compact C Type Format (CTF) (development files)
              FreeBSD-ctf-lib-15.0.b1.20251011075131  Compact C Type Format (CTF) (libraries)
                  FreeBSD-ctl-15.0.b1.20251011075131  CAM Target Layer / iSCSI target daemon
          FreeBSD-cxgbe-tools-15.0.b1.20251011075131  Configuration utility for Chelsio cxbge(4) network interfaces
                 FreeBSD-devd-15.0.b1.20251011075131  Kernel event handling daemon
             FreeBSD-devmatch-15.0.b1.20251011075131  Automatically load kernel drivers for attached hardware
         FreeBSD-devmatch-dev-15.0.b1.20251011075131  Automatically load kernel drivers for attached hardware (development files)
             FreeBSD-dhclient-15.0.b1.20251011075131  Dynamic Host Configuration Protocol (DHCP) client
                FreeBSD-diff3-15.0.b1.20251011075131  GNU 3-way file comparison and merge utility
                  FreeBSD-dma-15.0.b1.20251011075131  DragonFly Mail Agent
               FreeBSD-dtrace-15.0.b1.20251011075131  DTrace dynamic tracing framework
           FreeBSD-dtrace-dev-15.0.b1.20251011075131  DTrace dynamic tracing framework (development files)
               FreeBSD-dwatch-15.0.b1.20251011075131  Watch processes as they trigger a particular DTrace probe
                   FreeBSD-ee-15.0.b1.20251011075131  Easy Editor
            FreeBSD-efi-tools-15.0.b1.20251011075131  Utilities for the Unified Extensible Firmware Interface (UEFI)
        FreeBSD-efi-tools-dev-15.0.b1.20251011075131  Utilities for the Unified Extensible Firmware Interface (UEFI) (development files)
             FreeBSD-examples-15.0.b1.20251011075131  System interface examples
                   FreeBSD-fd-15.0.b1.20251011075131  Floppy disk utilities
                FreeBSD-fetch-15.0.b1.20251011075131  Retrieve a file from a remote URL
            FreeBSD-fetch-dev-15.0.b1.20251011075131  Retrieve a file from a remote URL (development files)
         FreeBSD-firmware-iwm-15.0.b1.20251011075131  Firmware for iwm(4) Intel 802.11ac network interfaces
                  FreeBSD-ftp-15.0.b1.20251011075131  File Transfer Protocol (FTP) client
                FreeBSD-fwget-15.0.b1.20251011075131  Install firmware packages for the running system
                FreeBSD-games-15.0.b1.20251011075131  Games
                 FreeBSD-geom-15.0.b1.20251011075131  GEOM configuration utilities
                FreeBSD-ggate-15.0.b1.20251011075131  GEOM Gate client and server
                 FreeBSD-gssd-15.0.b1.20251011075131  gssd(8) daemon for kernel GSS-API
                 FreeBSD-hast-15.0.b1.20251011075131  Highly Available Storage daemon
              FreeBSD-hostapd-15.0.b1.20251011075131  IEEE Std 802.11 Access Point authentication daemon
         FreeBSD-hyperv-tools-15.0.b1.20251011075131  Microsoft Hyper-V utilities
                FreeBSD-inetd-15.0.b1.20251011075131  Internet super-server
                  FreeBSD-ipf-15.0.b1.20251011075131  IP Filter (ipf) packet filter management tools
                 FreeBSD-ipfw-15.0.b1.20251011075131  ipfw (IP firewall) management utilities
                FreeBSD-iscsi-15.0.b1.20251011075131  iSCSI initiator
                 FreeBSD-jail-15.0.b1.20251011075131  Jail management tools
             FreeBSD-kerberos-15.0.b1.20251011075131  Kerberos client
         FreeBSD-kerberos-dev-15.0.b1.20251011075131  Kerberos client (development files)
         FreeBSD-kerberos-kdc-15.0.b1.20251011075131  Kerberos key distribution center
         FreeBSD-kerberos-lib-15.0.b1.20251011075131  Kerberos client (libraries)
       FreeBSD-kernel-generic-15.0.b1.20251011075131  FreeBSD GENERIC Kernel
           FreeBSD-kernel-man-15.0.b1.20251011075131  Kernel manual pages
                 FreeBSD-kyua-15.0.b1.20251011075131  Testing framework for infrastructure software
                FreeBSD-lib9p-15.0.b1.20251011075131  9P network protocol library
            FreeBSD-lib9p-dev-15.0.b1.20251011075131  9P network protocol library (development files)
           FreeBSD-libarchive-15.0.b1.20251011075131  Library for reading and writing streaming archives
       FreeBSD-libarchive-dev-15.0.b1.20251011075131  Library for reading and writing streaming archives (development files)
           FreeBSD-libbegemot-15.0.b1.20251011075131  rpoll(3) interface for event-driven I/O
       FreeBSD-libbegemot-dev-15.0.b1.20251011075131  rpoll(3) interface for event-driven I/O (development files)
     FreeBSD-libblocksruntime-15.0.b1.20251011075131  LLVM BlocksRuntime library
 FreeBSD-libblocksruntime-dev-15.0.b1.20251011075131  LLVM BlocksRuntime library (development files)
           FreeBSD-libbsdstat-15.0.b1.20251011075131  Periodic statistics library
       FreeBSD-libbsdstat-dev-15.0.b1.20251011075131  Periodic statistics library (development files)
            FreeBSD-libcasper-15.0.b1.20251011075131  Casper library
        FreeBSD-libcasper-dev-15.0.b1.20251011075131  Casper library (development files)
            FreeBSD-libcompat-15.0.b1.20251011075131  Compatibility library
        FreeBSD-libcompat-dev-15.0.b1.20251011075131  Compatibility library (development files)
   FreeBSD-libcompiler_rt-dev-15.0.b1.20251011075131  LLVM compiler_rt library (development files)
              FreeBSD-libcuse-15.0.b1.20251011075131  Userland character device library
          FreeBSD-libcuse-dev-15.0.b1.20251011075131  Userland character device library (development files)
             FreeBSD-libdwarf-15.0.b1.20251011075131  DWARF access library
         FreeBSD-libdwarf-dev-15.0.b1.20251011075131  DWARF access library (development files)
            FreeBSD-libevent1-15.0.b1.20251011075131  Private libevent1 library
        FreeBSD-libevent1-dev-15.0.b1.20251011075131  Private libevent1 library (development files)
          FreeBSD-libexecinfo-15.0.b1.20251011075131  NetBSD stack backtrace library
      FreeBSD-libexecinfo-dev-15.0.b1.20251011075131  NetBSD stack backtrace library (development files)
               FreeBSD-libipt-15.0.b1.20251011075131  Intel(R) Processor Trace decoder library
           FreeBSD-libipt-dev-15.0.b1.20251011075131  Intel(R) Processor Trace decoder library (development files)
              FreeBSD-libldns-15.0.b1.20251011075131  Private LDNS library
          FreeBSD-libldns-dev-15.0.b1.20251011075131  Private LDNS library (development files)
             FreeBSD-libmagic-15.0.b1.20251011075131  Magic number recognition library
         FreeBSD-libmagic-dev-15.0.b1.20251011075131  Magic number recognition library (development files)
            FreeBSD-libmilter-15.0.b1.20251011075131  sendmail Mail Filter API library
        FreeBSD-libmilter-dev-15.0.b1.20251011075131  sendmail Mail Filter API library (development files)
          FreeBSD-libpathconv-15.0.b1.20251011075131  Library for handling relative and absolute pathnames
      FreeBSD-libpathconv-dev-15.0.b1.20251011075131  Library for handling relative and absolute pathnames (development files)
        FreeBSD-librpcsec_gss-15.0.b1.20251011075131  RPCSEC_GSS library
    FreeBSD-librpcsec_gss-dev-15.0.b1.20251011075131  RPCSEC_GSS library (development files)
               FreeBSD-librss-15.0.b1.20251011075131  Receive-side scaling library
           FreeBSD-librss-dev-15.0.b1.20251011075131  Receive-side scaling library (development files)
           FreeBSD-libsqlite3-15.0.b1.20251011075131  Private SQLite library
       FreeBSD-libsqlite3-dev-15.0.b1.20251011075131  Private SQLite library (development files)
         FreeBSD-libthread_db-15.0.b1.20251011075131  Library for interacting with threaded processes
     FreeBSD-libthread_db-dev-15.0.b1.20251011075131  Library for interacting with threaded processes (development files)
               FreeBSD-libucl-15.0.b1.20251011075131  Private Universal Configuration Library (UCL) library
           FreeBSD-libucl-dev-15.0.b1.20251011075131  Private Universal Configuration Library (UCL) library (development files)
               FreeBSD-libvgl-15.0.b1.20251011075131  Video Graphics Library
           FreeBSD-libvgl-dev-15.0.b1.20251011075131  Video Graphics Library (development files)
            FreeBSD-libvmmapi-15.0.b1.20251011075131  Front-end library for the vmm(4) virtualization driver
        FreeBSD-libvmmapi-dev-15.0.b1.20251011075131  Front-end library for the vmm(4) virtualization driver (development files)
              FreeBSD-libyaml-15.0.b1.20251011075131  Private YAML library
          FreeBSD-libyaml-dev-15.0.b1.20251011075131  Private YAML library (development files)
                  FreeBSD-lld-15.0.b1.20251011075131  LLVM ELF link loader
                 FreeBSD-lldb-15.0.b1.20251011075131  LLVM debugger
             FreeBSD-lldb-dev-15.0.b1.20251011075131  LLVM debugger (development files)
              FreeBSD-locales-15.0.b1.20251011075131  Locale definitions
                   FreeBSD-lp-15.0.b1.20251011075131  Print spooler
               FreeBSD-mandoc-15.0.b1.20251011075131  Online manual page reader
            FreeBSD-mlx-tools-15.0.b1.20251011075131  Utility for managing Connect-X 4/5/6 Mellanox network adapters
                FreeBSD-mtree-15.0.b1.20251011075131  Filesystem hierarchy management tool
                 FreeBSD-natd-15.0.b1.20251011075131  Userland Network Address Translation (NAT) for ipfw
             FreeBSD-natd-dev-15.0.b1.20251011075131  Userland Network Address Translation (NAT) for ipfw (development files)
              FreeBSD-ncurses-15.0.b1.20251011075131  ncurses terminal control library
          FreeBSD-ncurses-dev-15.0.b1.20251011075131  ncurses terminal control library (development files)
               FreeBSD-netmap-15.0.b1.20251011075131  Userland netmap support
           FreeBSD-netmap-dev-15.0.b1.20251011075131  Userland netmap support (development files)
            FreeBSD-newsyslog-15.0.b1.20251011075131  Create and rotate system log files
                  FreeBSD-nfs-15.0.b1.20251011075131  NFS client and server utilities
                  FreeBSD-ntp-15.0.b1.20251011075131  Network Time Protocol (NTP) daemon
            FreeBSD-nuageinit-15.0.b1.20251011075131  cloud-init configuration support
           FreeBSD-nvme-tools-15.0.b1.20251011075131  NVMe utilities
              FreeBSD-openssl-15.0.b1.20251011075131  OpenSSL Transport Layer Security (TLS) library
          FreeBSD-openssl-dev-15.0.b1.20251011075131  OpenSSL Transport Layer Security (TLS) library (development files)
          FreeBSD-openssl-lib-15.0.b1.20251011075131  OpenSSL Transport Layer Security (TLS) library (libraries)
             FreeBSD-periodic-15.0.b1.20251011075131  Run periodic system functions
                   FreeBSD-pf-15.0.b1.20251011075131  OpenBSD packet filter
               FreeBSD-pf-dev-15.0.b1.20251011075131  OpenBSD packet filter (development files)
        FreeBSD-pkg-bootstrap-15.0.b1.20251011075131  pkg(7) bootstrap utility
                  FreeBSD-pmc-15.0.b1.20251011075131  Support for hardware performance counters
              FreeBSD-pmc-dev-15.0.b1.20251011075131  Support for hardware performance counters (development files)
               FreeBSD-powerd-15.0.b1.20251011075131  System power control utility
                  FreeBSD-ppp-15.0.b1.20251011075131  Point-to-Point Protocol (PPP) utilities
           FreeBSD-quotacheck-15.0.b1.20251011075131  Filesystem quota consistency checker
                   FreeBSD-rc-15.0.b1.20251011075131  rc(8) subsystem
                FreeBSD-rcmds-15.0.b1.20251011075131  BSD/SunOS remote status commands
                 FreeBSD-rdma-15.0.b1.20251011075131  Remote Direct Memory Access (RDMA) and InfiniBand utilities
               FreeBSD-rescue-15.0.b1.20251011075131  Rescue system
           FreeBSD-resolvconf-15.0.b1.20251011075131  A framework for managing multiple DNS configurations
                  FreeBSD-rip-15.0.b1.20251011075131  RIP routing protocol
              FreeBSD-runtime-15.0.b1.20251011075131  Core system
          FreeBSD-runtime-dev-15.0.b1.20251011075131  Core system (development files)
             FreeBSD-sendmail-15.0.b1.20251011075131  sendmail mail transport agent
             FreeBSD-set-base-15.0.b1.20251011075131  Base system (metapackage)
            FreeBSD-set-devel-15.0.b1.20251011075131  Development tools (metapackage)
          FreeBSD-set-minimal-15.0.b1.20251011075131  Basic multi-user system (metapackage)
         FreeBSD-set-optional-15.0.b1.20251011075131  Optional base system software (metapackage)
              FreeBSD-set-src-15.0.b1.20251011075131  System source code
             FreeBSD-smbutils-15.0.b1.20251011075131  SMB network filesystem utilities
         FreeBSD-smbutils-dev-15.0.b1.20251011075131  SMB network filesystem utilities (development files)
                FreeBSD-sound-15.0.b1.20251011075131  Audio utilities
            FreeBSD-sound-dev-15.0.b1.20251011075131  Audio utilities (development files)
                  FreeBSD-src-15.0.b1.20251011075131  System userland source code
              FreeBSD-src-sys-15.0.b1.20251011075131  System kernel source code
                  FreeBSD-ssh-15.0.b1.20251011075131  OpenSSH Secure Shell client and server
              FreeBSD-ssh-dev-15.0.b1.20251011075131  OpenSSH Secure Shell client and server (development files)
         FreeBSD-syscons-data-15.0.b1.20251011075131  syscons(4) fonts and keymaps
              FreeBSD-syslogd-15.0.b1.20251011075131  System logging daemon
                 FreeBSD-tcpd-15.0.b1.20251011075131  TCP Wrappers access control facility
             FreeBSD-tcpd-dev-15.0.b1.20251011075131  TCP Wrappers access control facility (development files)
               FreeBSD-telnet-15.0.b1.20251011075131  TELNET client
            FreeBSD-toolchain-15.0.b1.20251011075131  Utilities for program development
        FreeBSD-toolchain-dev-15.0.b1.20251011075131  Utilities for program development (development files)
                  FreeBSD-ufs-15.0.b1.20251011075131  UFS filesystem support
              FreeBSD-ufs-dev-15.0.b1.20251011075131  UFS filesystem support (development files)
              FreeBSD-ufs-lib-15.0.b1.20251011075131  UFS filesystem support (libraries)
              FreeBSD-unbound-15.0.b1.20251011075131  NLnet Labs Unbound DNS resolver
          FreeBSD-unbound-dev-15.0.b1.20251011075131  NLnet Labs Unbound DNS resolver (development files)
            FreeBSD-utilities-15.0.b1.20251011075131  Non-vital programs and libraries
        FreeBSD-utilities-dev-15.0.b1.20251011075131  Non-vital programs and libraries (development files)
                   FreeBSD-vi-15.0.b1.20251011075131  Text editor
              FreeBSD-vt-data-15.0.b1.20251011075131  vt(4) fonts and keymaps
                  FreeBSD-wpa-15.0.b1.20251011075131  IEEE Std 802.11 WPA Supplicant
                   FreeBSD-xz-15.0.b1.20251011075131  LZMA2 data compression
               FreeBSD-xz-dev-15.0.b1.20251011075131  LZMA2 data compression (development files)
               FreeBSD-xz-lib-15.0.b1.20251011075131  LZMA2 data compression (libraries)
                   FreeBSD-yp-15.0.b1.20251011075131  Yellow Pages (YP) / Network Information Service (NIS)
                  FreeBSD-zfs-15.0.b1.20251011075131  ZFS filesystem support
              FreeBSD-zfs-dev-15.0.b1.20251011075131  ZFS filesystem support (development files)
              FreeBSD-zfs-lib-15.0.b1.20251011075131  ZFS filesystem support (libraries)
             FreeBSD-zoneinfo-15.0.b1.20251011075131  Timezone database
                                           pkg-2.3.1  Package manager

root@pkgbase:~ # pkg info -qoa
base/FreeBSD-acct
base/FreeBSD-acpi
base/FreeBSD-apm
base/FreeBSD-at
base/FreeBSD-atf
base/FreeBSD-atf-dev
base/FreeBSD-atf-lib
base/FreeBSD-audit
base/FreeBSD-audit-dev
base/FreeBSD-audit-lib
base/FreeBSD-autofs
base/FreeBSD-bhyve
base/FreeBSD-blocklist
base/FreeBSD-blocklist-dev
base/FreeBSD-bluetooth
base/FreeBSD-bluetooth-dev
base/FreeBSD-bluetooth-lib
base/FreeBSD-bmake
base/FreeBSD-bootloader
base/FreeBSD-bootloader-dev
base/FreeBSD-bsdconfig
base/FreeBSD-bsdinstall
base/FreeBSD-bsnmp
base/FreeBSD-bsnmp-dev
base/FreeBSD-bzip2
base/FreeBSD-bzip2-dev
base/FreeBSD-bzip2-lib
base/FreeBSD-caroot
base/FreeBSD-ccdconfig
base/FreeBSD-certctl
base/FreeBSD-clang
base/FreeBSD-clang-dev
base/FreeBSD-clibs
base/FreeBSD-clibs-dev
base/FreeBSD-console-tools
base/FreeBSD-cron
base/FreeBSD-csh
base/FreeBSD-ctf
base/FreeBSD-ctf-dev
base/FreeBSD-ctf-lib
base/FreeBSD-ctl
base/FreeBSD-cxgbe-tools
base/FreeBSD-devd
base/FreeBSD-devmatch
base/FreeBSD-devmatch-dev
base/FreeBSD-dhclient
base/FreeBSD-diff3
base/FreeBSD-dma
base/FreeBSD-dtrace
base/FreeBSD-dtrace-dev
base/FreeBSD-dwatch
base/FreeBSD-ee
base/FreeBSD-efi-tools
base/FreeBSD-efi-tools-dev
base/FreeBSD-examples
base/FreeBSD-fd
base/FreeBSD-fetch
base/FreeBSD-fetch-dev
base/FreeBSD-firmware-iwm
base/FreeBSD-ftp
base/FreeBSD-fwget
base/FreeBSD-games
base/FreeBSD-geom
base/FreeBSD-ggate
base/FreeBSD-gssd
base/FreeBSD-hast
base/FreeBSD-hostapd
base/FreeBSD-hyperv-tools
base/FreeBSD-inetd
base/FreeBSD-ipf
base/FreeBSD-ipfw
base/FreeBSD-iscsi
base/FreeBSD-jail
base/FreeBSD-kerberos
base/FreeBSD-kerberos-dev
base/FreeBSD-kerberos-kdc
base/FreeBSD-kerberos-lib
base/FreeBSD-kernel-generic
base/FreeBSD-kernel-man
base/FreeBSD-kyua
base/FreeBSD-lib9p
base/FreeBSD-lib9p-dev
base/FreeBSD-libarchive
base/FreeBSD-libarchive-dev
base/FreeBSD-libbegemot
base/FreeBSD-libbegemot-dev
base/FreeBSD-libblocksruntime
base/FreeBSD-libblocksruntime-dev
base/FreeBSD-libbsdstat
base/FreeBSD-libbsdstat-dev
base/FreeBSD-libcasper
base/FreeBSD-libcasper-dev
base/FreeBSD-libcompat
base/FreeBSD-libcompat-dev
base/FreeBSD-libcompiler_rt-dev
base/FreeBSD-libcuse
base/FreeBSD-libcuse-dev
base/FreeBSD-libdwarf
base/FreeBSD-libdwarf-dev
base/FreeBSD-libevent1
base/FreeBSD-libevent1-dev
base/FreeBSD-libexecinfo
base/FreeBSD-libexecinfo-dev
base/FreeBSD-libipt
base/FreeBSD-libipt-dev
base/FreeBSD-libldns
base/FreeBSD-libldns-dev
base/FreeBSD-libmagic
base/FreeBSD-libmagic-dev
base/FreeBSD-libmilter
base/FreeBSD-libmilter-dev
base/FreeBSD-libpathconv
base/FreeBSD-libpathconv-dev
base/FreeBSD-librpcsec_gss
base/FreeBSD-librpcsec_gss-dev
base/FreeBSD-librss
base/FreeBSD-librss-dev
base/FreeBSD-libsqlite3
base/FreeBSD-libsqlite3-dev
base/FreeBSD-libthread_db
base/FreeBSD-libthread_db-dev
base/FreeBSD-libucl
base/FreeBSD-libucl-dev
base/FreeBSD-libvgl
base/FreeBSD-libvgl-dev
base/FreeBSD-libvmmapi
base/FreeBSD-libvmmapi-dev
base/FreeBSD-libyaml
base/FreeBSD-libyaml-dev
base/FreeBSD-lld
base/FreeBSD-lldb
base/FreeBSD-lldb-dev
base/FreeBSD-locales
base/FreeBSD-lp
base/FreeBSD-mandoc
base/FreeBSD-mlx-tools
base/FreeBSD-mtree
base/FreeBSD-natd
base/FreeBSD-natd-dev
base/FreeBSD-ncurses
base/FreeBSD-ncurses-dev
base/FreeBSD-netmap
base/FreeBSD-netmap-dev
base/FreeBSD-newsyslog
base/FreeBSD-nfs
base/FreeBSD-ntp
base/FreeBSD-nuageinit
base/FreeBSD-nvme-tools
base/FreeBSD-openssl
base/FreeBSD-openssl-dev
base/FreeBSD-openssl-lib
base/FreeBSD-periodic
base/FreeBSD-pf
base/FreeBSD-pf-dev
base/FreeBSD-pkg-bootstrap
base/FreeBSD-pmc
base/FreeBSD-pmc-dev
base/FreeBSD-powerd
base/FreeBSD-ppp
base/FreeBSD-quotacheck
base/FreeBSD-rc
base/FreeBSD-rcmds
base/FreeBSD-rdma
base/FreeBSD-rescue
base/FreeBSD-resolvconf
base/FreeBSD-rip
base/FreeBSD-runtime
base/FreeBSD-runtime-dev
base/FreeBSD-sendmail
base/FreeBSD-set-base
base/FreeBSD-set-devel
base/FreeBSD-set-minimal
base/FreeBSD-set-optional
base/FreeBSD-set-src
base/FreeBSD-smbutils
base/FreeBSD-smbutils-dev
base/FreeBSD-sound
base/FreeBSD-sound-dev
base/FreeBSD-src
base/FreeBSD-src-sys
base/FreeBSD-ssh
base/FreeBSD-ssh-dev
base/FreeBSD-syscons-data
base/FreeBSD-syslogd
base/FreeBSD-tcpd
base/FreeBSD-tcpd-dev
base/FreeBSD-telnet
base/FreeBSD-toolchain
base/FreeBSD-toolchain-dev
base/FreeBSD-ufs
base/FreeBSD-ufs-dev
base/FreeBSD-ufs-lib
base/FreeBSD-unbound
base/FreeBSD-unbound-dev
base/FreeBSD-utilities
base/FreeBSD-utilities-dev
base/FreeBSD-vi
base/FreeBSD-vt-data
base/FreeBSD-wpa
base/FreeBSD-xz
base/FreeBSD-xz-dev
base/FreeBSD-xz-lib
base/FreeBSD-yp
base/FreeBSD-zfs
base/FreeBSD-zfs-dev
base/FreeBSD-zfs-lib
base/FreeBSD-zoneinfo
ports-mgmt/pkg

You can even display pkg(8) distribution sets.

root@pkgbase:~ # pkg info -d -C -x '^FreeBSD-set-' | head
FreeBSD-set-base-15.0.b1.20251011075131:
        FreeBSD-set-optional-15.0.b1.20251011075131
        FreeBSD-set-minimal-15.0.b1.20251011075131
        FreeBSD-set-devel-15.0.b1.20251011075131
FreeBSD-set-devel-15.0.b1.20251011075131:
        FreeBSD-zfs-dev-15.0.b1.20251011075131
        FreeBSD-xz-dev-15.0.b1.20251011075131
        FreeBSD-utilities-dev-15.0.b1.20251011075131
        FreeBSD-unbound-dev-15.0.b1.20251011075131
        FreeBSD-ufs-dev-15.0.b1.20251011075131

root@pkgbase:~ # pkg sets | grep '^FreeBSD'
FreeBSD-set-base-15.0.b1.20251011075131:
FreeBSD-set-devel-15.0.b1.20251011075131:
FreeBSD-set-minimal-15.0.b1.20251011075131:
FreeBSD-set-optional-15.0.b1.20251011075131:
FreeBSD-set-src-15.0.b1.20251011075131:

You can even put it as an ALIAS into the /usr/local/etc/pkg.conf file.

root@pkgbase:~ # grep -e '^ALIAS' -e sets -e '^}' /usr/local/etc/pkg.conf
ALIAS {
    sets = "info -d -C -x '^FreeBSD-set-'";
}

root@pkgbase:~ # pkg sets | head 
FreeBSD-set-base-15.0.b1.20251011075131:
        FreeBSD-set-optional-15.0.b1.20251011075131
        FreeBSD-set-minimal-15.0.b1.20251011075131
        FreeBSD-set-devel-15.0.b1.20251011075131
FreeBSD-set-devel-15.0.b1.20251011075131:
        FreeBSD-zfs-dev-15.0.b1.20251011075131
        FreeBSD-xz-dev-15.0.b1.20251011075131
        FreeBSD-utilities-dev-15.0.b1.20251011075131
        FreeBSD-unbound-dev-15.0.b1.20251011075131
        FreeBSD-ufs-dev-15.0.b1.20251011075131

Repositories

For naming clarity the FreeBSD and FreeBSD-kmods repos that you knew from 14.x line were renamed into FreeBSD-ports and FreeBSD-ports-kmods respectively. The new PKGBASE repo is called FreeBSD-base.

root@pkgbase:~ # pkg repos -l
FreeBSD-ports
FreeBSD-ports-kmods
FreeBSD-base

root@pkgbase:~ # pkg repos
FreeBSD-ports: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
FreeBSD-ports-kmods: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
FreeBSD-base: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/base_latest",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }

For now the ‘third party’ packages pkg(8) repos config is in the Base System /etc/pkg/FreeBSD.conf file.

root@pkgbase:~ # grep '^[^#]' /etc/pkg/FreeBSD.conf
FreeBSD-ports: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports-kmods: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/kmods_quarterly_${VERSION_MINOR}",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

While the Base System packages pkg(8) repos config is in the ‘third party’ /usr/local/etc/pkg/FreeBSD.conf file.

root@pkgbase:~ # grep '^[^#]' /usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_latest",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

Which is not logical … but Colin Percival already wrote that this is just temporary and that all of these FreeBSD repos will be in the /etc/pkg/FreeBSD.conf file.

You can update all of them at once or by repo if needed.

root@pkgbase:~ # pkg update
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB 552.2kB/s    00:19    
Processing entries: 100%
FreeBSD-ports repository update completed. 36441 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   28 KiB  29.1kB/s    00:01    
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 199 packages processed.
Updating FreeBSD-base repository catalogue...
pkg: Repository FreeBSD-base has a wrong packagesite, need to re-create database
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   76 KiB  77.7kB/s    00:01    
Processing entries:   0%
Newer FreeBSD version for package FreeBSD-zoneinfo:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1500500
- running userland: 1500067
Ignore the mismatch and continue? [y/N]: y
Processing entries: 100%
FreeBSD-base repository update completed. 490 packages processed.
All repositories are up to date.

Updating

To update only the FreeBSD PKGBASE Base System specify the repo in the pkg(8) command.

root@pkgbase:~ # pkg upgrade -r FreeBSD-base
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
FreeBSD-base is up to date.
Checking for upgrades (205 candidates): 100%
Processing candidates (205 candidates): 100%
Checking integrity... done (0 conflicting)
Your packages are up to date.

No updates … strange considering BETA2 is now already available.

After I searched for an answer I got info that You need to modify the URL – to look like that one below.

root@pkgbase:~ # cat /usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: {
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_latest",
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

Now lets try to upgrade …

root@pkgbase:~ # pkg update -r FreeBSD-base
Updating FreeBSD-base repository catalogue...
pkg: Repository FreeBSD-base has a wrong packagesite, need to re-create database
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   76 KiB  77.7kB/s    00:01    
Processing entries: 100%
FreeBSD-base repository update completed. 490 packages processed.
FreeBSD-base is up to date.

Updating a single Base System package.

root@pkgbase:~ # pkg install FreeBSD-vi
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
The following 2 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-clibs-lib32: 15.0.b1.20251012072228 [FreeBSD-base]

Installed packages to be UPGRADED:
        FreeBSD-vi: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]

Number of packages to be installed: 1
Number of packages to be upgraded: 1

The process will require 4 MiB more space.
2 MiB to be downloaded.

Proceed with this action? [y/N]: y

Updating/upgrading whole FreeBSD system with PKGBASE packages.

root@pkgbase:~ # pkg upgrade -r FreeBSD-base
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
FreeBSD-base is up to date.
Checking for upgrades (202 candidates): 100%
Processing candidates (202 candidates): 100%
Checking integrity... done (5 conflicting)
  - FreeBSD-sound-15.0.b1.20251013072425 [FreeBSD-base] conflicts with FreeBSD-utilities-15.0.b1.20251011075131 [installed] on /usr/lib/virtual_oss/voss_null.so
  - FreeBSD-ncurses-lib-15.0.b1.20251015211959 [FreeBSD-base] conflicts with FreeBSD-ncurses-15.0.b1.20251011075131 [installed] on /lib/libncursesw.so.9
  - FreeBSD-bluetooth-lib-15.0.b1.20251013072425 [FreeBSD-base] conflicts with FreeBSD-bluetooth-15.0.b1.20251011075131 [installed] on /usr/lib/libbluetooth.so.4
  - FreeBSD-local-unbound-dev-15.0.b1.20251015211959 [FreeBSD-base] conflicts with FreeBSD-unbound-dev-15.0.b1.20251011075131 [installed] on /usr/lib/libprivateunbound.a
  - FreeBSD-local-unbound-15.0.b1.20251015211959 [FreeBSD-base] conflicts with FreeBSD-unbound-15.0.b1.20251011075131 [installed] on /etc/rc.d/local_unbound
Checking integrity... done (0 conflicting)
The following 208 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-clibs-lib32: 15.0.b1.20251012072228 [FreeBSD-base]
        FreeBSD-local-unbound: 15.0.b1.20251015211959 [FreeBSD-base]
        FreeBSD-local-unbound-dev: 15.0.b1.20251015211959 [FreeBSD-base]
        FreeBSD-ncurses-lib: 15.0.b1.20251015211959 [FreeBSD-base]

Installed packages to be UPGRADED:
        FreeBSD-acct: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]
        FreeBSD-acpi: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]
        FreeBSD-apm: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]
        (...)
        FreeBSD-zfs-dev: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]
        FreeBSD-zfs-lib: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]
        FreeBSD-zoneinfo: 15.0.b1.20251011075131 -> 15.0.b1.20251012072228 [FreeBSD-base]

Installed packages to be REMOVED:
        FreeBSD-unbound: 15.0.b1.20251011075131
        FreeBSD-unbound-dev: 15.0.b1.20251011075131

Number of packages to be removed: 2
Number of packages to be installed: 4
Number of packages to be upgraded: 202

The process will require 4 MiB more space.

Proceed with this action? [y/N]: y
[1/281] Upgrading FreeBSD-kernel-generic from 15.0.b1.20251011075131 to 15.0.b2.20251017190138...
[1/281] Extracting FreeBSD-kernel-generic-15.0.b2.20251017190138: 100%
[2/281] Deinstalling FreeBSD-set-base-15.0.b1.20251011075131...
(...)
[279/281] Extracting FreeBSD-zfs-dev-15.0.b1.20251012072228: 100%
[280/281] Installing FreeBSD-set-devel-15.0.b1.20251015211959...
[281/281] Installing FreeBSD-set-base-15.0.b1.20251012072228...

root@pkgbase:~ # freebsd-version -k
15.0-BETA2

root@pkgbase:~ # freebsd-version -u
15.0-BETA2

root@pkgbase:~ # freebsd-version -r
15.0-BETA1

root@pkgbase:~ # uname -prism
FreeBSD 15.0-BETA1 amd64 amd64 GENERIC

We may reboot now.

In both cases – for some reason – the FreeBSD-clibs-lib32 packages was pulled in as dependency … but You can delete it afterwards – it does not have any deps or reqs.

root@pkgbase:~ # pkg info | grep lib32
FreeBSD-clibs-lib32-15.0.b1.20251012072228 Core runtime libraries (32-bit libraries)

root@pkgbase:~ # pkg delete FreeBSD-clibs-lib32-15.0.b1.20251012072228
Cannot solve problem using SAT solver, trying another plan
(...)
Cannot solve problem using SAT solver, trying another plan
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 1 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
        FreeBSD-clibs-lib32: 15.0.b1.20251012072228

Number of packages to be removed: 1

The operation will free 4 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/1] Deinstalling FreeBSD-clibs-lib32-15.0.b1.20251012072228...
[1/1] Deleting files for FreeBSD-clibs-lib32-15.0.b1.20251012072228: 100%

Vital

Some packages will be marked as vital to prevent pkg delete -a from working and making damage – but vital concept does NOT protect against pkg delete -af since the understanding is that force -f flag specifically means “I know what I am doing – remove the packages at all costs.” … You have been warned.

PKGBASE Jails

The bsdinstall(8) installer has been updated with pkgbase --jail option that allows to populate a directory as FreeBSD Jail.

This is the recipe.

root@pkgbase:~ # mkdir -pv /jail/NEW
/jail
/jail/NEW

root@pkgbase:~ # export BSDINSTALL_CHROOT=/jail/NEW

root@pkgbase:~ # env TERM=xterm bsdinstall pkgbase --jail

Next select needed sets and proceed.

After installation there are 178 pkg(8) packages installed.

root@pkgbase:~ # pkg -r /jail/NEW info | wc -l
     178

root@pkgbase:~ # pkg -r /jail/NEW info -as | sort -k 2 -h | column -t | tail -10
FreeBSD-libmagic-15.snap20251011015136              11.8MiB
FreeBSD-utilities-dev-15.snap20251017141652         17.1MiB
FreeBSD-lldb-15.snap20251011015136                  18.4MiB
FreeBSD-zfs-dev-15.snap20251011015136               22.1MiB
FreeBSD-locales-15.snap20251011015136               24.3MiB
FreeBSD-openssl-dev-15.snap20251011015136           32.8MiB
FreeBSD-utilities-15.snap20251017141652             49.3MiB
FreeBSD-clibs-dev-15.snap20251018120849             59.2MiB
FreeBSD-clang-dev-15.snap20251011015136             70.4MiB
FreeBSD-clang-15.snap20251015183322                 149MiB

root@pkgbase:~ # du -smA /jail/NEW
804     /jail/NEW

Keep in mind that the pkg(8) is still not bootstrapped – we can do that now.

root@pkgbase:~ # chroot /jail/NEW/

[jail] root@pkgbase:/ # echo nameserver 9.9.9.9 > /etc/resolv.conf

[jail] root@pkgbase:/ # mount -t devfs devfs /dev

[jail] root@pkgbase:/ # pkg info
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/latest, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB   2.6MB/s    00:04    
Processing entries: 100%
FreeBSD-ports repository update completed. 36389 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   29 KiB  29.3kB/s    00:01    
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 200 packages processed.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.

… as you not need CLANG compiler in the Jail you may as well remove that part – same as many others – this is where PKGBASE helps.

[jail] root@pkgbase:/ # pkg delete -f FreeBSD-clang-15.snap20251015183322 FreeBSD-clang-dev-15.snap20251011015136
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 2 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
        FreeBSD-clang: 15.snap20251015183322
        FreeBSD-clang-dev: 15.snap20251011015136

Number of packages to be removed: 2

The operation will free 220 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/2] Deinstalling FreeBSD-clang-dev-15.snap20251011015136...
[1/2] Deleting files for FreeBSD-clang-dev-15.snap20251011015136: 100%
[2/2] Deinstalling FreeBSD-clang-15.snap20251015183322...
[2/2] Deleting files for FreeBSD-clang-15.snap20251015183322: 100%

[jail] root@pkgbase:/ # du -smA .
704     .

100 MB less space.

Additional Independent Rescue

Often in a serious problem the FreeBSD Rescue subsystem located at /rescue is the last resort help … but it will also be removed – as any other package.

The good news is that nothing prevents You from creating your own even more secure /RESCUE that will be entirely independent from pkg(8) command operations.

Do not just copy /rescue dir with cp(1) command as it will take almost 3 GB (1.5 GB after ZFS compression) with such operation πŸ™‚

root@pkgbase:/ # cp -ap /rescue /RESCUE
  
root@pkgbase:/ # du -sm /rescue /RESCUE
10      /rescue
1357    /RESCUE
  
root@pkgbase:/ # du -smA /rescue /RESCUE
20      /rescue
2855    /RESCUE

Here is how to create it in intelligent way – so it will only took the same small amount of space as original /rescue – with ln(1) hardlinks.

root@pkgbase:/ # mkdir /RESCUE

root@pkgbase:/ # cp /rescue/bectl /RESCUE/bectl

root@pkgbase:/ # cp /usr/local/sbin/pkg-static /RESCUE

root@pkgbase:/ # tar -cf /RESCUE/boot.tar /boot
tar: Removing leading '/' from member names
root@pkgbase:/ # ls -1 /rescue | while read I; do ln /RESCUE/bectl /RESCUE/"${I}"; done
ln: /RESCUE/bectl and /RESCUE/bectl are the same directory entry

root@pkgbase:/ # du -sm /rescue /RESCUE
11      /rescue
99      /RESCUE

root@pkgbase:/ # ls /rescue | wc -l
     148

root@pkgbase:/ # ls /RESCUE | wc -l
     152

root@pkgbase:/ # /RESCUE/bectl list
BE      Active Mountpoint Space Created
backup  -      -          393M  2025-10-18 23:35
default NR     /          1.42G 2025-10-18 16:31
new     -      -          8K    2025-10-20 12:46

You now have additional protection in case of serious emergency.

Our new /RESCUE is even better then the original on as we also have pkg-static(8) there … and a copy of /boot directory – so even if you wipe all FreeBSD system with pkg delete -fay you can restore the /boot and reboot into other ZFS Boot Environment πŸ™‚

The rescue procedure looks like that one below.

root@pkgbase:~ # /RESCUE/tar -C / -xf /RESCUE/boot.tar
tar: Failed to set default locale
boot/efi/: Can't restore time: Invalid argument
tar: Error exit delayed from previous errors.

root@pkgbase:~ # /RESCUE/reboot

After reboot the FreeBSD loader(8) will welcome you with possibility to select different ZFS Boot Environment.

In the Works …

As final PKGBASE world had not yet settled – expect additions and updates to this article as soon as new info gets to me.

… and feel free to share your findings and hints for living in the PKGBASE world.

UPDATE 1 – Safely Remove All Third Party Packages

After evaluating possible ways I currently use this solution below as a replacement for pkg delete -yaf from before PKGBASE times.

First – the pkg query '%o %R' prints ORIGIN and REPOSITORY as list.

The column(1) command used only to make it more readable/aligned.

pkgbase # pkg query '%o %R' | column -t
(...)
base/FreeBSD-zlib                  FreeBSD-base
base/FreeBSD-zlib-dev              FreeBSD-base
base/FreeBSD-zoneinfo              FreeBSD-base
sysutils/beadm                     FreeBSD-ports
sysutils/lsblk                     FreeBSD-ports
ports-mgmt/pkg                     FreeBSD-base

So we can check the 2nd column using awk(1) for FreeBSD-ports value … and print only the ORIGIN.

pkgbase # pkg query '%o %R' | awk '$2=="FreeBSD-ports" {print $1}'
sysutils/beadm
sysutils/lsblk

Notice that since PKGBASE the pkg(8) is now registered as PKGBASE package.

Now – to remove all third party packages we can do this below.

pkgbase # pkg query '%o %R' | awk '$2=="FreeBSD-ports" {print $1}' | xargs -n1 echo pkg delete -f -y
pkg delete sysutils/beadm
pkg delete sysutils/lsblk

Now – to REALLY remove these packages first remove the echo safety switch from the command above to make it work – because right now it only prints instructions that will remove packages.

EOF

New fwget(8) FreeBSD Firmware Tool

I did not used mine ThinkPad T14 for some time and after I tried to use it I noticed it was still running FreeBSD 14.1-RELEASE that was installed there – so I though – time for an upgrade. I did not wanted anything ‘experimental’ such as PKGBASE – just regular upgrade to supported FreeBSD 14.3-RELEASE version.Β Generally the classic upgrade procedure with freebsd-update(8) tool went well. Packages also updated OK with pkg(8) tool … but WiFi was gone.

For a start I though that wrong WiFi card is defined in my ~/scripts/network.sh wrapper … but no.

T14 % pciconf-list.sh | grep -i -e device -e wifI
      DEVICE       BUS  DESCRIPTION
    iwlwifi0    0:20:3  Comet Lake PCH-LP CNVi WiFi

T14 % grep -m 1 WLAN_IF ~/scripts/network.sh
WLAN_PH=iwlwifi0

Nope … everything is right. The pciconf-list.sh is here if needed.

Lets check what is shown by net.wlan.devices MIB.

T14 % sysctl net.wlan.devices
net.wlan.devices: 

Nope … but why?

Maybe dmesg(8) will show something …

T14 % grep -i wifi /var/run/dmesg.boot
Intel(R) Wireless WiFi based driver for FreeBSD
iwlwifi0:  mem 0xeb738000-0xeb73bfff at device 20.3 on pci0
iwlwifi0: Detected crf-id 0x3617, cnv-id 0x20000302 wfpm id 0x80000000
iwlwifi0: PCI dev 02f0/0074, rev=0x351, rfid=0x10a100
iwlwifi0: Detected Intel(R) Wi-Fi 6 AX201 160MHz
iwlwifi-QuZ-a0-hr-b0-77.ucode: could not load binary firmware /boot/firmware/iwlwifi-QuZ-a0-hr-b0-77.ucode either
iwlwifi-QuZ-a0-hr-b0-77.ucode: could not load binary firmware /boot/firmware/iwlwifi-QuZ-a0-hr-b0-77.ucode either
iwlwifi-QuZ-a0-hr-b0-77_ucode: could not load binary firmware /boot/firmware/iwlwifi-QuZ-a0-hr-b0-77_ucode either
iwlwifi_QuZ_a0_hr_b0_77_ucode: could not load binary firmware /boot/firmware/iwlwifi_QuZ_a0_hr_b0_77_ucode either
iwlwifi0: could not load firmware image 'iwlwifi-QuZ-a0-hr-b0-77.ucode'
iwlwifi0: File size way too small!
iwlwifi0: no suitable firmware found!
iwlwifi0: iwlwifi-QuZ-a0-hr-b0-77 is required
iwlwifi0: check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

No firmware … I never needed any additional firmware for WiFi.

The How to Unlock High Speed WiFi on FreeBSD 14 mentions fwget(8) as additional needed step but … there are ZERO mentions of fwget(8) in the official FreeBSD Handbook

Lets try to run it then …

T14 # fwget
Needed firmware packages: 'gpu-firmware-intel-kmod-kabylake wifi-firmware-iwlwifi-kmod-22000'
The most recent versions of packages are already installed

Already? Seems I missed them just a moment before πŸ™‚

Lets try the verbose mode.

T14 # fwget -v
Trying to match device 0x9b41 in class video and vendor intel with pci_video_intel
Trying to match device 0x02f0 in class network and vendor intel with pci_network_intel
Trying to match device 0x0d4f in class network and vendor intel with pci_network_intel
Trying to match device 0x522a in class misc and vendor realtek with pci_misc_realtek
Needed firmware packages: 'gpu-firmware-intel-kmod-kabylake wifi-firmware-iwlwifi-kmod-22000'
The most recent versions of packages are already installed

So there are some checks … lets check where they land.

T14 # find / -name iwlwifi-QuZ-a0-hr-b0-77.ucode
/boot/firmware/iwlwifi-QuZ-a0-hr-b0-77.ucode

T14 # ls -l /boot/firmware
.r--r--r-- root wheel 1.4 MB 2025/10/02 08:42 iwlwifi-9000-pu-b0-jf-b0-46.ucode
.r--r--r-- root wheel 1.4 MB 2025/10/02 08:42 iwlwifi-9260-th-b0-jf-b0-46.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-cc-a0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-Qu-b0-hr-b0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-Qu-b0-jf-b0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-Qu-c0-hr-b0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-Qu-c0-jf-b0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-QuZ-a0-hr-b0-77.ucode
.r--r--r-- root wheel 1.3 MB 2025/10/02 08:42 iwlwifi-QuZ-a0-jf-b0-77.ucode  

So we have FreeBSD Base System kernel modules in /boot/kernel and third party kernel modules installed by pkg(8) inside /boot/modules … and we now also have /boot/firmware for additional firmware from fwget(8) command.

Lets check where gpu-firmware-intel-kmod-kabylake landed out of curiosity …

T14 # find / -name gpu-firmware-intel-kmod-kabylake
T14 # 

Nowhere it seems … or maybe its named different …

T14 # find / -name gpu-firmware-intel-kmod-\* | grep -i kaby
/usr/local/share/licenses/gpu-firmware-intel-kmod-kabylake-20230625.1403000

T14 # find / -name gpu-firmware-intel-kmod-\*
/usr/local/share/licenses/gpu-firmware-intel-kmod-icelake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-rocketlake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-skylake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-elkhartlake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-kabylake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-tigerlake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-alderlake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-cannonlake-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-dg1-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-dg2-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-broxton-20230625.1403000
/usr/local/share/licenses/gpu-firmware-intel-kmod-geminilake-20230625.1403000

T14 # ls -l /usr/local/share/licenses | grep firmware
drwxr-xr-x root wheel  5 B 2024/06/22 01:40 bhyve-firmware-1.0_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-aldebaran-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-arcturus-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-banks-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-beige-goby-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-bonaire-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-carrizo-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-cyan-skillfish2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-dcn-3-1-4-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/09/22 03:03 gpu-firmware-amd-kmod-dcn-3-1-5-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-dcn-3-1-6-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-dcn-3-2-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-dcn-3-2-1-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-dimgrey-cavefish-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-fiji-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-10-3-6-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-10-3-7-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-11-0-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-11-0-1-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-11-0-2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-11-0-3-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-gc-11-0-4-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-green-sardine-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-hainan-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-hawaii-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-kabini-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-kaveri-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-mullins-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-navi10-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-navi12-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-navi14-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-navy-flounder-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-oland-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-picasso-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-pitcairn-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-polaris10-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-polaris11-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-polaris12-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-10-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-11-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-4-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-5-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-7-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-psp-13-0-8-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-raven-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-raven2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-renoir-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-5-2-6-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-5-2-7-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-6-0-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-6-0-1-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-6-0-2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sdma-6-0-3-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-si58-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-sienna-cichlid-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-smu-13-0-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-smu-13-0-10-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-smu-13-0-7-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-stoney-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:58 gpu-firmware-amd-kmod-tahiti-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-tonga-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-topaz-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vangogh-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vcn-3-1-2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vcn-4-0-0-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vcn-4-0-2-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vcn-4-0-4-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vega10-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vega12-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vega20-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-vegam-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-verde-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-amd-kmod-yellow-carp-20230625.1403000_2
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-alderlake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-broxton-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-cannonlake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-dg1-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-dg2-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-elkhartlake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-geminilake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-icelake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-kabylake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-rocketlake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-skylake-20230625.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-intel-kmod-tigerlake-20230625.1403000
drwxr-xr-x root wheel  5 B 2024/11/27 01:22 gpu-firmware-kmod-20241114,1
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-aruba-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-barts-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-bonaire-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-btc-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-caicos-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-cayman-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-cedar-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-cypress-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-hainan-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-hawaii-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-juniper-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-kabini-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-kaveri-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-mullins-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-oland-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-palm-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-pitcairn-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r100-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r200-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r300-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r420-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r520-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r600-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-r700-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-redwood-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rs600-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rs690-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rs780-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv610-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv620-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv630-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv635-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv670-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv710-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv730-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv740-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-rv770-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-sumo-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-sumo2-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-tahiti-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-turks-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/10/08 01:59 gpu-firmware-radeon-kmod-verde-20220511.1403000
drwxr-xr-x root wheel  5 B 2025/07/13 18:29 iwmbt-firmware-20250410
drwxr-xr-x root wheel  6 B 2025/10/09 21:00 wifi-firmware-iwlwifi-kmod-22000-20241017.1403000_2
drwxr-xr-x root wheel  6 B 2025/10/08 01:59 wifi-firmware-iwlwifi-kmod-9000-20241017.1403000_2

So there is additional /usr/local/share/licenses place for various firmware files … called licenses … while there already exists /boot/firmware dir … I would like to hear logic behind this decision πŸ™‚

After I had new firmware installed I decided to reboot to check it if will help.

… and it did.

T14 % sysctl net.wlan.devices
net.wlan.devices: iwlwifi0

T14 % grep -i wifi /var/run/dmesg.boot
Intel(R) Wireless WiFi based driver for FreeBSD
iwlwifi0:  mem 0xeb738000-0xeb73bfff at device 20.3 on pci0
iwlwifi0: Detected crf-id 0x3617, cnv-id 0x20000302 wfpm id 0x80000000
iwlwifi0: PCI dev 02f0/0074, rev=0x351, rfid=0x10a100
iwlwifi0: Detected Intel(R) Wi-Fi 6 AX201 160MHz
iwlwifi0: successfully loaded firmware image 'iwlwifi-QuZ-a0-hr-b0-77.ucode'
iwlwifi0: TLV_FW_FSEQ_VERSION: FSEQ Version: 89.3.35.37
iwlwifi0: loaded firmware version 77.0b4c06ad.0 QuZ-a0-hr-b0-77.ucode op_mode iwlmvm
iwlwifi0: Detected RF HR B5, rfid=0x10a100
iwlwifi0: base HW address: ec:63:d7:ab:62:d3

T14 % ifconfig wlan0
wlan0: flags=8843 metric 0 mtu 1500
        options=0
        ether ec:63:d7:ab:52:f3
        inet 172.16.27.57/19 broadcast 172.16.31.255
        groups: wlan
        ssid "WIFI" channel 6 (2437 MHz 11g ht/20) bssid 1c:61:b4:3c:f7:48
        regdomain FCC country US authmode WPA2/802.11i privacy ON
        deftxkey UNDEF AES-CCM 2:128-bit txpower 30 bmiss 7 scanvalid 60
        protmode CTS -ampdutx ampdurx ampdulimit 64k -amsdutx amsdurx shortgi
        -ldpctx ldpcrx -uapsd wme roaming MANUAL
        parent interface: iwlwifi0
        media: IEEE 802.11 Wireless Ethernet MCS mode 11ng
        status: associated
        nd6 options=29

T14 % ping -c 1 freebsd.org
PING freebsd.org (96.47.72.84): 56 data bytes
64 bytes from 96.47.72.84: icmp_seq=0 ttl=53 time=149.414 ms

--- freebsd.org ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 149.414/149.414/149.414/0.000 ms

Works.

Lets do a little check when fwget(8) tool happened – below is list of related commits.

The first one was sponsored by the Beckhoff Automation company.

First commits happened in 2023 … two years ago – so it seams its not that ‘new’ anyway πŸ™‚

I will also try to remember to update the post when some official documentation arrives … besides theΒ fwget(8) man page of course.

EOF

FreeBSD PKGBASE pkgbasify(8) Tool

The so called PKGBASE is the future of packaging the FreeBSD Base system – and its already implemented and tested in the upcoming 15.0-RELEASE version that will come later this year. You can even decide at the bsdinstall(8) stage if you want to install FreeBSD the ‘classic’ way or the PKGBASE way.

The PKGBASE is also well documented and you can run your Personal FreeBSD PKGBASE Update Server without a problem.

Right now there are only latest 15-CURRENT images that you can use and try all of that … but there is also FreeBSD Foundation sponsored pkgbasify(8) tool – it will literally convert your FreeBSD 14.x or 15.x installation into a PKGBASE install.

The instructions to do sa are really simple – download it – make it executable – execute it.

FreeBSD # fetch https://github.com/FreeBSDFoundation/pkgbasify/raw/refs/heads/main/pkgbasify.lua
FreeBSD # chmod +x ./pkgbasify.lua
FreeBSD # ./pkgbasify.lua

You will be asked several questions – including quite important one about creating a backup ZFS Boot Environment before you start the process – make sure your answer to that one is a big and fat YES.

Here is how the ‘upgrade’ process looks like.

I have placed (...) leaving only first and last 3 messages of the same type – to not have a mile/kilometer long output here.

FreeBSD # ./pkgbasify.lua
Running this tool will irreversibly modify your system to use pkgbase.
This tool and pkgbase are experimental and may result in a broken system.
It is highly recommend to backup your system before proceeding.
Do you accept this risk and wish to continue? (y/n) y
Updating FreeBSD-base repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   53 KiB  54.6kB/s    00:01    
Processing entries: 100%
FreeBSD-base repository update completed. 561 packages processed.
All repositories are up to date.
System has older __FreeBSD_version than remote pkgbase packages (1500046 vs 1500051).
It is recommended to update your system before running pkgbasify.
Ignore the osversion and continue anyway? (y/n) y
Create a boot environment before conversion? (y/n) y
Creating /usr/local/etc/pkg/repos/FreeBSD-base.conf
Adding BACKUP_LIBRARIES=yes to /usr/local/etc/pkg.conf
Updating FreeBSD-base repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   53 KiB  54.6kB/s    00:01    
Processing entries:   0%
Processing entries: 100%
FreeBSD-base repository update completed. 561 packages processed.
FreeBSD-base is up to date.
The following 292 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-acct: 15.snap20250707041723 [FreeBSD-base]
        FreeBSD-acct-man: 15.snap20241026125659 [FreeBSD-base]
        FreeBSD-acpi: 15.snap20250707041723 [FreeBSD-base]
        (...)
        FreeBSD-zfs-dev: 15.snap20250707041723 [FreeBSD-base]
        FreeBSD-zfs-man: 15.snap20250711002650 [FreeBSD-base]
        FreeBSD-zoneinfo: 15.snap20250521200023 [FreeBSD-base]

Number of packages to be installed: 292

The process will require 2 GiB more space.
530 MiB to be downloaded.
[1/292] Fetching FreeBSD-libbsm-15.snap20250707041723.pkg: 100%   37 KiB  37.6kB/s    00:01    
[2/292] Fetching FreeBSD-libsqlite3-dev-15.snap20250708002345.pkg: 100%    2 MiB   1.1MB/s    00:02    
[3/292] Fetching FreeBSD-libldns-dev-15.snap20250707041723.pkg: 100%  666 KiB 682.5kB/s    00:01    
(...)
[290/292] Fetching FreeBSD-clibs-dev-15.snap20250713141730.pkg: 100%   16 MiB   2.1MB/s    00:08    
[291/292] Fetching FreeBSD-libstdbuf-dev-15.snap20250611191401.pkg: 100%    4 KiB   4.5kB/s    00:01    
[292/292] Fetching FreeBSD-wpa-man-15.snap20241026125659.pkg: 100%   14 KiB  14.2kB/s    00:01    
Checking integrity... done (0 conflicting)
Checking integrity... done (0 conflicting)
The following 292 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-acct: 15.snap20250707041723 [FreeBSD-base]
        FreeBSD-acct-man: 15.snap20241026125659 [FreeBSD-base]
        FreeBSD-acpi: 15.snap20250707041723 [FreeBSD-base]
        (...)
        FreeBSD-zfs-dev: 15.snap20250707041723 [FreeBSD-base]
        FreeBSD-zfs-man: 15.snap20250711002650 [FreeBSD-base]
        FreeBSD-zoneinfo: 15.snap20250521200023 [FreeBSD-base]

Number of packages to be installed: 292

The process will require 2 GiB more space.
[1/292] Installing FreeBSD-acct-15.snap20250707041723...
[1/292] Extracting FreeBSD-acct-15.snap20250707041723: 100%
[2/292] Installing FreeBSD-acct-man-15.snap20241026125659...
(...)
[291/292] Extracting FreeBSD-zfs-man-15.snap20250711002650: 100%
[292/292] Installing FreeBSD-zoneinfo-15.snap20250521200023...
[292/292] Extracting FreeBSD-zoneinfo-15.snap20250521200023: 100%
Merged /etc/master.passwd
Merged /etc/rc.shutdown
Merged /etc/mtree/BSD.tests.dist
Merged /etc/mtree/BSD.usr.dist
Merged /etc/mtree/BSD.include.dist
Merged /etc/rc
Merged /etc/regdomain.xml
Merged /etc/sysctl.conf
Merged /etc/ssh/sshd_config
Merged /etc/group
Merged /etc/pccard_ether
Merged /etc/hosts
Merged /etc/rc.d/routing
Merged /etc/rc.d/nuageinit_user_data_script
Merged /etc/rc.d/mountcritlocal
Merged /etc/rc.d/kdc
Merged /etc/rc.d/zfsbe
Merged /etc/rc.d/zfs
Merged /etc/rc.d/zpool
Merged /etc/rc.d/hostname
Merged /etc/defaults/rc.conf
Merged /etc/rc.subr
Merged /etc/shells
Merged /etc/network.subr
Restarting sshd
Performing sanity check on sshd configuration.
Stopping sshd.
Waiting for PIDS: 12314, 12314.
Performing sanity check on sshd configuration.
Starting sshd.
Conversion finished.

Please verify that the contents of the following critical files are as expected:
/etc/master.passwd
/etc/group
/etc/ssh/sshd_config

After verifying those files, restart the system.

FreeBSD # reboot

All of the above would usually last about 10 minutes – it will be a lot faster if you have a really fast connection to the Internet.

After the conversion the system pkg(8) information looks as follows – including some ‘regular’ packages.

FreeBSD # pkg info
FreeBSD-acct-15.snap20250707041723 System Accounting Utilities
FreeBSD-acct-man-15.snap20241026125659 System Accounting Utilities (Manual Pages)
FreeBSD-acpi-15.snap20250707041723 ACPI Utilities
FreeBSD-acpi-man-15.snap20241026125659 ACPI Utilities (Manual Pages)
FreeBSD-apm-15.snap20250707041723 APM Utilities
FreeBSD-apm-man-15.snap20241026125659 APM Utilities (Manual Pages)
FreeBSD-at-15.snap20250707041723 AT Utilities
FreeBSD-at-man-15.snap20241026125659 AT Utilities (Manual Pages)
FreeBSD-audit-15.snap20250707041723 OpenBSM auditing utilities
FreeBSD-audit-dev-15.snap20250707041723 OpenBSM auditing utilities (Development Files)
FreeBSD-audit-man-15.snap20241026125659 OpenBSM auditing utilities (Manual Pages)
FreeBSD-autofs-15.snap20250707041723 Autofs Utilities
FreeBSD-autofs-man-15.snap20241026125659 Autofs Utilities (Manual Pages)
FreeBSD-bhyve-15.snap20250707041723 Bhyve Utilities
FreeBSD-bhyve-man-15.snap20250521163614 Bhyve Utilities (Manual Pages)
FreeBSD-blocklist-15.snap20250707041723 Blocklist Utilities
FreeBSD-blocklist-dev-15.snap20250707041723 Blocklist Utilities (Development Files)
FreeBSD-blocklist-man-15.snap20250203152159 Blocklist Utilities (Manual Pages)
FreeBSD-bluetooth-15.snap20250713095951 Bluetooth Utilities
FreeBSD-bluetooth-dev-15.snap20250707041723 Bluetooth Utilities (Development Files)
FreeBSD-bluetooth-man-15.snap20250130000845 Bluetooth Utilities (Manual Pages)
FreeBSD-bootloader-15.snap20250711053733 Bootloader
FreeBSD-bootloader-dev-15.snap20250711053733 Bootloader (Development Files)
FreeBSD-bsdinstall-15.snap20250707041723 BSDInstall Utilities
FreeBSD-bsdinstall-man-15.snap20250428171657 BSDInstall Utilities (Manual Pages)
FreeBSD-bsnmp-15.snap20250712134400 BSNMP Utilities
FreeBSD-bsnmp-dev-15.snap20250707041723 BSNMP Utilities (Development Files)
FreeBSD-bsnmp-man-15.snap20241026125659 BSNMP Utilities (Manual Pages)
FreeBSD-caroot-15.snap20250313075117 SSL Certificates
FreeBSD-ccdconfig-15.snap20250705072435 ccdconfig package
FreeBSD-ccdconfig-man-15.snap20250123170723 ccdconfig package (Manual Pages)
FreeBSD-certctl-15.snap20250117230744 SSL Certificate Utility
FreeBSD-certctl-man-15.snap20241026125659 SSL Certificate Utility (Manual Pages)
FreeBSD-clang-15.snap20250707041723 Clang Utilities
FreeBSD-clang-dev-15.snap20250707041723 Clang Utilities (Development Files)
FreeBSD-clang-man-15.snap20250505204745 Clang Utilities (Manual Pages)
FreeBSD-clibs-15.snap20250711204811 Core C Libraries
FreeBSD-clibs-dev-15.snap20250713141730 Core C Libraries (Development Files)
FreeBSD-clibs-man-15.snap20250709212429 Core C Libraries (Manual Pages)
FreeBSD-console-tools-15.snap20250707041723 Console Utilities
FreeBSD-console-tools-man-15.snap20241026125659 Console Utilities (Manual Pages)
FreeBSD-cron-15.snap20250707041723 cron(8) and crontab(1)
FreeBSD-cron-man-15.snap20241026125659 cron(8) and crontab(1) (Manual Pages)
FreeBSD-csh-15.snap20250709192127 C Shell
FreeBSD-csh-man-15.snap20241026125659 C Shell (Manual Pages)
FreeBSD-ctf-tools-15.snap20250707041723 CTF Utilities
FreeBSD-ctf-tools-man-15.snap20250616132851 CTF Utilities (Manual Pages)
FreeBSD-ctl-15.snap20250709143654 ctl package
FreeBSD-ctl-man-15.snap20250528033824 ctl package (Manual Pages)
FreeBSD-cxgbe-tools-15.snap20250707041723 Chelsio cxbge Utilities
FreeBSD-cxgbe-tools-man-15.snap20250519031828 Chelsio cxbge Utilities (Manual Pages)
FreeBSD-devd-15.snap20250707041723 Devd Utility and scripts
FreeBSD-devd-man-15.snap20250709143654 Devd Utility and scripts (Manual Pages)
FreeBSD-devmatch-15.snap20250707041723 Devmatch Utility
FreeBSD-devmatch-dev-15.snap20250611191401 Devmatch Utility (Development Files)
FreeBSD-devmatch-man-15.snap20250130000845 Devmatch Utility (Manual Pages)
FreeBSD-dhclient-15.snap20250707041723 DHCP Client
FreeBSD-dhclient-man-15.snap20241026125659 DHCP Client (Manual Pages)
FreeBSD-dma-15.snap20250707041723 DMA Mail Agent Utilities
FreeBSD-dma-man-15.snap20241026125659 DMA Mail Agent Utilities (Manual Pages)
FreeBSD-dtrace-15.snap20250707211642 Dtrace Utilities
FreeBSD-dtrace-dev-15.snap20250707211642 Dtrace Utilities (Development Files)
FreeBSD-dtrace-man-15.snap20250712093938 Dtrace Utilities (Manual Pages)
FreeBSD-dwatch-15.snap20241026125659 Dwatch Utilities
FreeBSD-dwatch-man-15.snap20250419184622 Dwatch Utilities (Manual Pages)
FreeBSD-ee-15.snap20250707041723 Easy Editor Utilities
FreeBSD-ee-man-15.snap20241026125659 Easy Editor Utilities (Manual Pages)
FreeBSD-efi-tools-15.snap20250707041723 UEFI Utilities
FreeBSD-efi-tools-dev-15.snap20250707041723 UEFI Utilities (Development Files)
FreeBSD-efi-tools-man-15.snap20241026125659 UEFI Utilities (Manual Pages)
FreeBSD-examples-15.snap20250710194216 Examples in /usr/share/examples
FreeBSD-fd-15.snap20250707041723 Floppy disk support
FreeBSD-fd-man-15.snap20250515020636 Floppy disk support (Manual Pages)
FreeBSD-fetch-15.snap20250707041723 Fetch Utility
FreeBSD-fetch-dev-15.snap20250707041723 Fetch Utility (Development Files)
FreeBSD-fetch-man-15.snap20241026125659 Fetch Utility (Manual Pages)
FreeBSD-firmware-iwm-15.snap20241216095300 iwm(4) firmwares
FreeBSD-ftp-15.snap20250707041723 FTP Utilities
FreeBSD-ftp-man-15.snap20241026125659 FTP Utilities (Manual Pages)
FreeBSD-ftpd-15.snap20250707041723 FTP Daemon
FreeBSD-ftpd-man-15.snap20250626130045 FTP Daemon (Manual Pages)
FreeBSD-fwget-15.snap20250619004001 FWGET Utility
FreeBSD-fwget-man-15.snap20241026125659 FWGET Utility (Manual Pages)
FreeBSD-games-15.snap20250705234744 Games
FreeBSD-games-man-15.snap20241026125659 Games (Manual Pages)
FreeBSD-geom-15.snap20250707041723 GEOM Utilitites
FreeBSD-geom-man-15.snap20250428160923 GEOM Utilitites (Manual Pages)
FreeBSD-ggate-15.snap20250707041723 GEOM Gate Utilities
FreeBSD-ggate-man-15.snap20241026125659 GEOM Gate Utilities (Manual Pages)
FreeBSD-hast-15.snap20250707041723 Highly Available Storage daemon
FreeBSD-hast-man-15.snap20241026125659 Highly Available Storage daemon (Manual Pages)
FreeBSD-hostapd-15.snap20250707041723 802.11 Access Point Daemon an Utilities
FreeBSD-hostapd-man-15.snap20241026125659 802.11 Access Point Daemon an Utilities (Manual Pages)
FreeBSD-hyperv-tools-15.snap20250707041723 Microsoft HyperV Utilities
FreeBSD-hyperv-tools-man-15.snap20241026125659 Microsoft HyperV Utilities (Manual Pages)
FreeBSD-inetd-15.snap20250707041723 Internet super-server
FreeBSD-inetd-man-15.snap20241026125659 Internet super-server (Manual Pages)
FreeBSD-ipf-15.snap20250708002345 ipf package
FreeBSD-ipf-man-15.snap20250304221631 ipf package (Manual Pages)
FreeBSD-ipfw-15.snap20250709090258 ipfw package
FreeBSD-ipfw-man-15.snap20250418123705 ipfw package (Manual Pages)
FreeBSD-iscsi-15.snap20250707041723 iscsi package
FreeBSD-iscsi-man-15.snap20250528033824 iscsi package (Manual Pages)
FreeBSD-jail-15.snap20250707041723 Jail Utilities
FreeBSD-jail-man-15.snap20250616132851 Jail Utilities (Manual Pages)
FreeBSD-kerberos-15.snap20250707041723 Kerberos Utilities
FreeBSD-kerberos-lib-15.snap20250708002345 Kerberos Libraries
FreeBSD-kerberos-lib-dev-15.snap20250708002345 Kerberos Libraries (Development Files)
FreeBSD-kerberos-lib-man-15.snap20241026125659 Kerberos Libraries (Manual Pages)
FreeBSD-kerberos-man-15.snap20241028160252 Kerberos Utilities (Manual Pages)
FreeBSD-kernel-generic-15.snap20250714080908 FreeBSD GENERIC kernel 
FreeBSD-lib9p-15.snap20250707041723 lib9p package
FreeBSD-lib9p-dev-15.snap20250707041723 lib9p package (Development Files)
FreeBSD-libarchive-15.snap20250709192127 libarchive package
FreeBSD-libarchive-dev-15.snap20250707041723 libarchive package (Development Files)
FreeBSD-libarchive-man-15.snap20250601213626 libarchive package (Manual Pages)
FreeBSD-libbegemot-15.snap20250705234744 libbegemot package
FreeBSD-libbegemot-dev-15.snap20250612001522 libbegemot package (Development Files)
FreeBSD-libbegemot-man-15.snap20241026125659 libbegemot package (Manual Pages)
FreeBSD-libblocksruntime-15.snap20250616183901 libblocksruntime package
FreeBSD-libblocksruntime-dev-15.snap20250611191401 libblocksruntime package (Development Files)
FreeBSD-libbsdstat-15.snap20250616183901 libbsdstat package
FreeBSD-libbsdstat-dev-15.snap20250611191401 libbsdstat package (Development Files)
FreeBSD-libbsm-15.snap20250707041723 libbsm package
FreeBSD-libbsm-dev-15.snap20250707041723 libbsm package (Development Files)
FreeBSD-libbsm-man-15.snap20241026125659 libbsm package (Manual Pages)
FreeBSD-libbz2-15.snap20250616183901 libbz2 package
FreeBSD-libbz2-dev-15.snap20250611191401 libbz2 package (Development Files)
FreeBSD-libcasper-15.snap20250707041723 libcasper package
FreeBSD-libcasper-dev-15.snap20250612202243 libcasper package (Development Files)
FreeBSD-libcasper-man-15.snap20241026125659 libcasper package (Manual Pages)
FreeBSD-libcompat-dev-15.snap20250707041723 libcompat package (Development Files)
FreeBSD-libcompat-man-15.snap20241026125659 libcompat package (Manual Pages)
FreeBSD-libcompiler_rt-dev-15.snap20250612001522 libcompiler_rt package (Development Files)
FreeBSD-libcuse-15.snap20250707041723 libcuse package
FreeBSD-libcuse-dev-15.snap20250707041723 libcuse package (Development Files)
FreeBSD-libcuse-man-15.snap20241026125659 libcuse package (Manual Pages)
FreeBSD-libdwarf-15.snap20250705072435 libdwarf package
FreeBSD-libdwarf-dev-15.snap20250612030328 libdwarf package (Development Files)
FreeBSD-libdwarf-man-15.snap20241026125659 libdwarf package (Manual Pages)
FreeBSD-libevent1-15.snap20250707041723 libevent1 package
FreeBSD-libevent1-dev-15.snap20250707041723 libevent1 package (Development Files)
FreeBSD-libexecinfo-15.snap20250707041723 libexecinfo package
FreeBSD-libexecinfo-dev-15.snap20250707041723 libexecinfo package (Development Files)
FreeBSD-libexecinfo-man-15.snap20241026125659 libexecinfo package (Manual Pages)
FreeBSD-libipt-15.snap20250707041723 libipt package
FreeBSD-libipt-dev-15.snap20250707041723 libipt package (Development Files)
FreeBSD-libldns-15.snap20250707041723 libldns package
FreeBSD-libldns-dev-15.snap20250707041723 libldns package (Development Files)
FreeBSD-liblzma-15.snap20250705072435 liblzma package
FreeBSD-liblzma-dev-15.snap20250612001522 liblzma package (Development Files)
FreeBSD-libmagic-15.snap20250707041723 libmagic package
FreeBSD-libmagic-dev-15.snap20250707041723 libmagic package (Development Files)
FreeBSD-libmagic-man-15.snap20241208191210 libmagic package (Manual Pages)
FreeBSD-libpathconv-15.snap20250616183901 libpathconv package
FreeBSD-libpathconv-dev-15.snap20250611191401 libpathconv package (Development Files)
FreeBSD-libpathconv-man-15.snap20241026125659 libpathconv package (Manual Pages)
FreeBSD-librpcsec_gss-15.snap20250705234744 librpcsec_gss package
FreeBSD-librpcsec_gss-dev-15.snap20250612001522 librpcsec_gss package (Development Files)
FreeBSD-librpcsec_gss-man-15.snap20241026125659 librpcsec_gss package (Manual Pages)
FreeBSD-librss-15.snap20250707041723 librss package
FreeBSD-librss-dev-15.snap20250707041723 librss package (Development Files)
FreeBSD-libsdp-15.snap20250707041723 libsdp package
FreeBSD-libsdp-dev-15.snap20250707041723 libsdp package (Development Files)
FreeBSD-libsdp-man-15.snap20241026125659 libsdp package (Manual Pages)
FreeBSD-libsqlite3-15.snap20250708002345 libsqlite3 package
FreeBSD-libsqlite3-dev-15.snap20250708002345 libsqlite3 package (Development Files)
FreeBSD-libstdbuf-15.snap20250616183901 libstdbuf package
FreeBSD-libstdbuf-dev-15.snap20250611191401 libstdbuf package (Development Files)
FreeBSD-libstdbuf-man-15.snap20241026125659 libstdbuf package (Manual Pages)
FreeBSD-libstdthreads-15.snap20250707041723 libstdthreads package
FreeBSD-libstdthreads-dev-15.snap20250611191401 libstdthreads package (Development Files)
FreeBSD-libstdthreads-man-15.snap20241026125659 libstdthreads package (Manual Pages)
FreeBSD-libthread_db-15.snap20250705072435 libthread_db package
FreeBSD-libthread_db-dev-15.snap20250616132851 libthread_db package (Development Files)
FreeBSD-libucl-15.snap20250707041723 libucl package
FreeBSD-libucl-dev-15.snap20250707041723 libucl package (Development Files)
FreeBSD-libucl-man-15.snap20241026125659 libucl package (Manual Pages)
FreeBSD-libufs-15.snap20250707041723 libufs package
FreeBSD-libufs-dev-15.snap20250707041723 libufs package (Development Files)
FreeBSD-libufs-man-15.snap20250505161221 libufs package (Manual Pages)
FreeBSD-libvgl-15.snap20250705234744 libvgl package
FreeBSD-libvgl-dev-15.snap20250612001522 libvgl package (Development Files)
FreeBSD-libvgl-man-15.snap20241026125659 libvgl package (Manual Pages)
FreeBSD-libvmmapi-15.snap20250707041723 libvmmapi package
FreeBSD-libvmmapi-dev-15.snap20250707041723 libvmmapi package (Development Files)
FreeBSD-liby-dev-15.snap20250611191401 liby package (Development Files)
FreeBSD-libyaml-15.snap20250626114931 libyaml package
FreeBSD-libyaml-dev-15.snap20250626114931 libyaml package (Development Files)
FreeBSD-libzfs-15.snap20250707041723 libzfs package
FreeBSD-libzfs-dev-15.snap20250707041723 libzfs package (Development Files)
FreeBSD-lld-15.snap20250705072435 lld package
FreeBSD-lld-man-15.snap20241026125659 lld package (Manual Pages)
FreeBSD-lldb-15.snap20250707041723 lldb package
FreeBSD-lldb-dev-15.snap20250425182925 lldb package (Development Files)
FreeBSD-lldb-man-15.snap20241026125659 lldb package (Manual Pages)
FreeBSD-locales-15.snap20241113231628 locales package
FreeBSD-lp-15.snap20250707041723 Printer subsystem
FreeBSD-lp-man-15.snap20241026125659 Printer subsystem (Manual Pages)
FreeBSD-mlx-tools-15.snap20250707041723 Mellanox Utilities
FreeBSD-mlx-tools-man-15.snap20241026125659 Mellanox Utilities (Manual Pages)
FreeBSD-mtree-15.snap20250707041723 MTREE Files
FreeBSD-mtree-man-15.snap20241026125659 MTREE Files (Manual Pages)
FreeBSD-natd-15.snap20250707041723 natd package
FreeBSD-natd-dev-15.snap20250707041723 natd package (Development Files)
FreeBSD-natd-man-15.snap20250204215803 natd package (Manual Pages)
FreeBSD-netmap-15.snap20250707041723 Netmap Library and Utilities
FreeBSD-netmap-dev-15.snap20250707041723 Netmap Library and Utilities (Development Files)
FreeBSD-netmap-man-15.snap20241026125659 Netmap Library and Utilities (Manual Pages)
FreeBSD-newsyslog-15.snap20250705072435 Newsyslog Utility
FreeBSD-newsyslog-man-15.snap20241129050736 Newsyslog Utility (Manual Pages)
FreeBSD-nfs-15.snap20250707041723 NFS Utilities
FreeBSD-nfs-man-15.snap20250609160437 NFS Utilities (Manual Pages)
FreeBSD-ntp-15.snap20250707041723 Network Time Protocol server and client
FreeBSD-ntp-man-15.snap20241112035500 Network Time Protocol server and client (Manual Pages)
FreeBSD-nuageinit-15.snap20250705145802 CloudInit support scripts
FreeBSD-nuageinit-man-15.snap20250626130045 CloudInit support scripts (Manual Pages)
FreeBSD-nvme-tools-15.snap20250709143654 NVME Utilities
FreeBSD-nvme-tools-man-15.snap20250709143654 NVME Utilities (Manual Pages)
FreeBSD-openssl-15.snap20250707041723 OpenSSL Utility
FreeBSD-openssl-lib-15.snap20250707041723 OpenSSL Libraries
FreeBSD-openssl-lib-dev-15.snap20250707041723 OpenSSL Libraries (Development Files)
FreeBSD-openssl-lib-man-15.snap20241104155004 OpenSSL Libraries (Manual Pages)
FreeBSD-openssl-man-15.snap20241104155004 OpenSSL Utility (Manual Pages)
FreeBSD-periodic-15.snap20250515020636 Periodic Utility
FreeBSD-periodic-man-15.snap20241026125659 Periodic Utility (Manual Pages)
FreeBSD-pf-15.snap20250712134400 pf package
FreeBSD-pf-dev-15.snap20250712134400 pf package (Development Files)
FreeBSD-pf-man-15.snap20250712134400 pf package (Manual Pages)
FreeBSD-pkg-bootstrap-15.snap20250707041723 pkg bootstrap Utility
FreeBSD-pkg-bootstrap-man-15.snap20250430011047 pkg bootstrap Utility (Manual Pages)
FreeBSD-ppp-15.snap20250707041723 ppp package
FreeBSD-ppp-man-15.snap20250204215803 ppp package (Manual Pages)
FreeBSD-quotacheck-15.snap20250707041723 quotacheck package
FreeBSD-quotacheck-man-15.snap20241026125659 quotacheck package (Manual Pages)
FreeBSD-rc-15.snap20250712171839 RC Scripts
FreeBSD-rc-man-15.snap20250612160001 RC Scripts (Manual Pages)
FreeBSD-rcmds-15.snap20250707041723 BSD/SunOS remote status commands
FreeBSD-rcmds-man-15.snap20250505161221 BSD/SunOS remote status commands (Manual Pages)
FreeBSD-rdma-15.snap20250707041723 RDMA Utilities
FreeBSD-rdma-man-15.snap20241026125659 RDMA Utilities (Manual Pages)
FreeBSD-rescue-15.snap20250712134400 Rescue Utilities
FreeBSD-resolvconf-15.snap20241026125659 Resolvconf Utility and scripts
FreeBSD-resolvconf-man-15.snap20241026125659 Resolvconf Utility and scripts (Manual Pages)
FreeBSD-runtime-15.snap20250713130127 FreeBSD Base System
FreeBSD-runtime-dev-15.snap20250710171124 FreeBSD Base System (Development Files)
FreeBSD-runtime-man-15.snap20250711235756 FreeBSD Base System (Manual Pages)
FreeBSD-sendmail-15.snap20250707041723 Sendmail Utilities
FreeBSD-sendmail-dev-15.snap20250707041723 Sendmail Utilities (Development Files)
FreeBSD-sendmail-man-15.snap20241026125659 Sendmail Utilities (Manual Pages)
FreeBSD-smbutils-15.snap20250707041723 SMB Utilities
FreeBSD-smbutils-dev-15.snap20250707041723 SMB Utilities (Development Files)
FreeBSD-smbutils-man-15.snap20241026125659 SMB Utilities (Manual Pages)
FreeBSD-src-15.snap20250713215434 FreeBSD Userland Sources
FreeBSD-src-sys-15.snap20250714080908 FreeBSD Kernel Sources
FreeBSD-ssh-15.snap20250707041723 Secure Shell Utilities
FreeBSD-ssh-dev-15.snap20250707041723 Secure Shell Utilities (Development Files)
FreeBSD-ssh-man-15.snap20250219191646 Secure Shell Utilities (Manual Pages)
FreeBSD-syscons-data-15.snap20241026125659 syscons-data package
FreeBSD-syslogd-15.snap20250707041723 Syslog Daemon
FreeBSD-syslogd-man-15.snap20241223174616 Syslog Daemon (Manual Pages)
FreeBSD-tcpd-15.snap20250707041723 TCP Wrapper utilities
FreeBSD-tcpd-dev-15.snap20250707041723 TCP Wrapper utilities (Development Files)
FreeBSD-tcpd-man-15.snap20241026125659 TCP Wrapper utilities (Manual Pages)
FreeBSD-telnet-15.snap20250707041723 Telnet client
FreeBSD-telnet-man-15.snap20241026125659 Telnet client (Manual Pages)
FreeBSD-tests-15.snap20250713190803 Test Suite
FreeBSD-tests-dbg-15.snap20250713190803 Test Suite (Debugging Symbols)
FreeBSD-tests-dev-15.snap20250707041723 Test Suite (Development Files)
FreeBSD-tests-man-15.snap20250616132851 Test Suite (Manual Pages)
FreeBSD-toolchain-15.snap20250707041723 Utilities for program development
FreeBSD-toolchain-dev-15.snap20250528033824 Utilities for program development (Development Files)
FreeBSD-toolchain-man-15.snap20250616224003 Utilities for program development (Manual Pages)
FreeBSD-ufs-15.snap20250707041723 UFS Libraries and Utilities
FreeBSD-ufs-man-15.snap20250505161221 UFS Libraries and Utilities (Manual Pages)
FreeBSD-unbound-15.snap20250707041723 Unbound DNS Resolver
FreeBSD-unbound-dev-15.snap20250707041723 Unbound DNS Resolver (Development Files)
FreeBSD-unbound-man-15.snap20241026125659 Unbound DNS Resolver (Manual Pages)
FreeBSD-utilities-15.snap20250713215434 Non-vital programs and libraries
FreeBSD-utilities-dev-15.snap20250711053733 Non-vital programs and libraries (Development Files)
FreeBSD-utilities-man-15.snap20250713175247 Non-vital programs and libraries (Manual Pages)
FreeBSD-vi-15.snap20250709192127 Vi Editor
FreeBSD-vi-man-15.snap20250102090848 Vi Editor (Manual Pages)
FreeBSD-vt-data-15.snap20250617031524 vt-data package
FreeBSD-wpa-15.snap20250707041723 802.11 Supplicant
FreeBSD-wpa-man-15.snap20241026125659 802.11 Supplicant (Manual Pages)
FreeBSD-yp-15.snap20250707041723 Yellow Pages programs
FreeBSD-yp-man-15.snap20241026125659 Yellow Pages programs (Manual Pages)
FreeBSD-zfs-15.snap20250712171839 ZFS Libraries and Utilities
FreeBSD-zfs-dev-15.snap20250707041723 ZFS Libraries and Utilities (Development Files)
FreeBSD-zfs-man-15.snap20250711002650 ZFS Libraries and Utilities (Manual Pages)
FreeBSD-zoneinfo-15.snap20250521200023 zoneinfo package
beadm-1.3.5_1                  Solaris-like utility to manage Boot Environments on ZFS
brotli-1.1.0,1                 Generic-purpose lossless compression algorithm
ccache4-4.10.2                 Tool to minimize the compile time of C/C++ programs
curl-8.14.0                    Command line tool and library for transferring data with URLs
expat-2.7.1                    XML 1.0 parser written in C
freebsd-release-manifests-20250531 FreeBSD release manifests
gettext-runtime-0.23.1         GNU gettext runtime libraries and programs
git-lite-2.49.0                Distributed source code management tool (lite flavor)
htop-3.4.0                     Better top(1) - interactive process viewer
indexinfo-0.3.1_1              Utility to regenerate the GNU info page index
libfmt-10.2.1                  Formatting library for C++
libidn2-2.3.8                  Implementation of IDNA2008 internationalized domain names
liblz4-1.10.0,1                LZ4 compression library, lossless and very fast
libnghttp2-1.65.0              HTTP/2 C Library
libpsl-0.21.5_2                C library to handle the Public Suffix List
libssh2-1.11.1,3               Library implementing the SSH2 protocol
libunistring-1.3               Unicode string library
lsblk-4.0                      Lists information about block devices in the system
nginx-1.28.0_1,3               Robust and small WWW server
pcre2-10.45_1                  Perl Compatible Regular Expressions library, version 2
perl5-5.40.2_2                 Practical Extraction and Report Language
pkg-2.1.4                      Package manager
portconfig-0.6.2               Utility to set up FreeBSD port options
poudriere-devel-3.4.99.20250601 Port build and test system
screen-5.0.1_4                 Multi-screen window manager
tree-2.2.1                     Display a tree-view of directories with optional color or HTML output
xxhash-0.8.3                   Extremely fast non-cryptographic hash algorithm
zsh-5.9_5                      The Z shell
zsh-autosuggestions-0.7.1      Fish-like autosuggestions for Zsh
zsh-completions-0.35.0         Additional completion definitions for Zsh
zsh-syntax-highlighting-0.8.0,1 Fish shell syntax highlighting for Zsh
zstd-1.5.7                     Fast real-time compression algorithm

The pkg(8) repositories information.

FreeBSD # pkg repos  
FreeBSD: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/latest",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
FreeBSD-kmods: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_latest",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
FreeBSD-base: { 
    url             : "pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/base_latest",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }

As expected the FreeBSD-base is added to the list.

PKGBASE Base System Upgrade

Several days later I decided to update/upgrade my system – here is how it went.

FreeBSD # pkg upgrade            
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating FreeBSD-kmods repository catalogue...
FreeBSD-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
Checking for upgrades (31 candidates): 100%
Processing candidates (31 candidates): 100%
The following 32 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-clibs-lib32: 15.snap20250715212405 [FreeBSD-base]

Installed packages to be UPGRADED:
        FreeBSD-bhyve: 15.snap20250707041723 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-bluetooth: 15.snap20250713095951 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-bootloader: 15.snap20250711053733 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-bootloader-dev: 15.snap20250711053733 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-bsdinstall: 15.snap20250707041723 -> 15.snap20250715191524 [FreeBSD-base]
        FreeBSD-bsnmp: 15.snap20250712134400 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-clang: 15.snap20250707041723 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-clang-dev: 15.snap20250707041723 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-clibs: 15.snap20250711204811 -> 15.snap20250715212405 [FreeBSD-base]
        FreeBSD-clibs-dev: 15.snap20250713141730 -> 15.snap20250716035604 [FreeBSD-base]
        FreeBSD-cxgbe-tools: 15.snap20250707041723 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-dtrace-man: 15.snap20250712093938 -> 15.snap20250716103437 [FreeBSD-base]
        FreeBSD-hyperv-tools: 15.snap20250707041723 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-inetd: 15.snap20250707041723 -> 15.snap20250715051601 [FreeBSD-base]
        FreeBSD-ipfw: 15.snap20250709090258 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-jail: 15.snap20250707041723 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-kernel-generic: 15.snap20250714080908 -> 15.snap20250716085830 [FreeBSD-base]
        FreeBSD-pf: 15.snap20250712134400 -> 15.snap20250715150641 [FreeBSD-base]
        FreeBSD-pf-dev: 15.snap20250712134400 -> 15.snap20250715101340 [FreeBSD-base]
        FreeBSD-rescue: 15.snap20250712134400 -> 15.snap20250715101340 [FreeBSD-base]
        FreeBSD-runtime: 15.snap20250713130127 -> 15.snap20250715212405 [FreeBSD-base]
        FreeBSD-runtime-dev: 15.snap20250710171124 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-runtime-man: 15.snap20250711235756 -> 15.snap20250715201916 [FreeBSD-base]
        FreeBSD-smbutils: 15.snap20250707041723 -> 15.snap20250714223419 [FreeBSD-base]
        FreeBSD-src: 15.snap20250713215434 -> 15.snap20250716113846 [FreeBSD-base]
        FreeBSD-src-sys: 15.snap20250714080908 -> 15.snap20250716085830 [FreeBSD-base]
        FreeBSD-tests: 15.snap20250713190803 -> 15.snap20250715212405 [FreeBSD-base]
        FreeBSD-tests-dbg: 15.snap20250713190803 -> 15.snap20250715212405 [FreeBSD-base]
        FreeBSD-utilities: 15.snap20250713215434 -> 15.snap20250715212405 [FreeBSD-base]
        FreeBSD-utilities-dev: 15.snap20250711053733 -> 15.snap20250715161419 [FreeBSD-base]
        FreeBSD-utilities-man: 15.snap20250713175247 -> 15.snap20250716103437 [FreeBSD-base]

Number of packages to be installed: 1
Number of packages to be upgraded: 31

The process will require 4 MiB more space.
464 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/32] Fetching FreeBSD-bluetooth-15.snap20250715161419.pkg: 100%  182 KiB 186.6kB/s    00:01    
[2/32] Fetching FreeBSD-runtime-15.snap20250715212405.pkg: 100%    2 MiB   1.3MB/s    00:02    
[3/32] Fetching FreeBSD-bhyve-15.snap20250715161419.pkg: 100%  233 KiB 238.4kB/s    00:01    
(...)    
[30/32] Fetching FreeBSD-clibs-15.snap20250715212405.pkg: 100%    2 MiB 406.0kB/s    00:04    
[31/32] Fetching FreeBSD-ipfw-15.snap20250715161419.pkg: 100%   85 KiB  86.7kB/s    00:01    
[32/32] Fetching FreeBSD-clibs-dev-15.snap20250716035604.pkg: 100%   16 MiB   1.7MB/s    00:10    
Checking integrity... done (0 conflicting)
[1/44] Deinstalling FreeBSD-bootloader-dev-15.snap20250711053733...
[1/44] Deleting files for FreeBSD-bootloader-dev-15.snap20250711053733: 100%
[2/44] Deinstalling FreeBSD-clang-dev-15.snap20250707041723...
(...)
[43/44] Extracting FreeBSD-utilities-dev-15.snap20250715161419: 100%
[44/44] Installing FreeBSD-utilities-man-15.snap20250716103437...
[44/44] Extracting FreeBSD-utilities-man-15.snap20250716103437: 100%

After that my system was up to date – upgraded – with PKGBASE concept of the FreeBSD Base System.

Fresh Start Test

I was really positively surprised how well the pkgbasify(8) tool works – so I wanted to do another test – which means:

  • Install FreeBSD 15-CURRENT with PKGBASE packages from the bsdinstall(8) installer.
  • Convert FreeBSD 15-CURRENT classic bsdinstall(8) install with pkgbasify(8) tool.

I used FreeBSD 15-CURRENT image from 2025/06/12 that I already had on the disk.

With ‘classic’ install I selected only BASE and KERNEL to install.

After both installation finished and rebooted – and after I converted the ‘classic’ one into PKGBASE I compared the Base packages installed.

    • BASE INSTALL: 286
    • BASE CONVERT: 290

The pkgbasify(8) conversion went the same as in my other system. I just needed to destroy some leftovers.

FreeBSD # find / -name \*.pkgsave -delete 
FreeBSD # rm -rf /tmp/pkgbasify.*
FreeBSD # rm -rf /var/db/etcupdate

Nothing more I believe.

Things to Watch

For some reason unknown to me – all of the ORIGIN names for Base System packages use base instead of base-part-name convention.

FreeBSD # pkg info -qoa | uniq -c
 290 base
   1 print/indexinfo
   1 ports-mgmt/pkg
   1 sysutils/screen

Other thing that was curious to me was that the FreeBSD that I installed as PKGBASE from the bsdinstall(8) installer did not had the pkg(8) tool initialized … which is strange because the same pkg(8) tool fetched needed Base System packages and installed them.

FreeBSD # pkg info
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/latest, please wait...

While I installed the ‘classic’ way of FreeBSD with only BASE and KERNEL selected – the pkgbasify(8) tool decided to also install tests packages in the process – so I decided to delete it.

FreeBSD # pkg delete \
            FreeBSD-tests-15.snap20250718205142 \
            FreeBSD-tests-dbg-15.snap20250718205142 \
            FreeBSD-tests-dev-15.snap20250707041723 \
            FreeBSD-tests-man-15.snap20250616132851 

After some comparisons with diff(1) command – as parts of it shown below.

… I noticed that the shar(1) command is missing.

CONVERT # shar
usage: shar file ...

PKGBASE # shar
-sh: shar: not found

After some digging I have come to the following conclusions.

First – the shar(1) has been deprecated – https://lists.freebsd.org/archives/dev-commits-src-all/2025-January/050131.html – details in the link – so it makes sense that its not longer available.

Second – if you still need shar(1) command for any reason – https://github.com/cschuber/FreeBSD-shar – its here if needed.

Third – FreeBSD CURRENT moves – and sometimes it moves (and evolves) fast – keep that in mind. Its one of the reason most of use should just use RELEASE or STABLE and use CURRENT only if you know what you are signing for.

That is all from my side for this article – feel free to share your thoughts on this one πŸ™‚

EOF

Crucial FreeBSD Toolkit

While FreeBSD is similar in many concepts to other UNIX systems or to Linux – its good to know exact commands and solutions for various needs.

Today I would like to share all of them – after using FreeBSD for about 20 years – both privately and professionally.

The Table of Contents looks as follows.

  • Scroll Raw FreeBSD Console
  • Suspend/Resume Internals
  • Network Information
  • FreeBSD Tools
  • Additional Mount Points
  • Disk Information and Evaluation
  • Linux lsblk(8) Command
  • Instant Reboot
  • Mount ISO Image
  • Free RAM Memory
  • What is Listening
  • The tar(1) That Does More
  • Create/Extend Raw Volume
  • Filesystem Detection
  • Track Disk Utilization over Time
  • Manage ZFS Boot Environments
  • Sensors
  • Gigabytes in df(8) Command
  • Process Tracing
  • Idle and Realtime Priority
  • The fstab(5) Input
  • Forgotten systat(8) Command
  • Apply devfs(8) Ruleset Live
  • UPDATE 1 – Network Information on macOS

~

Scroll Raw FreeBSD Console

This is probably the first question I asked at the legendary – now killed and not existent – BSDForums.net – how to scroll the raw terminal on the FreeBSD – as I came from the Linux world to FreeBSD – I expected that just [SHIFT]+[PGUP] and [SHIFT]+[PGDN] would work … not on FreeBSD.

On FreeBSD You first need to hit [Scroll Lock] key – then you can scroll the console buffer with [PGUP] and [PGDN] keys.

~

Suspend/Resume Internals

On FreeBSD system one can use to enter sleep (S3) state with zzz(8) command.

To add various tasks that need to happen before sleep happens can be added to the /etc/rc.suspend file.

To add various tasks that need to happen after sleep ends and resume phase happens – use the /etc/rc.resume file instead.

~

Network Information

Linux is well known to rewrite its older ifconfig(8) and router(8) tools into ip(8) command.

FreeBSD still uses (and develops) the ifconfig(8) and route(8) commands – but if you come from Linux – the so called muscle memory will often guide your fingers to type ip(8) command instead of ifconfig(8) – how to cope with that?

The answer is simple – additional shell function that would take care of that.

Below you can copy the needed function.

FreeBSD % grep -A 256 'ip()' /usr/local/etc/zshrc | bat -l sh
  ip() {
    case ${1} in
      (r)
        netstat -Wrn -f inet \
          | grep -A 256 '^Destination' \
          | awk '{printf("%20s  %-18s  %18s  %-7s\n", $1, $2, $4, $3)}'
          ;;
      (l)
        netstat -Win -f link \
          | awk '{printf("%20s  %-18s  %18s  %-7s\n", $1, $4, $3, $2)}'
          ;;
      (a|*)
        netstat -Win -f inet \
          | awk '{printf("%20s  %-18s  %18s  %-7s\n", $1, $4, $3, $2)}'
          ;;
    esac
  }

FreeBSD % ip a
                Name  Address                        Network  Mtu    
                 lo0  127.0.0.1                  127.0.0.0/8  -      
           vm-public  10.1.1.1                   10.1.1.0/24  -      
          vm-VLAN239  172.27.33.193         172.27.33.192/26  -      
                 ue0  192.168.50.3           192.168.50.0/24  -      

FreeBSD % ip r
         Destination  Gateway                          Nhop#  Flags  
             default  192.168.50.114                      11  UGS    
         10.1.1.0/24  link#5                               2  U      
            10.1.1.1  link#2                               3  UHS    
           127.0.0.1  link#2                               1  UH     
    172.27.33.192/26  link#6                               4  U      
       172.27.33.193  link#2                               5  UHS    
     192.168.50.0/24  link#3                               6  U      
        192.168.50.3  link#2                               7  UHS    

I still need to work with Linux systems from time to time – so having a working ip(8) command equivalent on FreeBSD is welcoming.

… and if you are curious why I always use -prism option set for the uname(1) command – besides that it shows all information that is needed – its my personal tribute to Edward Snowden – the man who bravely whistleblowered the PRISM program – KUDOS to You mate. Not sure how much accurate is the movie – Snowden (2016) – but I really enjoyed it – especially after the Joseph Gordon-Levitt performance in the Dark Knight Rises (2012) and Premium Rush (2012) movies.

~

FreeBSD Tools

By default the FreeBSD ifconfig(8) command displays information in hexadecimal values like netmask 0xffffff00 for example instead of /24 … but you can use -f cidr option to switch to the latter.

You can also make that permanent with IFCONFIG_FORMAT=inet:cidr variable exported within your shell configs with either export(1) or setenv(1) depending on your preferred shell.

FreeBSD # ifconfig ue0
ue0: flags=8843 metric 0 mtu 1500
        options=0
        ether 02:25:6d:76:1e:7b
        inet 192.168.50.3 netmask 0xffffff00 broadcast 192.168.50.255
        nd6 options=29

FreeBSD # export IFCONFIG_FORMAT=inet:cidr

FreeBSD # ifconfig ue0
ue0: flags=8843 metric 0 mtu 1500
        options=0
        ether 02:25:6d:76:1e:7b
        inet 192.168.50.3/24 broadcast 192.168.50.255
        nd6 options=29

~

Additional Mount Points

In about 2013 I wrote and published automount(8) that utilizes FreeBSD devd(8) daemon to automatically mount and serve removable media and disks. Twelve years later – after many updates and improvements – I still use and maintain that very solution.

While using FreeBSD there came one additional need that automount(8) does not cover. What is additionally mounted and what I can unmount to get to the ‘default’ state of mounted filesystems?

In the past I checked the output of mount(8) command – and acted accordingly – that took time. Every. Single. Time.

That pushed me to kinda semi automate it – to not waste much more time on that.

Meet mnt.sh command (script).

It has two functions – first to list all filesystems and devices that are mounted additionally to what FreeBSD system has after the boot – or in Jails – or in Bhyve VMs. Secondly it allows to successfully unmount all of them with -u option. Nothing more. Nothing less.

~

Disk Information and Evaluation

When people think about that topic – they often either think about some S.M.A.R.T. related tools or benchmarks … and the diskinfo(8) can tell you fast how good the disk performs. Just start it against any disk with -cvt arguments and you know what You need to know.

In the terminal.

FreeBSD % diskinfo -ctv DISK

That is most that you need for a start.

~

Linux lsblk(8) Command

While for most of the time I prefer FreeBSD tools for the job – exceptions sometimes happen – and lsblk(8) is one of such welcoming exception. It lists all disks/partitions/filesystems in a system that FreeBSD does not with its Geom disk list or gpart show commands – or just not in a condensed way that I really like.

It took me some time to rewrite the meritum of the tool in the POSIX /bin/sh shell – but now its available at lsblk package on FreeBSD.

You can read more about lsblk(8) for FreeBSD on the List Block Devices on FreeBSD lsblk(8) Style page.

When you do not have lsblk(8) installed there is also some fallback in geom(8) command.

FreeBSD % geom -t
Geom               Class      Provider
nda0               DISK       nda0
  nda0             DEV       
  nda0             PART       nda0p1
    nda0p1         DEV       
    nda0p1         LABEL      gpt/efiboot0
      gpt/efiboot0 DEV       
  nda0             PART       nda0p2
    nda0p2         DEV       
    nda0p2         LABEL      gpt/gptboot0
      gpt/gptboot0 DEV       
  nda0             PART       nda0p3
    nda0p3         DEV       
    nda0p3         LABEL      gpt/swap0
      gpt/swap0    DEV       
      swap         SWAP      
  nda0             PART       nda0p4
    nda0p4         DEV       
    nda0p4.eli     ELI        nda0p4.eli
      nda0p4.eli   DEV       
      zfs::vdev    ZFS::VDEV 
nda1               DISK       nda1
  nda1             DEV       
  nda1             PART       nda1p1
    nda1p1         DEV       
    nda1p1.eli     ELI        nda1p1.eli
      nda1p1.eli   DEV       
      zfs::vdev    ZFS::VDEV 
da0                DISK       da0
  da0              DEV       

Its far from perfect – but its a reasonable lsblk(8) FreeBSD Base System replacement.

~

Instant Reboot

Nothing really fancy – but sometimes needed – imagine some process (or mount) went sideways and usual reboot(8) or shutdown(8) commands are not able to do anything to reboot a locked system.

This is when this tip is useful. Its equivalent of Linux -r flag for the reboot(8) command. Restart the system NOW – in that single second – no questions asked. We need to make sure we will disable crash dumps before doing that ‘instant’ restart with dumpon off command.

FreeBSD # dumpon off
FreeBSD # sysctl debug.kdb.panic=1

After issuing that command you can be SURE that its restated.

~

Mount ISO Image

Mounting ISO image on Linux systems requires one step while it requires two steps on FreeBSD.

Lets bring that up to par with loop.sh script.

FreeBSD % loop.sh -h
usage: loop.sh image.iso /mnt/point

Example usage below.

Keep in mind that even loop.sh image.iso ISO command would work.

~

Free RAM Memory

You can get the amount of free RAM from – for example – the top(1) command – but a lot of people already have the free(1) command. Fortunately you can install freecolor package on FreeBSD and have the same functionality.

FreeBSD # pkg install -y freecolor

FreeBSD # freecolor -o -m
             total       used       free     shared    buffers     cached
Mem:         31728       6874      24854          0          0          0
Swap:         2048          0       2048

FreeBSD # pkg which -o $( which freecolor )
/usr/local/bin/freecolor was installed by package sysutils/freecolor

~

What is Listening

The question that every sysadmin asks himself everytime server is managed.

FreeBSD offers really great sockstat(8) command for that.

FreeBSD # sockstat -l4
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     sshd       42298 8   tcp4   *:22                  *:*
root     nfsd       90131 5   tcp4   *:2049                *:*
root     cupsd      81818 7   tcp4   127.0.0.1:631         *:*

~

The tar(1) That Does More

On FreeBSD the tar(1) command uses libarchive(3) – it allows tar(1) to also read and extract – for example – ISO files.

FreeBSD % which tar      
/usr/bin/tar

FreeBSD % tar -tf ~/vm/iso/FreeBSD-15.0-CURRENT-amd64-20250612-e6928c33f60c-277883-disc1.iso | head
.
bin
bin/cat
bin/chflags
bin/chio
bin/chmod
bin/cp
bin/cpuset
bin/csh
bin/tcsh

~

Create/Extend Raw Volume

On FreeBSD that is covered by the truncate(1) command.

For example – want to expand your vm-bhyve VM disk up to 100 GB in size? This is the command.

FreeBSD # cd /vm/poudriere   

FreeBSD # truncate -s 100g disk0.img      

~

Filesystem Detection

When I started with automount(8) I could only rely on file -s ... command for filesystem detection.

Some time after automount(8) introduction the fstyp(8) command was introduced.

It is more or less simplified way to check what filesystem is on a device – and its really useful.

FreeBSD % fstyp /dev/nda0p1
msdosfs

~

Track Disk Utilization over Time

One of the commands I love from FreeBSD is this one – gstat(8) – just shows in desired interval how many IOPS and bandwidth the disks provide.

FreeBSD # gstat -p -I 3s
dT: 0.010s  w: 1.000s
 L(q)  ops/s    r/s   kBps   ms/r    w/s   kBps   ms/w   %busy Name
    0    486    486  20228  0.214      0      0  0.000   10.4| nda0
    0      0      0      0  0.000      0      0  0.000    0.0| nda1
    0      0      0      0  0.000      0      0  0.000    0.0| da0

It also comes with useful colors – and there is also Rust version on the FreeBSD Ports as sysutils/gstat-rs port available.

~

Manage ZFS Boot Environments

Right now FreeBSD has bectl(8) in the base – which works well. There is also mine beadm(8) available as sysutils/beadm package that has one important additional reroot option – ZFS Boot Environments Revolutions – more on that here.

Once You understand how great protection ZFS Boot Environments give – you will never want to live without them.

~

Sensors

Linux comes with a sensors(8) command that prints various sensors temperatures etc. While similar information was available on FreeBSD – it was never gathered in one single place … up till I wrote the sensors(8) command for FreeBSD.

Installation is pretty straightforward.

FreeBSD # mkdir -p ~/bin
FreeBSD # fetch -o ~/bin/sensors https://raw.githubusercontent.com/vermaden/sensors/master/sensors
FreeBSD # chmod +x ~/bin/sensors

If you would like to read more about it – Sensors Information on FreeBSD – you will find it here.

~

Gigabytes in df(8) Command

Both IBM AIX and FreeBSD UNIX systems have one advantage that Linux df(8) command – they both support -g flag that will display usage in gigabytes. Unfortunately with Linux one you can either have megabytes at most.

The one on IBM AIX looks slightly different – but the end result is similar.

~

Process Tracing

On Linux systems many times I needed to use useful strace(8) command. On IBM AIX and FreeBSD UNIX its called truss(8) but does the same thing.

FreeBSD # truss -s 30 /bin/ls /tmp/gimp 2>&1 | grep /
open("/etc/libmap.conf",O_RDONLY|O_CLOEXEC,030250030030) = 3 (0x3)
read(3,"includedir /usr/local/etc/libm"...,35)   = 35 (0x23)
open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) = 3 (0x3)
open("/usr/local/etc/libmap.d/mesa.conf",O_RDONLY|O_CLOEXEC,0165) = 4 (0x4)
open("/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,016177641474) = 3 (0x3)
pread(3,"/lib:/usr/lib:/usr/lib/compat:"...,437,0x80) = 437 (0x1b5)
open("/lib/libutil.so.9",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
open("/lib/libtinfow.so.9",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
open("/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
readlink("/etc/malloc.conf",0x2b93923aae70,1024) ERR#2 'No such file or directory'
open("/usr/share/locale/en_US.UTF-8/LC_COLLATE",O_RDONLY|O_CLOEXEC,022216535310) = 3 (0x3)
open("/usr/share/locale/en_US.UTF-8/LC_CTYPE",O_RDONLY|O_CLOEXEC,022216532030) = 3 (0x3)
open("/usr/share/locale/en_US.UTF-8/LC_MONETARY",O_RDONLY|O_CLOEXEC,022216533616) = 3 (0x3)
open("/usr/share/locale/en_US.UTF-8/LC_NUMERIC",O_RDONLY|O_CLOEXEC,022216533636) = 3 (0x3)
open("/usr/share/locale/en_US.UTF-8/LC_TIME",O_RDONLY|O_CLOEXEC,022216533656) = 3 (0x3)
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES",O_RDONLY|O_CLOEXEC,022216533656) = 3 (0x3)
fstatat(AT_FDCWD,"/tmp/gimp",{ mode=drwxr-xr-x ,inode=354,size=3,blksize=4096 },0x0) = 0 (0x0)
open("/tmp/gimp",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,016033264547) = 4 (0x4)

One can also use DTrace if needed.

~

Idle and Realtime Priority

I do not remember how many times I wanted a process – like make(1) for FreeBSD Ports compiling for example – would REALLY do not interfere with what I am interactively doing right now – have as low priority as possible … and the good oldschool renice(8) was just not enough.

This is where FreeBSD idprio(1) and rtprio(1) command come handy – for idle and realtime respectively. If you want to allow a regular user to be able to use them – add that user to idletime or realtime groups.

While the renice(8) command takes argument from -19 to 20 – both idprio(1) and rtprio(1) commands take argument from 0 to 31. Higher the value – bigger the power. For example idprio 31 command would make a command ultra low in the priority – that when anything else uses CPU – that command will literally have to wait till its not πŸ™‚

~

The fstab(5) Input

When you are on a Linux system – the /etc/mtab file helps mounted filesystems in fstab(5) format. That helps if you mounted filesystem by hand and now want to add that information to /etc/fstab file to make it permanent. On Linux you would do something like that:

Linux # tail -1 /etc/mtab >> /etc/fstab
Linux # vi /etc/fstab

On FreeBSD there is no /etc/mtab file – but there is -p file for mount(8) command – that prints mounted filesystems in fstab(5) format – so on FreeBSD you would do something like that instead.

FreeBSD # mount -p | tail -1 >> /etc/fstab
FreeBSD # vi /etc/fstab

~

Forgotten systat(8) Command

Its rarely known – that systat(8) command – I often use it for example to check how much the network interfaces are utilized.

FreeBSD # systat -if 1

                    /0   /1   /2   /3   /4   /5   /6   /7   /8   /9   /10
     Load Average   ||

      Interface           Traffic               Peak                Total
           tap0  in      0.000 KB/s          0.000 KB/s           10.095 MB
                 out     0.174 KB/s          0.174 KB/s          350.764 MB

     vm-VLAN239  in      0.160 KB/s          0.160 KB/s           22.615 MB
                 out     0.174 KB/s          0.174 KB/s          351.268 MB

      vm-public  in      0.160 KB/s          0.160 KB/s           12.183 MB
                 out     0.000 KB/s          0.000 KB/s            0.000 KB

            lo0  in      0.160 KB/s          0.160 KB/s          113.110 MB
                 out     0.000 KB/s          0.000 KB/s           95.753 MB

            em0  in      8.569 KB/s         25.965 KB/s           37.437 GB
                 out     6.907 KB/s        127.806 KB/s           82.828 GB

The next one should be familiar to IBM AIX fans – as it kinda reminds topas(8) command.

FreeBSD # systat -vmstat

    6 users    Load  0.31  0.61  0.62                  Jun 24 15:29:45
   Mem usage:  89%Phy  5%Kmem                           VN PAGER   SWAP PAGER
Mem:      REAL           VIRTUAL                        in   out     in   out
       Tot   Share     Tot    Share     Free   count
Act 24451M    995M   7391G     116G    3591M   pages
All 24515M   1058M   7391G     117G                       ioflt  Interrupts
Proc:                                                     cow    3353 total
  r   p   d    s   w   Csw  Trp  Sys  Int  Sof  Flt    49 zfod        atkbd0 1
         33 1364        7K   53   2K   2K    2   52       ozfod       acpi0 9
                                                         %ozfod       psm0 12
 0.6%Sys   0.5%Intr  1.2%User  0.0%Nice 97.6%Idle         daefr   145 cpu0:timer
|    |    |    |    |    |    |    |    |    |    |       prcfr   129 cpu1:timer
+                                                      25 totfr   121 cpu2:timer
                                           dtbuf          react   129 cpu3:timer
Namei     Name-cache   Dir-cache   1102463 maxvn          pdwak   115 cpu4:timer
   Calls    hits   %    hits   %     17701 numvn     1108 pdpgs    86 cpu5:timer
     196     188  96                  1404 frevn          intrn   207 cpu6:timer
                                                    2729M wire    115 cpu7:timer
Disks  nda0  nda1   da0 pass0 pass1 pass2           2616M act    1961 xhci0 128
KB/t   2.67  1024  0.00  0.00  0.00  0.00             21G inact       nvme0:admi
tps       1     1     0     0     0     0           1542M laund       nvme0:io0
MB/s   0.00  0.80  0.00  0.00  0.00  0.00           3591M free        nvme0:io1
%busy     0     0     0     0     0     0               0 buf       1 nvme0:io2
                                                                      nvme0:io3
                                                                      nvme1:admi
                                                                    1 nvme1:io0
                                                                      nvme1:io1
                                                                      nvme1:io2
                                                                      nvme1:io3
                                                                  188 hdac0 139
                                                                  147 em0:irq0
                                                                    8 vgapci0
                                                                      iwm0 142
                                                                      xhci1 143

The systat(8) command even comes with ZFS ARC monitor.

FreeBSD # systat -zarc

                       Total     MFU     MRU    Anon     Hdr   L2Hdr   Other
     ZFS ARC            641M    303M    234M   1917K   4525K       0  99181K

                                Rate   Hits Misses | Total Rate   Hits Misses
     arcstats                  :  0%      0      0 |        96%   177M  6695k
     arcstats.demand_data      :  0%      0      0 |        98% 41577k   633k
     arcstats.demand_metadata  :  0%      0      0 |        96%   134M  4870k
     arcstats.prefetch_data    :  0%      0      0 |         4%  18251   425k
     arcstats.prefetch_metadata:  0%      0      0 |        64%  1371k   768k
     zfetchstats               :  0%      0      0 |        39% 13054k 20324k
     arcstats.l2               :  0%      0      0 |         0%      0      0







Disks  nda0  nda1   da0 pass0 pass1 pass2
KB/t   0.00  0.00  0.00  0.00  0.00  0.00
tps       0     0     0     0     0     0
MB/s   0.00  0.00  0.00  0.00  0.00  0.00
%busy     0     0     0     0     0     0


~

Apply devfs(8) Ruleset Live

One of the things I found useful – especially for debugging – was how to apply new devfs(8) ruleset to running Jail.

FreeBSD # devfs -m /jail/dns/dev ruleset 130

Hope that helps.

~

Summary

Feel free to share your favorite useful FreeBSD commands that make your life better.

~

UPDATE 1 – Network Information on macOS

Thanks to @matuzalem I can add variation that works better on macOS – thanks for sharing.

ip() {
  case ${1} in
    (r)
      printf "%20s %-18s %18s %-7s\n" "Name" "Address" "Network" "Mtu"
      netstat -Wrn -f inet \
        | grep -A 256 '^Destination' \
        | awk '{printf("%20s %-18s %18s %-7s\n", $1, $2, $4, $3)}'
      ;;
    (l)
      printf "%20s %-18s %18s %-7s\n" "Name" "Address" "Network" "Mtu"
      netstat -Win -f link \
        | grep -vE 'lo[0-9]*|awdl[0-9]*|llw[0-9]*|stf[0-9]*|gif[0-9]*|pflog[0-9]*|pktap[0-9]*' \
        | awk '{printf("%20s %-18s %18s %-7s\n", $1, $4, $3, $2)}'
      ;;
    (a|*)
      printf "%20s %-18s %18s %-7s\n" "Name" "Address" "Network" "Mtu"
      netstat -Win -f inet \
        | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" \
        | awk '{printf("%20s %-18s %18s %-7s\n", $1, $4, $3, $2)}'
      ;;
  esac
}

Enjoy πŸ™‚

EOF

Poudriere Inside FreeBSD VNET Jail

I usually prefer to run Poudriere inside FreeBSD Bhyve VM – its just faster to setup – but as sometimes its desired to use the power of FreeBSD Jails instead – here is how to do this.

Host Setup

First we will setup the host system.

To make things faster we will install the host system using FreeBSD provided raw system image – as described – Install FreeBSD with One Command – here for example. You can also use the bsdinstall(8) installer it needed.

Here is how we expect the host system to look like.

HOST # cat /etc/rc.conf
hostname="host.lab.org"
ifconfig_vtnet0="inet 10.1.1.123/24 up"
defaultrouter="10.1.1.1"
cloned_interfaces="bridge0"
ifconfig_bridge0="up addm vtnet0"
gateway_enable=YES
kld_list="${kld_list} linux linux64"
sshd_enable="YES"
zfs_enable="YES"
nginx_enable="YES"

We will need to configure the devfs.rules file.

HOST # cat /etc/devfs.rules
[poudriere=120]
add include $devfsrules_jail
add path 'fd*' unhide

For some reason the /etc/jail.conf file must exist if you use /etc/jail.conf.d/ dir.

HOST # :> /etc/jail.conf

Now – the Poudriere Jail config – I will call it joudriere for convenience.

HOST # cat /etc/jail.conf.d/joudriere.conf
joudriere {

  # GLOBAL
    exec.start = "/bin/sh /etc/rc";
    exec.stop  = "/bin/sh /etc/rc.shutdown";
    exec.consolelog = "/var/log/jail_console_${name}.log";
    exec.clean;
    mount.devfs;
    host.hostname = joudriere.lab.org;
    path = /jail/${name};

  # PERMISSIONS
    allow.chflags;
    allow.read_msgbuf;
    allow.mlock;
    allow.chflags;
    allow.mount;
    allow.mount.devfs;
    allow.mount.nullfs;
    allow.mount.fdescfs;
    allow.mount.nullfs;
    allow.mount.tmpfs;
    allow.mount.zfs=true;
    allow.mount.procfs;
    allow.mount.linprocfs;
    allow.raw_sockets;
    allow.socket_af;
    allow.sysvipc;
    devfs_ruleset = 120;
    enforce_statfs = 1;
    children.max = 200;
    sysvmsg=new;
    sysvsem=new;
    sysvshm=new;
 
  # VNET/VIMAGE
    vnet;
    vnet.interface = "${if}b";

  # NETWORKS/INTERFACES
    $id = "234";
    $ip = "10.1.1.${id}/24";
    $gw = "10.1.1.1";
    $br = "vm-public";
    $if = "epair${id}";

  # ADD TO bridge0 INTERFACE
    exec.prestart += "ifconfig ${if} create up";
    exec.prestart += "ifconfig ${if}a up descr jail:${name}";
    exec.prestart += "ifconfig ${br} addm ${if}a up";
    exec.start    += "ifconfig ${if}b ${ip} up";
    exec.start    += "route add default ${gw}";
    exec.poststop += "ifconfig ${if}a destroy";
}

We will need to extract FreeBSD base.txz there.

HOST # mkdir -p /jail/joudriere /jail/BASE

HOST # fetch -o /jail/BASE/14.3-RELEASE-base.txz 'https://download.freebsd.org/releases/amd64/14.3-RELEASE/base.txz'

HOST # tar --unlink -C /jail/joudriere -xf /jail/BASE/14.3-RELEASE-base.txz

Now we can start our Poudriere joudriere Jail and enter it for more setup.

HOST # service jail onestart joudriere

HOST # env PS1='joudriere # ' jexec joudriere /bin/sh

Jail Setup

Some basic stuff for a start.

joudriere # service sshd enable

joudriere # service sshd start

joudriere # service nginx enable

joudriere # service nginx start

joudriere # sed -i '' s.quarterly.latest.g /etc/pkg/FreeBSD.conf

joudriere # echo nameserver 1.1.1.1 > /etc/resolv.conf

joudriere # pkg install -y poudriere-devel tree screen git-lite

The Jail setup main /etc/rc.conf config file.

joudriere # cat /etc/rc.conf
sshd_enable="YES"
nginx_enable="YES"

Now the rest of the Poudriere setup commands.

joudriere # export SSL=/usr/local/etc/ssl

joudriere # mkdir -p \
              /usr/ports/distfiles \
              ${SSL}/keys \
              ${SSL}/certs

joudriere # chmod 0600 ${SSL}/keys

joudriere # openssl genrsa -out ${SSL}/keys/poudriere.key 4096

joudriere # openssl rsa \
              -in  ${SSL}/keys/poudriere.key -pubout \
              -out ${SSL}/certs/poudriere.cert

joudriere # mkdir /var/ccache

joudriere # cat << EOF > /usr/local/etc/poudriere.conf
ZPOOL=zroot
FREEBSD_HOST=ftp://ftp.freebsd.org
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=/usr/local/poudriere/data
DISTFILES_CACHE=/usr/ports/distfiles
CCACHE_DIR=/var/ccache
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key
URL_BASE=http://0.0.0.0/
USE_TMPFS=no
TMPFS_LIMIT=12
MAX_MEMORY=12
PARALLEL_JOBS=4
PREPARE_PARALLEL_JOBS=4
MAX_FILES=4096
KEEP_OLD_PACKAGES=yes
KEEP_OLD_PACKAGES_COUNT=3
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
RESTRICT_NETWORKING=no
EOF

joudriere # mkdir -p /usr/local/poudriere/data/logs/bulk

joudriere # ln -s \
              /usr/local/etc/ssl/certs/poudriere.cert \
              /usr/local/poudriere/data/logs/bulk/poudriere.cert

joudriere # cat << EOF > /usr/local/etc/poudriere.d/make.conf
# general
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes

# ccache(1)
WITH_CCACHE_BUILD=yes

# ports options
FORCE_MAKE_JOBS=yes
MAKE_JOBS_UNSAFE=yes
MAKE_JOBS_NUMBER=8
EOF

joudriere # sed -i '' -E 's|text/plain[\t\ ]*txt|text/plain txt log|g' /usr/local/etc/nginx/mime.types

joudriere # cat << EOF > /usr/local/etc/nginx/nginx.conf
events {
  worker_connections 1024;
}

http {
  include      mime.types;
  default_type application/octet-stream;

  server {
    listen 80 default;
    server_name 0.0.0.0;
    root /usr/local/share/poudriere/html;

    location /data {
      alias /usr/local/poudriere/data/logs/bulk;
      autoindex on;
    }

    location /packages {
      root /usr/local/poudriere/data;
      autoindex on;
    }
  }
}
EOF

joudriere # mkdir /root/.cache

joudriere # ln -sf /var/ccache /root/.cache/ccache

joudriere # cat << EOF > /var/ccache/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
hash_dir = false
EOF

Poudriere Setup

We will now fetch FreeBSD release and also the FreeBSD Ports tree.

joudriere # poudriere jail -c -j 14-3-R-amd64 -v 14.3-RELEASE

joudriere # poudriere jail -l
JAILNAME     VERSION      OSVERSION ARCH  METHOD TIMESTAMP           PATH
14-3-R-amd64 14.3-RELEASE 1403000   amd64 http   2025-07-01 18:15:02 /usr/local/poudriere/jails/14-3-R-amd64

joudriere # poudriere ports -c

joudriere # poudriere ports -l
PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2025-07-01 18:21:08 /usr/local/poudriere/ports/default

Now a final test – the poudriere-bulk(8) job.

Without better target I have chosen to build devel/cmake package.

joudriere # poudriere bulk -j 14-3-R-amd64 -b latest devel/cmake
[00:00:00] Creating the reference jail... done
[00:00:02] Mounting system devices for 14-3-R-amd64-default
[00:00:02] Mounting ccache from: /var/ccache
[00:00:02] Mounting ports from: /usr/local/poudriere/ports/default
[00:00:02] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default
[00:00:02] Mounting distfiles from: /usr/ports/distfiles
[00:00:02] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf
/etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf
[00:00:02] Starting jail 14-3-R-amd64-default
Updating /var/run/os-release done.
[00:00:02] Will build as root:wheel (0:0)
[00:00:03] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS
[00:00:03] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no
[00:00:05] Ports top-level git hash: 385ccb2a2 
[00:00:05] Acquiring build logs lock for 14-3-R-amd64-default... done
[00:00:05] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2025-07-03_00h26m17s
[00:00:05] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2025-07-03_00h26m17s
[00:00:05] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports
[00:00:06] Gathering ports metadata
(...)

Seems to be working properly.

EOF

Failed Backup Server Build

When you read my blog articles and stuff – you may get the idea that everything I do – just happens to be right and that I succeed at every attempt. This article is here to remind you that I also often fail trying to do what was suppose to be great ‘on paper’ before doing it. Some call it experience … but the problem with experience is that you get it just after you needed it.

Out of Space

While I was relatively happy with my earlier backup box – Perfect NAS Solution – described here – it had one drawback. Space … lack of it. I did not wanted to invest in 8 TB NVMe SSD – so I used 4 TB NVMe SSD 2280 and 2 TB NVMe SSD 2230 as this AMD Ryzen based box had only two M.2 slots for storage … and getting 4 TB 2230 SSD is also very expensive.

% df -g /data
Filesystem 1G-blocks Used Avail Capacity  Mounted on
data/data      7311 4833  2478    66%    /data
 
% zpool list data
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
data   7.27T  4.72T  2.55T        -         -     1%    64%  1.00x    ONLINE  -

As I got 2 TB and 4 TB I created two independent ZFS pools on them and then I created needed datasets for needed directories from the /data dir … but as time as passed some grew too much – like /data/download for example … so I started to manually move these datasets between these SSDs … and that just started to require too much micro management I did not wanted to waste time on.

Perfect Hardware for the Job

After checking what is available on the market I decided to get new small box – this time Intel N100 (or N150) based – with multiple M.2 slots. I was able to find even smaller then AMD Ryzen box computer that would have not only four M.2 slots but even FIVE of them.

The fifth one is hidden inside and fits nicely the 2 TB NVMe SSD 2230 that I already had – I also got four 2 TB 2280 ones and 16 GB RAM as seen on the above picture. The system is not fanless – but a small occasional fan does not hurt much – as AMD Ryzen box also had fan that almost never started – and it had much larger TDP then the 6 W TDP of Intel N100 CPU.

This little gem even have additional USB-A slot inside – so you can fit Lexar S47 32 GB USB pendrive there – not to mention TWO Intel 2.5 GB network cards.

Here is how Maiyunda M1S compares against previous GenMachine solution.

Keep it Cool

The only thing that I was worried about was cooling of the NVMe SSDs – to make them not hot enough – and while the box has two 2.5 GbE ports (supported on FreeBSD by igc(4) driver) – speeds like 50-70MB/s are more then enough for my needs (assuming that LAN would be used) – as I also am used to 10-11 MB/s when WiFi is involved … and I came prepared when it comes to cooling.

I attached radiators to all of the SSDs – the internal one had smaller heatsink (and it was more hot) but the top ones got really nice piece of aluminum on them – attached using 15W/mK silicone thermal pad.

Huge Metal Fan

While I prefer passive cooled solutions – its not always possible to get all the features in decent prices in fanless mode.

After tweaking various BIOS settings I came to Hardware Monitor for thermal related stuff … and it seems that even that small Intel N100 with 6W TDP can be REALLY hot. After messing with the settings of the internal fan – and keeping it running all the time at about 3000 RPM – I settles on about 60oC temperature.

The temperatures reported with sensors(8) were high but not problematic. As you can expect the internal NVMe SSD was little warmer.

# sensors
 
            BATTERY/AC/TIME/FAN/SPEED 
 ------------------------------------ 
               dev.cpu.0.cx_supported: C1/1/0 
                   dev.cpu.0.cx_usage: 100.00% last 6353us
                       dev.cpu.0.freq: 800 
                hw.acpi.cpu.cx_lowest: C1 
                            powerd(8): running
 
                  SYSTEM/TEMPERATURES 
 ------------------------------------ 
      hw.acpi.thermal.tz0.temperature: 27.9C (max: 110.1C)
                dev.cpu.0.temperature: 68.0C (max: 105.0C)
                dev.cpu.1.temperature: 67.0C (max: 105.0C)
                dev.cpu.2.temperature: 67.0C (max: 105.0C)
                dev.cpu.3.temperature: 67.0C (max: 105.0C)
 
                   DISKS/TEMPERATURES 
 ------------------------------------ 
              smart.nvme0.temperature: 74.0C
              smart.nvme1.temperature: 39.0C
              smart.nvme2.temperature: 38.0C
              smart.nvme3.temperature: 39.0C
              smart.nvme4.temperature: 38.0C

I am Speed

This is how all the disks looked like using lsblk(8) command.

# lsblk -d
DEVICE SIZE MODEL
da0     29G Lexar USB Flash Drive
nda0   1.9T WD PC SN740 SDDPTQE-2T00
nda1   1.9T ADATA SX8200PNP
nda2   1.9T ADATA SX8200PNP
nda3   1.9T ADATA SX8200PNP
nda4   1.9T ADATA SX8200PNP
-       10T TOTAL SYSTEM STORAGE

Quick ‘benchmark’ of the NVMe SSD drives using diskinfo(8) is shown below.

# for I in 0 1 2 3 4; do diskinfo -vt nda${I}; echo; done | grep -e nda -e side
nda0
        outside:       102400 kbytes in   0.137933 sec =   742389 kbytes/sec
        inside:        102400 kbytes in   0.136937 sec =   747789 kbytes/sec
nda1
        outside:       102400 kbytes in   0.136848 sec =   748275 kbytes/sec
        inside:        102400 kbytes in   0.135698 sec =   754617 kbytes/sec
nda2
        outside:       102400 kbytes in   0.136665 sec =   749277 kbytes/sec
        inside:        102400 kbytes in   0.135783 sec =   754144 kbytes/sec
nda3
        outside:       102400 kbytes in   0.190700 sec =   536969 kbytes/sec
        inside:        102400 kbytes in   0.135555 sec =   755413 kbytes/sec
nda4
        outside:       102400 kbytes in   0.136825 sec =   748401 kbytes/sec
        inside:        102400 kbytes in   0.135868 sec =   753673 kbytes/sec

I forgot to mention one important thing – the Intel N100 CPU maximum number of PCIe lanes is 9.


    SPEC       LANE         X1         X2         X4       X8          X16
PCIe 1.x   2.5 GT/s    0.5GB/s    1.0GB/s    2.0GB/s    4.0GB/s    8.0GB/s
PCIe 2.x   5.0 GT/s    1.0GB/s    2.0GB/s    4.0GB/s    8.0GB/s   16.0GB/s
PCIe 3.x   8.0 GT/s    2.0GB/s    4.0GB/s    8.0GB/s   16.0GB/s   32.0GB/s
PCIe 4.x  16.0 GT/s    4.0GB/s    8.0GB/s   16.0GB/s   32.0GB/s   64.0GB/s
PCIe 5.x  32.0 GT/s    8.0GB/s   16.0GB/s   32.0GB/s   64.0GB/s  128.0GB/s
PCIe 6.x  64.0 GT/s   16.0GB/s   32.0GB/s   64.0GB/s  128.0GB/s  256.0GB/s

That means that all these NVMe SSDs work not at their maximum speed like up to 8000MB/s with PCIe 3.0 4x lanes. Each of these NVMe have only ONE (1) PCIe 3.0 lane – that means the maximum speed each of them would be quarter of their normal operation – this thing alone would make heat generated by them in quarter.

ZFS Part

So … I had the system running – I had the drives attached – I created ZFS pool … and for the first time I decided that ZFS based encryption is good enough – so I did not used geli(8) this time. The plan was to use RAID5 (raidz) setup here – so I will have some redundancy again.

# zpool create data raidz nda0 nda1 nda2 nda3 nda4

# zpool list data
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
data   9.31T   912K  9.31T        -         -     0%     0%  1.00x    ONLINE  -
 
# zpool status data
  pool: data
 state: ONLINE
config:
 
        NAME        STATE     READ WRITE CKSUM
        data        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            nda0    ONLINE       0     0     0
            nda1    ONLINE       0     0     0
            nda2    ONLINE       0     0     0
            nda3    ONLINE       0     0     0
            nda4    ONLINE       0     0     0
 
errors: No known data errors

# zfs set recordsize=1m data

# zfs set compression=zstd data

# zfs set atime=off data

# zfs set mountpoint=none data

# zfs set mountpoint=/data data/data

# zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt data/data

# zfs mount -a

… but one of the NVMe SSD 2280 drives came broken – lots of read/write errors and entirely ‘broken’ S.M.A.R.T report.

Broken Drive and Resilver

That allowed me to test the ZFS resilver on these drives – you can see for yourself how it went below.

# zpool status
  pool: data
 state: DEGRADED
status: One or more devices could not be used because the label is missing or
        invalid.  Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-4J
  scan: scrub repaired 768K in 00:02:50 with 0 errors on Sun May 18 13:29:47 2025
config:
 
        NAME                      STATE     READ WRITE CKSUM
        data                      DEGRADED     0     0     0
          raidz1-0                DEGRADED     0     0     0
            nda0                  ONLINE       0     0     0
            13389973369551797347  UNAVAIL      0     0     0  was /dev/nda1
            nda2                  ONLINE       0     0     0
            nda3                  ONLINE       0     0     0
            nda4                  ONLINE       0     0     0
 
errors: No known data errors
 
# zpool replace data 13389973369551797347 /dev/nda1
 
# zpool status data
  pool: data
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Wed May 21 20:33:21 2025
        198G / 198G scanned, 3.95G / 197G issued at 1011M/s
        806M resilvered, 2.00% done, 00:03:15 to go
config:
 
        NAME                        STATE     READ WRITE CKSUM
        data                        DEGRADED     0     0     0
          raidz1-0                  DEGRADED     0     0     0
            nda0                    ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              13389973369551797347  UNAVAIL      0     0     0  was /dev/nda1/old
              nda1                  ONLINE       0     0     0  (resilvering)
            nda2                    ONLINE       0     0     0
            nda3                    ONLINE       0     0     0
            nda4                    ONLINE       0     0     0
 
errors: No known data errors
 
# zpool status data
  pool: data
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Wed May 21 20:33:21 2025
        198G / 198G scanned, 95.0G / 197G issued at 1.22G/s
        19.1G resilvered, 48.16% done, 00:01:23 to go
config:
 
        NAME                        STATE     READ WRITE CKSUM
        data                        DEGRADED     0     0     0
          raidz1-0                  DEGRADED     0     0     0
            nda0                    ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              13389973369551797347  UNAVAIL      0     0     0  was /dev/nda1/old
              nda1                  ONLINE       0     0     0  (resilvering)
            nda2                    ONLINE       0     0     0
            nda3                    ONLINE       0     0     0
            nda4                    ONLINE       0     0     0
 
errors: No known data errors
 
# gstat -p -I 1s
dT: 1.009s  w: 1.000s
 L(q)  ops/s    r/s   kBps   ms/r    w/s   kBps   ms/w   %busy Name
    0   1171   1171 274041  0.451      0      0  0.000   41.3| nda0
    0   1235      0      0  0.000   1235 275531  0.362   36.9| nda1
    0   1164   1164 274283  0.407      0      0  0.000   38.4| nda2
    0   1159   1159 274295  0.410      0      0  0.000   38.5| nda3
    0   1161   1161 274263  0.409      0      0  0.000   38.4| nda4
    0      2      2     16  0.901      0      0  0.000    0.2| da0
 
dT: 1.002s  w: 1.000s
 L(q)  ops/s    r/s   kBps   ms/r    w/s   kBps   ms/w   %busy Name
    0   1165   1132 265890  0.450     31    148  0.038   39.9| nda0
    2   1214      0      0  0.000   1212 265882  0.352   36.1| nda1
    1   1172   1137 265942  0.407     33    152  0.038   37.7| nda2
    1   1166   1133 265902  0.408     31    148  0.042   37.7| nda3
    1   1171   1129 265698  0.411     40    180  0.041   37.7| nda4
    0      0      0      0  0.000      0      0  0.000    0.0| da0
 
# zpool status data
  pool: data
 state: ONLINE
  scan: resilvered 39.6G in 00:02:50 with 0 errors on Wed May 21 20:36:11 2025
config:
 
        NAME        STATE     READ WRITE CKSUM
        data        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            nda0    ONLINE       0     0     0
            nda1    ONLINE       0     0     0
            nda2    ONLINE       0     0     0
            nda3    ONLINE       0     0     0
            nda4    ONLINE       0     0     0
 
errors: No known data errors

So it went pretty fast while the temperatures remained close to what have You seen earlier.

The Ugly

… but after some changes in the BIOS – like disabling the Integrated GPU – I needed to reset the BIOS settings altogether … and this is the part when things went fast south really hard.

After the reset I went into BIOS to setup the fan to run at about 3000 RPM … but it seems it went entirely gone … and that small box while doing nothing – started to be as warm as 90oC now … which I consider really bad – I was not even able to hold that computer case without any gloves on my hands.

When I entered the BIOS this is what I saw.

I was out of ideas and really disappointed – so I took a picture of that BIOS and created a ‘send item back and get money back’ issue on Aliexpress portal – where I got it. To be honest I did not expected much – more like a long battle to prove that something is really wrong.

Mine ‘problem report’ was not long – just a simple description on what is wrong:

“Hello. The FAN will just not start and I get some crazy temperatures like 89/82 Celsius – this Mini PC is hot as fuck – and its doing nothing – its crazy for a 6W TDP Intel N100 CPU.”

Get Money Back

I was trying to be polite – while I was also very angry because such high temperatures on a 6W TDP CPU are insane …

… and to my surprise the request was positively accepted the next day – they offered a free send back was of the hardware and promised to send me all the money back – at least that part of the story is successful.

Summary

When You want to do something ambitions – there is bigger chance that you fail … and I failed here … or should I say the hardware failed me.

Some say that if you learn from a failure it is not really a failure but a valuable lesson – and I treat that one exactly like that.

Next plans? I already ordered another Intel N100 box (actually N150 as they run out of N100 devices) with 4-5 M.2 slots and I will share with you in other article how that story went …

UPDATE 1 – High Hopes

After initial failure I have had really High Hopes (great Ping Floyd track) for the next X86 P6 Tiny NAS box I ordered … and I got disappointed again.

I first prepared all needed parts for the build as shown below.

Now – after trying to fit the NVMe adapter with 2230 2TB SSD … it was obvious that the ‘hat’ and the ‘adapter’ will not fit both together … so I was limited to ‘only’ FOUR NVMe SSDs each of 2TB size.

That was still OK – after RAM installation it looked more or less like that above.

All of my hopes were killed during the boot cycle – also seen in dmesg(8) later.

These nvmeX: timeouts above does not look that bad at first – not to mention that the box booted to BIOS POST message in 6-7 minutes – like a regular RACK server – but after the login: prompt it was obvious that a timeout for nvmeX: controller means … that a drive attached to it will NOT be available in the system.

The first (or maybe second) time it booted the drives (and controllers) were there and even the temperatures were ‘right’ – everything seemed cool … until several reboots later.

Before everything went south I was able to at least do some things as shown below.

But after that everything just broke … again.

After thinking about it I had two choices.

I could orderΒ Terramaster F8 SSD Intel N95 based NAS or more expensiveΒ Terramaster F8 SSD Plus Intel N305 powered version.

But I have decided something entirely different.

As I still got 8TB Samsung 2.5 SATA SSD I decided to get some simple AMD Ryzen based Mini PC with ONE 2.5 slot for that SSD and go that route. That AMD Ryzen based box still did not arrived at my lawn – so I will have to wait for it a little longer.

Fortunately the ‘seller’ of that ‘broken’ NAS was also kind enough to sent me the money back after I filled all needed ‘resignation’ docs.

… and do not get me wrong here – I will still seek for a usable and predictable multiple NVMe SSD NAS case – it just that it seems its not that easy and obvious to find a reasonable one …

UPDATE 2 – Interim Solution

While searching for next possible hardware solution that would allow what I want – in the mean time I got something that would ‘just work’ with what I have – I picked some used Minisforum UM350 mini PC for $230 with 4-CORE AMD Ryzen 5 3550H CPU.

While it does not offer any redundancy – mine 8 TB Samsung 870 QVO SSD will work well with it – while FreeBSD system will reside in the NVMe SSD.

One of the things I set in BIOS was the lowest possible power consumption.

In the real world – when idle – and with FreeBSD’s powerd(8) enabled – it consumes about 7W of power.

It works really well with FreeBSD and even the internal WiFi card worked out of the box was working reliably with 14.3-RELEASE version.

From the other boring stuff – that 8 TB Samsung 870 QVO SSD was earlier taken off my ThinkPad W520 – so the only thing I needed to do was to attach GELI target – import ZFS pool – and update the files with rsync(1) command – nothing fancy.

I need to confess that my next solution already arrived at my door step … I will add another update (or article) when I will have time to check it.

EOF

FreeBSD Jails Security

I believe this topic is not really well discussed online – and often with multiple misunderstandings.

There seems to be this general belief that Podman on Linux is as safe as Jails on FreeBSD … lets try to dig into that.

Below I will try to show all differences between security of FreeBSD Jails and Podman containers on Linux.

The Table of Contents for the article below.

  • General Concepts
    • Podman
    • Jails
    • General Concepts Security Summary
  • Root User
  • Isolation Layers
    • Pure Podman and Jails
    • Podman and Jails with Additional Security Layers
    • Isolation Layers Security Summary
  • Kernel Syscalls Surface
    • Podman
    • Jails
    • Kernel Syscalls Surface Security Summary
  • Dedicated Network Interface
    • Podman
    • Jails
    • Dedicated Network Interface Security Summary
  • Dedicated Firewall Inside
    • Podman
    • Jails
    • Dedicated Firewall Inside Security Summary
  • How Well Battle Tested
    • Podman
    • Jails
  • CVEs
    • Podman
    • Jails
    • CVEs Security Summary
  • Endgame Summary

Now lets get into the details.

General Concepts

Podman

Generally to create new container some image from the registry is downloaded – like registry.fedoraproject.org/fedora-minimal:30 for example – and then needed files and packages are added – as needed.

There is also an alternative – to use the scratch as ’empty’ image to create a Podman container that only have needed binary inside.

Jails

Historically Jails were used as a more or less complete FreeBSD system inside – with its own version smaller or equal to the version of the host.

The idea is simple – you create a directory (or ZFS dataset) that will be your root and extract there FreeBSD Base System like that.

freebsd # mkdir -p /jail/test
freebsd # fetch https://download.freebsd.org/releases/amd64/14.2-RELEASE/base.txz
freebsd # tar -C /jail/test --unlink -xf base.txz

Now some short config at /etc/jail.conf or as separate /etc/jail.conf.d/test file and you can start and use your Jail.

Most people do not know that You can use Jails in the same way as Podman or Docker – because there is no need for minimal system image at all.Β Its even possible to create a Jail with single file in it – let me show you how.

freebsd # mkdir -p /jail/minimal/dev
freebsd # cp /rescue/sh /jail/minimal

Even /etc/jail.conf or /etc/jail.conf.d/minimal config is NOT needed.

We can just start the Jail straight from the command line with needed options – after executing this jail(8) command you will be taken inside into the minimal Jail.

freebsd # jail -n minimal            \
            -c path=/jail/minimal    \
               host.hostname=minimal \
               ip4.addr=10.0.0.111   \
               mount.devfs           \
               command=/sh

minimal # /sh
Cannot read termcap database;
using dumb terminal settings.

minimal # for I in 1 2 3; do echo ${I}; done
1
2
3

minimal # echo /*
/dev /sh

Check other terminal on a host system to verify its running.

freebsd # jls
   JID  IP Address      Hostname                      Path
     1  10.0.0.111      minimal                      /jail/minimal

General Concepts Security Summary

Known UNIX saying is that less is more … and also more secure. Security guides and best practices out there suggest the same same thing – the less things you have in a service – the safer the solution – the smaller the potential attack surface – both Jails and Podman does not require ANY minimal system or image to start with – just files/executables (along with dependencies/libraries of course) for your service.

Root User

This one will be fast and easy. Podman in ‘rootless’ mode does not use root user from the host – same as Jails – they also have some virtual root not related in any way to root user on the host system.

Isolation Layers

Pure Podman and Jails

The so called ‘rootless’ Podman seems to be advertised as being on the same level of isolation as Jails – but only if You run that Podman with properly configured and enabled SELinux/AppArmor solutions. Without SELinux/AppArmor the Jails offer a lot better isolation then ‘rootless’ Podman.

Podman and Jails with Additional Security Layers

Now – when you run Podman with SELinux/AppArmor properly configured and then you add MAC Framework modules on FreeBSD like:

  • mac_sebsd
  • mac_jail
  • mac_bsdextended
  • mac_portacl

Then the Jails are better isolated again.

Isolation Layers Security Summary

FreeBSD Jails when run alone without any other additional solutions provide better isolation then Podman – and even if You add that additional layer of isolation – the Jails are still more secure.

Kernel Syscalls Surface

Podman

Even ‘rootless’ Podman has full access to all Linux kernel syscalls – unless blocked additionally by seccomp command/solution with some default profile for the task – or customized/generated one.

Jails

Jails have restricted use of FreeBSD kernel syscalls without any additional tools – and that can be also narrowed with MAC Framework additionally if needed. On the contrary one can ADD additional syscalls with devfs(8) command/solution on FreeBSD.

Kernel Syscalls Surface Security Summary

Jails are safer than Podman when it comes to kernel syscalls attack surface because while Podman needs additional tool (and profile) to limit the syscalls spectrum – FreeBSD Jails by default have minimal syscall exposition.

Dedicated Network Interface

Podman

You can NOT dedicate any physical interface to the ‘rootless’ Podman container.

There are some workarounds though:

  • Use root level helper like macvlan – but it runs in root context/permissions.
  • Decrease security and use ‘rootful’ Podman instead where root from the Podman container is exactly the same root user on host system.

Jails

FreeBSD Jails solution can have:

  • Zero network interfaces.
  • Virtual tap(4) network interface.
  • Virtual tun(4) network interface.
  • Virtual epair(4) network interface.
  • Virtual ng_ether(4) Netgraph network interface.
  • Any dedicated physical network interface from the host.
  • Any part/chunk of SR-IOV dedicated physical network interface from the host.

That means that you can create a Jail that will not be even accessible from the host system but only from the network.

Dedicated Network Interface Security Summary

The Podman looses big here. Not possible to use any physical host network interface limits the security possibilities a lot.

Dedicated Firewall Inside

Podman

You can NOT run any firewall inside ‘rootless’ Podman containers.

Jails

You can run entire dedicated (and separated from the host) network stack inside a Jail – and also any firewall like pf(4) or ipfw(4) also independently from the host inside VNET Jails.

Dedicated Firewall Inside Security Summary

Having a dedicated firewall running in each Jail definitely increases its security level.

How Well Battle Tested

Podman

Docker – which is Podman predecessor is with us since 2014 – that means about 15 years less then Jails which were developed in 1999.

The most secure variant of Podman – the ‘rootless’ one – first appeared in late 2019 (1.6 version) release – so only little above 5 years in service.

Jails

Jails are in production since 1999/2000 when they were introduced – so 25 years strong – very well battle tested.

That means Jails are the most battle tested of all of them.

TL;DR: FreeBSD Jails are generally more secure out-of-the-box compared to Podman containers and even more secure if you take the time to add additional layers of security.

CVEs

Official database of CVE incidents exists and one may just check how many security vulnerabilities were found in a project one is interested.

Podman

Lets count how many CVEs are known about Linux for a start.

% links -dump -width 512 'https://app.opencve.io/cve/?vendor=linux' | grep -i TOTAL
   Total 10064 CVE

The number is 10064.

Now – how many for Podman.

% links -dump -width 512 'https://app.opencve.io/cve/?search=podman' | grep -i TOTAL
   Total 24 CVE

There are 24 of them for the period of 5 years on the market – which means about 5 per year.

Jails

Now its time for FreeBSD system.

% links -dump -width 512 'https://app.opencve.io/cve/?vendor=freebsd' | grep -i TOTAL
   Total 557 CVE

% links -dump -width 512 https://www.freebsd.org/security/advisories/ | grep -c BSD-SA
649

Seems that the FreeBSD project has more Security Advisories (649) published then CVEs for FreeBSD (557) exist πŸ™‚

Now lets check Jails track record.

% links -dump -width 512 https://freebsd.org/security/advisories/ | grep -i jail 
   2021-04-06 FreeBSD-SA-21:10.jail_mount            
   2021-02-24 FreeBSD-SA-21:05.jail_chdir            
   2021-02-24 FreeBSD-SA-21:04.jail_remove           
   2020-03-19 FreeBSD-SA-20:08.jail                  
   2010-05-27 FreeBSD-SA-10:04.jail                  
   2007-01-11 FreeBSD-SA-07:01.jail                  
   2004-06-07 FreeBSD-SA-04:12.jailroute             
   2004-02-25 FreeBSD-SA-04:03.jail                  

% links -dump -width 512 https://freebsd.org/security/advisories/ | grep -c jail
8

There are 8 known security issues within the FreeBSD project.

Lets compare that to CVE database.

% links -dump -width 512 'https://app.opencve.io/cve/?search=jail&vendor=freebsd' | grep -i TOTAL
   Total 18 CVE

Total of 18 CVEs over the period of more then 25 years – that means less then one CVE per year – 0.7 to be precise.

CVEs Security Summary

There are 10064 known security CVEs for Linux systems while only 557649 for FreeBSD – that means more then ONE MAGNITUDE OF ORDER less for FreeBSD systems.

While Jails have about 0.7 CVE security issue per year the Podman have 5 CVE security issues per year.

The winner here is crystal clear – and its FreeBSD Jails again.

Endgame Summary

It is well known and documented that FreeBSD Jails are way more secure and flexible when compared to Podman (even ‘rootless’ mode) on Linux.

Feel free to take your voice in the discussion.

UPDATE 1 – Thoughts After Comments

Disappointment

When I only write about FreeBSD related stuff – not touching the Linux world – everybody seems to love it – but the more I dig into the Linux land with comparisons and pros/cons stuff – the more backslash I get – and as well known saying goes – “You have enemies? Good. That means you’ve stood up for something, sometime in your life.” – that is probably the best summary after posting my last 3 articles – and for the record they are:

The things that makes them a whole is FreeBSD Jails topic discussed in the terms of Containers and Containers Security terms.

Some people accuse me of being not fair or not understanding the case … but its really hard to get deep specifics of Podman containers internals.

Let me give You an example – when Podman container is started – there is a seccomp command run with the default policy (and --seccomp-policy=POLICY argument to be precise) to limit/contain the kernel syscalls … but which ones? Have you tried to search for that information online? I mean – yes I can just install everything from scratch and check in the files from packages … but where it is documented? … and for which Linux distro … as there are so many?

… and this is just one of the examples.

Let me give You another one. I stated that with VNET Jails you get a separate network stack for FreeBSD Jail and you can run your own dedicated firewall inside such as pf(4) or ipfw(4) for example. Some people stated in the comments that the same can be achieved with CAP_NET_ADMIN capability (with --cap-add=NET_ADMIN argument) … OK – but then I check the Linux capabilities(7) man page it states this:

linux # man 7 capabilities | grep -m 1 firewall
- administration of IP firewall, masquerading, and accounting;

Great. But is it on the host firewall or on a separate from the host firewall inside the Podman container? … and even if inside a Podman container – can it be different firewall or the same as on the host?

… and probably if I would ask where its exactly documented in the details – the most common response I probably would get would be: “In the source code”.

Ignorance

I even talked this with my buddy – lets call him Marian (name changed of course) – because I do not want to disclose who he is – about this situation – and he ran both FreeBSD and OpenBSD in the past (also Solaris/AIX/HP-UX/…) and in his last several jobs he was in the SRE role to use AWS (Amazon Web Services) – or just Amazon Cloud to be short – to provide needed solutions – and he said that he really loved the recent FreeBSD Jails articles and that in his cloud related Linux/containers circle no one even tries to get that deep into the differences or actual security.

They are just using it in some AWS managed K8S service – making sure that all the needed services provide the ‘building blocks’ and thats it. No one really even seeks for this level of detail. No one cares.

OCI Containers

Inspiration was usual accusations that FreeBSD Jails are not containers – in my point of view FreeBSD Jails are one of the available containers solutions – but if you want to have OCI compliant containers solution based on FreeBSD Jails – then use them with pot/nomad and you have OCI compatible containers solution based on FreeBSD Jails containers.

EOF

Minecraft Server in FreeBSD Jails Container

Today – as my son requested – we will talk about Minecraft server … inside FreeBSD Jails container.

This is kinda like Docker/Podman thing on Linux – but secure instead.

Prepare

First we will populate /jail path and also fetch needed FreeBSD Base System version.

As for today – we will use 14.2-RELEASE version of FreeBSD UNIX.

host # mkdir -p /jail/minecraft /jail/BASE

host # VER=$( freebsd-version | awk -F '-' '{print $1 "-" $2}' )

host # fetch -o /jail/BASE/${VER}-base.txz https://download.freebsd.org/releases/amd64/14.2-RELEASE/base.txz

Next we will create our dedicated Minecraft FreeBSD Jail and populate it with its own Base System contents.

We will also copy /var/run/dmesg.boot as Minecraft server looks for it.

host # tar -C /jail/minecraft --unlink -xvf /jail/BASE/14.2-RELEASE-base.txz

host # cp /var/run/dmesg.boot /jail/minecraft/var/run/

Create

Now we will setup base FreeBSD Jails configuration.

These will be the default for all other Jails unless we redefine them.

host # cat /etc/jail.conf
exec.start      = "/bin/sh /etc/rc";
exec.stop       = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";
exec.clean;
mount.devfs;

Now out Minecraft Jail config.

We will use em0 LAN interface and 10.0.0.210 IP address.

host # cat /etc/jail.conf.d/minecraft.conf
  minecraft {
  # GLOBAL
    exec.start = "/bin/sh /etc/rc";
    exec.stop  = "/bin/sh /etc/rc.shutdown";
    exec.consolelog = "/var/log/jail_console_${name}.log";
    exec.clean;
    mount.devfs;
    host.hostname = ${name};
    path = /jail/${name};

  # CUSTOM
Β  ip4.addr = 10.0.0.210;
interface = em0;
allow.raw_sockets;
allow.sysvipc;
devfs_ruleset=210;
allow.mount;
enforce_statfs=1;
allow.mount.devfs;
allow.mount.procfs;
allow.mount.fdescfs; }

Below you will also find /etc/devfs.rules ruleset on the host below.

host # grep -A 4 minecraft /etc/devfs.rules
[minecraft=210]
add include $devfsrules_jail
add path 'fd*' unhide

We can now start our Jail.

host # service jail onestart minecraft
Starting jails: minecraft.

host # jls
   JID  IP Address      Hostname                      Path
     1  10.0.0.210      minecraft                     /jail/minecraft

You may as well use mine jmore(8) tool.

host # jmore
JAIL       JID  TYPE  VER     DIR              IFACE   IP(s)
----       ---  ----  ---     ---              -----   -----
classic    -    std   13.2-R  /jail/classic    em0     10.0.0.199
ctld-two   -    vnet  13.2-R  /jail/ctld-two   ${if}b  -
ctld       -    vnet  13.2-R  /jail/ctld       ${if}b  -
fbsdjail   -    std   13.1-R  /jail/fbsdjail   wlan0   10.0.0.43
iscsi      -    vnet  13.2-R  /jail/iscsi      ${if}b  -
minecraft  1    std   14.2-R  /jail/minecraft  em0     10.0.0.210
minio      -    std   14.0-R  /jail/minio      em0     10.0.0.133
nfsd       -    vnet  14.1-R  /jail/nfsd       ${if}b  -
other      -    std   14.1-R  /jail/other      em0     10.0.0.199
sambajail  -    vnet  14.1-R  /jail/sambajail  ${if}b  -
unfs3      -    vnet  14.1-R  /jail/unfs3      ${if}b  -

To make that Minecraft Jail permanently start at boot something like that below would be needed on the host system in the /etc/rc.conf file.

host # grep jail /etc/rc.conf
  jail_enable=YES
  jail_devfs_enable=YES
  jail_list="minecraft"

Configure FreeBSD Jail

Now we will enter the Minecraft Jail.

The jmore minecraft c is equivalent to the well known env PS1='minecraft # ' jexec minecraft /bin/sh command.

host # jmore minecraft c
minecraft # 

Next some basic things such as DNS or switching to latest branch for pkg(8) FreeBSD package manager.

minecraft # echo nameserver 1.1.1.1 > /etc/resolv.conf

minecraft # mkdir -p /usr/local/etc/pkg/repos

minecraft # sed -e 's|quarterly|latest|g' /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf

minecraft # pkg search -o minecraft
games/minecraft-client         Client for the block building game

Now we will install all other needed packages – as Minecraft server needs to be build using FreeBSD Ports.

minecraft # pkg install gitup bsddialog ccache portconfig openjdk21 tmux jless

As we need to build Minecraft server from the FreeBSD Ports because of license that needs to be accepted (or ignored) manually – we will now need to fetch the FreeBSD Ports tree with gitup tool.

At the make config part choose DAEMON option.

minecraft # gitup ports
(...)
#
# Please review the following file(s) for important changes.
#       /usr/ports/UPDATING
#       /usr/ports/mail/dspam/files/UPDATING
#
# Done.

minecraft # cd /usr/ports/games/minecraft-server

minecraft # make config

 +------------|minecraft-server-1.21.4|--------------+
 | 'F1' for Ports Collection help.                   |  
 | +---------- RUN [select at least one] ----------+ |
 | | new (*) DAEMON     Run as a service           | |
 | | new ( ) STANDALONE Run the .jar file directly | |
 | +-----------------------------------------------+ |
 |                [  OK  ]     [Cancel]              |
 +---------------------------------------------------+

Build

Next we will build Minecraft server.

minecraft # echo DISABLE_LICENSES=yes >> /etc/make.conf

minecraft # env BATCH=yes make build install clean
(...)
When you first run minecraft-server, it will populate the file
/usr/local/etc/minecraft-server/eula.txt

It is required to read the EULA, and then set eula=true

- Configuration files can be found in /usr/local/etc/minecraft-server/
- Log and debug output files can be found in /var/log/minecraft-server/
- World files can be found in /var/db/minecraft-server/

Without daemon option:
- To run the server, run /usr/local/bin/minecraft-server
- To edit java's parameters, edit /usr/local/etc/minecraft-server/java-args.txt
- To run with a specific version of Java, set environment variable JAVA_VERSION,
  for example:
    export JAVA_VERSION=22
    /usr/local/bin/minecraft-server
  or:
    JAVA_VERSION=22 /usr/local/bin/minecraft-server

With daemon option:
- The service has been installed with the name 'minecraft'
- To adjust maximum memory usage (-Xmx), use minecraft_memx= in /etc/rc.conf
- To adjust initial memory usage (-Xms), use minecraft_mems= in /etc/rc.conf
- To add other java parameters, use minecraft_args= in /etc/rc.conf
- To run with a specific version of Java, use minecraft_java_version= in /etc/rc.conf
- To see the interactive console, type service minecraft console

===>  Cleaning for minecraft-server-1.21.4

Minecraft Server Configuration

As suggested in the pkg-message we will add additional virtual filesystems to the /etc/fstab file.

We will also make sure they are mounted at Jail start time with /etc/rc.local file.

minecraft # cat << FSTAB >> /etc/fstab
        fdesc   /dev/fd         fdescfs         rw      0       0
        proc    /proc           procfs          rw      0       0
FSTAB

minecraft # echo 'mount -a' >> /etc/rc.local

minecraft # mount -a

minecraft # mount
zroot/jail on / (zfs, local, noatime, nfsv4acls)
devfs on /dev (devfs)
fdescfs on /dev/fd (fdescfs)
procfs on /proc (procfs, local)
devfs on /dev (devfs)

We will not configure Minecraft Jail main /etc/rc.conf config file with needed Minecraft server options.

We will also ‘accept’ EULA and create basic Minecraft server config at /usr/local/etc/minecraft-server/server.properties file.

You may also configure additional Java parameters in the /usr/local/etc/minecraft-server/java-args.txt file.

Increase the values if its too small for your case.

minecraft # cat << RC >> /etc/rc.conf
minecraft_enable=YES
minecraft_mems=1024M
minecraft_memx=1024M
RC

minecraft # echo eula=true > /usr/local/etc/minecraft-server/eula.txt

minecraft # cat << MINECRAFT > /usr/local/etc/minecraft-server/server.properties
enable-jmx-monitoring=false
rcon.port=25575
level-seed=
gamemode=survival
enable-command-block=false
enable-query=false
generator-settings={}
enforce-secure-profile=true
level-name=world
motd=FreeBSD Minecraft Server
query.port=25565
pvp=true
generate-structures=true
max-chained-neighbor-updates=1000000
difficulty=easy
network-compression-threshold=256
max-tick-time=60000
require-resource-pack=false
use-native-transport=true
max-players=20
online-mode=false
enable-status=true
allow-flight=false
initial-disabled-packs=
broadcast-rcon-to-ops=true
view-distance=10
server-ip=
resource-pack-prompt=
allow-nether=true
server-port=25565
enable-rcon=false
sync-chunk-writes=true
resource-pack-id=
op-permission-level=4
prevent-proxy-connections=false
hide-online-players=false
resource-pack=
entity-broadcast-range-percentage=100
simulation-distance=10
rcon.password=
player-idle-timeout=0
force-gamemode=false
rate-limit=0
hardcore=false
white-list=false
broadcast-console-to-ops=true
spawn-npcs=true
spawn-animals=true
log-ips=true
function-permission-level=2
initial-enabled-packs=vanilla
level-type=minecraft\:normal
text-filtering-config=
spawn-monsters=true
enforce-whitelist=false
spawn-protection=16
resource-pack-sha1=
max-world-size=29999984
MINECRAFT

Start

Now it is the time to start the installed and configured Minecraft server.

minecraft # service minecraft start
Starting minecraft.

minecraft # service minecraft status
minecraft is running.

minecraft # sockstat -l4
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
mcserver java       33227 103 tcp4   10.0.0.210:25565      *:*
root     syslogd     7809 5   udp4   10.0.0.210:514        *:*

It seems to be running properly – but in case it does not – try this command for the debug purposes.

minecraft # su mcserver -c '/usr/local/bin/java -Xmx1024M -Xms1024M -jar /usr/local/minecraft-server/server.jar nogui'

Connect with Minecraft Client

First – make sure that your client is in the same version as the Minecraft server version – 1.21.4 in my case.

In my case the Minecraft client is started from some random Windows box – as shown below.

Hit Multiplayer button.

Now hist Add Server button – so we will add out FreeBSD based Minecraft server.

Enter your preferred Minecraft server name and the IP address.

After a moment our FreeBSD based Minecraft server will appear on the list.

Now hit the Join Server button to join it.

We will see the Connecting to the server… message.

… and after a moment we are joined to our Minecraft server.

Users

As I am not a Minecraft expert it took me a little to find out a way to define ‘admins’ on that server.

Fortunately I have a working solution πŸ™‚

When I was writing about mine jmore(8) tool here New jmore(8) FreeBSD Jails List/Manage Tool I initially called it jless(8) but someone notified my that there is already a tool with that name and that its for JSON. We will use it in a moment πŸ™‚

When someone connects to our server its name and uuid is being added to the /usr/local/etc/minecraft-server/usercache.json file as shown below.

host # cat /jail/minecraft/usr/local/etc/minecraft-server/usercache.json | tr ',' '\n'
[{"name":"antuan"
"uuid":"0d61326c-dfd1-3fa8-ba9d-249d402fb700"
"expiresOn":"2025-05-05 14:04:15 +0000"}
{"name":"antek"
"uuid":"4b520bac-4b31-3c41-8f9b-2781763e5c88"
"expiresOn":"2025-05-05 09:16:08 +0000"}]
host # jless /jail/minecraft/usr/local/etc/minecraft-server/usercache.json | cat [ { "name": "antuan", "uuid": "0d61326c-dfd1-3fa8-ba9d-249d402fb700", "expiresOn": "2025-05-05 14:04:15 +0000" }, { "name": "antek", "uuid": "4b520bac-4b31-3c41-8f9b-2781763e5c88", "expiresOn": "2025-05-05 09:16:08 +0000" } ]

It looks even better with colors from bat(1) command.

Now – to make these users ‘admins’ we need to add them to the /usr/local/etc/minecraft-server/ops.json file and also restart Minecraft server to make it effective.

host # jless /jail/minecraft/usr/local/etc/minecraft-server/ops.json | cat
[
  {
    "uuid": "4b520bac-4b31-3c41-8f9b-2781763e5c88",
    "name": "antek",
    "level": 4,
"bypassesPlayerLimit": false
}, { "uuid": "0d61326c-dfd1-3fa8-ba9d-249d402fb700", "name": "antuan", "level": 4,
"bypassesPlayerLimit": false } ]

Level 4 is the highest level of permissions for the record.

Now my son has all needed commands that he uses like /gamemode or /time for example πŸ™‚

Summary

Feel free to add your thoughts about other needed configurations about personal Minecraft server.

UPDATE 1 – FreeBSD Jails versus Linux Podman

I do not expected that first sentence will be the reason for most comments – so I also add some details here. Lets have a discussion about differences between security of FreeBSD Jails and Linux Podman containers.

Isolation: With rootless Podman it seems to be on the same level as Jails – but only if You run Podman with SELinux/AppArmor enabled. Without SELinux/AppArmor the Jails offer better isolation. When you run Podman with SELinux/AppArmor and then you add MAC Framework (like mac_sebsd/mac_jail/mac_bsdextended/mac_portacl) the Jails are more isolated again.

Kernel Syscalls Surface: Even rootless Podman has ‘full’ syscall access unless blocked by seccomp (SELinux). Jails have restricted use of syscalls without any additional tools – and that can be also narrowed even more with MAC Framework on FreeBSD.

Firewall: You can not run firewall inside rootless Podman container. You can run entire network stack and any firewall like PF or IPFW independently from the host inside VNET Jail – which means more security.

TL;DR: FreeBSD Jails are generally more secure out-of-the-box compared to Podman containers and even more secure if you take the time to add additional layers of security.

Time on the market is also important factor.

Jails are in production since 1999/2000 when they were introduced – so 25 years strong – very well battle tested. Docker is with us since 2014 so that means about 10 years less – but we must compare Jails to Podman.Β Rootless support for Podman first appeared late 2019 (in 1.6 version) so only less then 6 years on the market.

That means Jails are the most battle tested of all of them.

EOF